2010-06-09 57 views
1

大家好,獲取平面片從陣列中的數據

我看了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); 

任何簡單的算法呢? 在此先感謝。

回答

1

第二和第三功能都重新採樣您的數據集(它們基本上是在一個新的參考中表達您的圖像)。

所以他們必須重新組織數據:

  1. 創建大小爲ny*nz爲YZ和XZ
  2. 一個新的數組nx*nz裝滿數據在給定的平面
  3. 返回指針鋪設陣列新分配的陣列

(在這種情況下,調用者負責解除分配新分配的內存。)

您的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; 
} 
+0

非常感謝!正是我想要的 – 2010-06-09 15:53:33

1

C數組在存儲器中總是連續的。你所追求的東西似乎需要後續元素地址之間更復雜的關係,而不僅僅是添加元素的大小。

我想你要麼進一步抽象它,以便獲得一個函數(getAt()或其他)來調用索引到數組中,或動態創建新切片並複製數據。

1

這不適用於您提到的返回類型。

我會解釋一下。

在第一個函數中,你返回一個指針,調用者期望連續打包數據的地址。這沒關係,因爲原始結構支持它。

對於第二個函數,如果你想返回連續打包平面的地址,你必須做[1]重新排序,意思是在別處拷貝它[2]分配內存,因爲複製到其他地方, [3]釋放內存,因爲在2中完成分配。

如果從性能的角度來看複製是可以接受的,最好的方法是使用智能對象來處理您的工作。 STL的std :: vector可能是最好的。

如果您有非常大的數據或性能問題,那麼您將不得不設計不同的方法而不復制數據。你將不得不實現自定義索引器 - 也就是說,避免你要求的轉換。