首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >分割3d图像

分割3d图像
EN

Stack Overflow用户
提问于 2016-06-16 19:13:22
回答 1查看 264关注 0票数 1

我试着分割一个图像的三维表示。已知的因素如下:

  • DimensionX
  • DimensionY
  • DimensionZ
  • voxels[]

Voxels[]是一个表示像素灰度的ushort数组。

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

我有树实现,但他们有一个问题,他们不工作的维度是不一样的。(除了get Z片,这是完美的工作)。

以下是这些方法:

代码语言:javascript
复制
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作为深度,是一个更困难的问题。

代码语言:javascript
复制
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;
} 

如何改进最后两个方法,使其与不相等的维度一起工作?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-17 08:50:14

为什么不使用基向量来制作通用切片函数呢?这将大大减少管理的代码。

基本上,您可以得到U,V轴,每个轴都映射到X,YZ中。切片W是第三个未使用的轴。因此,你只需循环U,V,并离开W的原样。每个U,V都有一个基向量(ux,uy,uz)(vx,vy,vz),用于描述x,y,z坐标中增量的变化。

我把它编码到我的 class in C++.

代码语言:javascript
复制
//---------------------------------------------------------------------------
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;
        }
    }
//---------------------------------------------------------------------------

正如你所看到的,它很好,很简单.而且还可以进行更多的优化。在这里,使用和输出示例:

代码语言:javascript
复制
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)+uzdv=...,直接增加地址,而不需要任何乘法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37867603

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档