问候所有人,
我将3d网格数据(来自多个TIF图像)读入结构如下:
typedef struct VolumeData{
int nx;
int ny;
int nz;
unsigned char *data; // size is nx*ny*nz
}
现在我想从这个1-D网格数据中获取平面切片:
例如:
unsigned char* getXYPlaneStack(VolumeData *vol,int z);
I could implement above function because the *data array stores image stack.
但我很难在其他轴上实施:
unsigned char* getYZPlaneStack(VolumeData *vol,int x);
和
unsigned char* getXZPlaneStack(VolumeData *vol,int y);
任何简单的算法吗? 提前谢谢。
答案 0 :(得分:1)
C数组在内存中始终是顺序的。您所追求的似乎需要在后续元素的地址之间建立更复杂的关系,而不仅仅是添加元素的大小。
我认为您要么必须进一步抽象它,以便获得一个函数(getAt()
或其他东西)来调用索引到数组中,或者动态创建新切片并复制数据
答案 1 :(得分:1)
使用您提到的返回类型无法做到这一点。
我会解释。
在第一个函数中,返回一个指针,调用者需要连续打包数据的地址。这没关系,因为原始结构支持它。
对于第二个函数,如果要返回连续打包平面的地址,则必须进行[1]重新排序,这意味着,将其复制到别处[2]分配内存,因为在其他地方进行复制,并且[ 3]释放内存,因为在2中完成了分配。
如果从性能的角度来看,复制是可以接受的,那么最好的方法是使用能够为您处理工作的智能对象。 STL的std :: vector可能是最好的。
如果您需要关注非常大的数据或性能,则必须设计不同的方法而不复制数据。您必须实现自定义索引器 - 即避免您要求的转换。
答案 2 :(得分:1)
第二和第三个功能都重新采样您的数据集(它们基本上是以新的参考形式表达您的图像)。
所以他们必须重组数据:
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;
}