C 从阵列数据获取平面切片

C 从阵列数据获取平面切片,c,algorithm,3d,plane,C,Algorithm,3d,Plane,大家好, 我将三维网格数据(来自多个TIF图像)读取到结构中,如下所示: typedef struct VolumeData{ int nx; int ny; int nz; unsigned char *data; // size is nx*ny*nz } 现在我想从一维网格数据中获取平面切片: 例如: 但我很难沿着其他轴执行: unsigned char* getYZPlaneStack(VolumeData *vol,int x); 及 有什么简单的算法吗? 提前感谢。C数组

大家好,

我将三维网格数据(来自多个TIF图像)读取到结构中,如下所示:

typedef struct VolumeData{
 int nx;
 int ny;
 int nz;
 unsigned char *data; // size is nx*ny*nz
}
现在我想从一维网格数据中获取平面切片:

例如:

但我很难沿着其他轴执行:

unsigned char* getYZPlaneStack(VolumeData *vol,int x);

有什么简单的算法吗?
提前感谢。

C数组在内存中总是按顺序排列的。您所追求的似乎需要在后续元素的地址之间建立更复杂的关系,而不仅仅是添加元素的大小


我认为您要么需要进一步抽象它,以便获得一个函数(
getAt()
或其他什么)来调用以索引到数组中,要么动态创建新切片并跨数组复制数据。

对于您提到的返回类型,这是不可能的

我会解释的

在第一个函数中,返回一个指针,调用者需要连续压缩数据的地址。这没关系,因为原始结构支持它

对于第二个函数,如果要返回连续压缩平面的地址,则必须进行[1]重新排序,也就是说,将其复制到其他位置[2]分配内存,因为复制到其他位置,以及[3]释放内存,因为在第2步中完成了分配

如果从性能角度看复制是可以接受的,那么最好的方法是使用智能对象,它将为您处理工作。STL的std::vector可能是最好的


如果您有非常大的数据,或者性能是一个问题,那么您必须设计一种不同的方法,而不复制数据。您必须实现自定义索引器-也就是说,避免您要求的转换。

第二个和第三个函数都会对数据集重新采样(它们基本上是在新的引用中表示图像)

因此,他们必须重新组织数据:

  • 为YZ创建一个大小为
    ny*nz
    的新数组,为XZ创建一个大小为
    nx*nz
    的新数组
  • 在给定平面中用数据填充阵列
  • 返回指向新分配数组的指针
  • (在此场景中,调用方负责释放新分配的内存。)

    YZ平面的算法为:

    // I assume this sorting order:
    //       Z ^          Slices are
    //        /           stacked along
    //       /            the Z axis
    //      +-------> X
    //      |
    //      |
    //    Y v
    
    // Assumes your data is stored in row major order:
    //          +-------> X        +---------> X
    // slice 0: | 0 1 2 | slice 1: | 6  7  8 | etc.
    //          | 3 4 5 |          | 9 10 11 |
    //        Y v                Y v
    // Assumes x is the column index, y the row index, z the slice index.
    // For example, you want element #9:
    // - col 0   -> x = 0
    // - row 1   -> y = 1
    // - slice 1 -> z = 1
    // I suggest you rename nx, ny, nz into nbCols, nbRows, nbSlices to make
    // things explicit
    index computeIndex(VolumeData *vol, int x, int y, int z)
    {
        int nx = vol->nx, // nb cols
            ny = vol->ny, // nb rows
            nz = vol->nz; // nb slices
        int index = nx*ny*z // size of one slice, multiplied by slice index
                  + nx*y    // size of one row (nb cols), multiplied by row index
                  + x;      // offset in row (column index)
        return index;
    }
    
    unsigned char* getYZPlaneStack(VolumeData *vol,int x)
    {
        int nx = vol->nx, // nb rows
            ny = vol->ny, // nb columns
            nz = vol->nz; // nb slices
        unsigned char *newData = new unsigned char[ny*nz];
        // Depth is now along the X axis
        //   +-----> Z
        //   |
        //   |
        // Y v
        for(int y = 0; y < ny; ++y)      // For each row
            for(int z = 0; z < nz; ++z ) // For each column
            {
                int i = computeIndex(vol, x, y, z);
                newData[nz*y+z] = vol->data[i];
            }
        return newData;
    }
    
    //我假设这个排序顺序:
    //Z^片是
    ///堆积如山
    ///Z轴
    //+--->X
    //      |
    //      |
    //Y v
    //假设您的数据按行主顺序存储:
    //+----------->X+----------->X
    //第0部分:| 0 1 2 |第1部分:| 6 7 8 |等。
    //          | 3 4 5 |          | 9 10 11 |
    //Y v Y v
    //假设x是列索引,y是行索引,z是切片索引。
    //例如,您需要元素#9:
    //-col 0->x=0
    //-第1行->y=1
    //-切片1->z=1
    //我建议您将nx、ny、nz重命名为nbCols、nbRows、nbSlices,以便
    //明确的事情
    索引计算索引(卷数据*卷,整数x,整数y,整数z)
    {
    int nx=vol->nx,//nb cols
    ny=vol->ny,//nb行
    nz=vol->nz;//nb切片
    int index=nx*ny*z//一个切片的大小,乘以切片索引
    +nx*y//一行的大小(nb列),乘以行索引
    +x;//行中的偏移量(列索引)
    收益指数;
    }
    无符号字符*getYZPlaneStack(卷数据*vol,int x)
    {
    int nx=vol->nx,//nb行
    ny=vol->ny,//nb列
    nz=vol->nz;//nb切片
    无符号字符*newData=新的无符号字符[ny*nz];
    //深度现在沿X轴
    //+--->Z
    //   |
    //   |
    //Y v
    for(int y=0;ydata[i];
    }
    返回新数据;
    }
    
    unsigned char* getXZPlaneStack(VolumeData *vol,int y);
    
    // I assume this sorting order:
    //       Z ^          Slices are
    //        /           stacked along
    //       /            the Z axis
    //      +-------> X
    //      |
    //      |
    //    Y v
    
    // Assumes your data is stored in row major order:
    //          +-------> X        +---------> X
    // slice 0: | 0 1 2 | slice 1: | 6  7  8 | etc.
    //          | 3 4 5 |          | 9 10 11 |
    //        Y v                Y v
    // Assumes x is the column index, y the row index, z the slice index.
    // For example, you want element #9:
    // - col 0   -> x = 0
    // - row 1   -> y = 1
    // - slice 1 -> z = 1
    // I suggest you rename nx, ny, nz into nbCols, nbRows, nbSlices to make
    // things explicit
    index computeIndex(VolumeData *vol, int x, int y, int z)
    {
        int nx = vol->nx, // nb cols
            ny = vol->ny, // nb rows
            nz = vol->nz; // nb slices
        int index = nx*ny*z // size of one slice, multiplied by slice index
                  + nx*y    // size of one row (nb cols), multiplied by row index
                  + x;      // offset in row (column index)
        return index;
    }
    
    unsigned char* getYZPlaneStack(VolumeData *vol,int x)
    {
        int nx = vol->nx, // nb rows
            ny = vol->ny, // nb columns
            nz = vol->nz; // nb slices
        unsigned char *newData = new unsigned char[ny*nz];
        // Depth is now along the X axis
        //   +-----> Z
        //   |
        //   |
        // Y v
        for(int y = 0; y < ny; ++y)      // For each row
            for(int z = 0; z < nz; ++z ) // For each column
            {
                int i = computeIndex(vol, x, y, z);
                newData[nz*y+z] = vol->data[i];
            }
        return newData;
    }