我试着分割一个图像的三维表示。已知的因素如下:
Voxels[]是一个表示像素灰度的ushort数组。

现在我要把它切成所有可能的方向。让我们说x,y或z。



我有树实现,但他们有一个问题,他们不工作的维度是不一样的。(除了get Z片,这是完美的工作)。
以下是这些方法:
private ushort[] GetZSlice(int z, ushort[] voxels, int DimensionX, int DimensionY)
{
var res = new ushort[DimensionX * DimensionY];
for(int j = 0; j < DimensionY; j++)
{
for(int i = 0; i < DimensionX; i++)
{
res[j*DimensionX + i] = voxels[z*DimensionX*DimensionY + j*DimensionX + i];
}
}
return res;
}这个方法工作得很好,不是我选择的尺寸。
接下来的两种方法,以x或y作为深度,是一个更困难的问题。
private ushort[] GetYSlice(int y, ushort[] voxels, int DimensionX, int DimensionY, int DimensionZ)
{
var res = new ushort[DimensionX * DimensionZ];
for( int i = 0; i < DimensionX; i++)
{
for( int j = 0; j < DimensionX; j++)
{
res[j + i*DimensionX] = voxels[j * DimensionZ * DimensionY + Y*DimensionZ + i]
}
}
return res;
}
private ushort[] GetXSlice(int x, ushort[voxels], int DimensionX, int DimensionY, int DimensionZ)
{
var res = new short[DimensionY * DimensionZ];
for(int i = 0; i < DimensionY; i++)
{
for(int j = 0; j < DimensionZ; j++)
{
res[j + i*DimensionZ] = voxels[i*DimensionY + j*DimensionZ*DimensionX + x]
}
}
return res;
} 如何改进最后两个方法,使其与不相等的维度一起工作?
发布于 2016-06-17 08:50:14
为什么不使用基向量来制作通用切片函数呢?这将大大减少管理的代码。
基本上,您可以得到U,V轴,每个轴都映射到X,Y或Z中。切片W是第三个未使用的轴。因此,你只需循环U,V,并离开W的原样。每个U,V都有一个基向量(ux,uy,uz),(vx,vy,vz),用于描述x,y,z坐标中增量的变化。
我把它编码到我的 class in C++.
//---------------------------------------------------------------------------
class LED_cube
{
public:
int xs,ys,zs,***map;
LED_cube() { xs=0; ys=0; zs=0; map=NULL; }
LED_cube(LED_cube& a) { xs=0; ys=0; zs=0; map=NULL; *this=a; }
~LED_cube() { _free(); }
LED_cube* operator = (const LED_cube *a) { *this=*a; return this; }
LED_cube* operator = (const LED_cube &a);
void _free();
void resize(int _xs,int _ys,int _zs);
void cls(int col); // clear cube with col 0x00BBGGRR
void sphere(int x0,int y0,int z0,int r,int col); // draws sphere surface with col 0x00BBGGRR
void slice (char *uv,int slice,int col); // draws (XY,XZ,YZ) slice with col 0x00BBGGRR
void glDraw(); // render cube by OpenGL as 1x1x1 cube at 0,0,0
};
//---------------------------------------------------------------------------
void LED_cube::slice(char *uv,int slice,int col)
{
// detect basis vectors from uv string
int ux=0,uy=0,uz=0,us=0;
int vx=0,vy=0,vz=0,vs=0;
int x=slice,y=slice,z=slice,u,v,x0,y0,z0;
if (uv[0]=='X') { x=0; ux=1; us=xs; }
if (uv[0]=='Y') { y=0; uy=1; us=ys; }
if (uv[0]=='Z') { z=0; uz=1; us=zs; }
if (uv[1]=='X') { x=0; vx=1; vs=xs; }
if (uv[1]=='Y') { y=0; vy=1; vs=ys; }
if (uv[1]=='Z') { z=0; vz=1; vs=zs; }
// render slice
if ((x>=0)&&(x<xs)&&(y>=0)&&(y<ys)&&(z>=0)&&(z<zs))
for (u=0;u<us;u++,x+=ux,y+=uy,z+=uz)
{
x0=x; y0=y; z0=z;
for (v=0;v<vs;v++,x+=vx,y+=vy,z+=vz)
map[x][y][z]=col;
x=x0; y=y0; z=z0;
}
}
//---------------------------------------------------------------------------正如你所看到的,它很好,很简单.而且还可以进行更多的优化。在这里,使用和输出示例:
cube.resize(32,16,20);
cube.cls(0x00202020);
cube.slice("XY",5,0x000000FF);
cube.slice("XZ",5,0x0000FF00);
cube.slice("YZ",5,0x00FF0000);
cube.glDraw();

当您将体素存储在一维数组中时,只需从x,y,z中计算地址。因此,map[x][y][z]将成为您的voxels[(x*ys*zs)+(y*zs)+z]或任何组合的轴序,您得到。这可以完全编码到基向量中,这样就可以有du=(ux*ys*zs)+(uy*zs)+uz和dv=...,直接增加地址,而不需要任何乘法。
https://stackoverflow.com/questions/37867603
复制相似问题