1

みなさん、こんにちは。

(複数のTIF画像からの)3Dグリッドデータを次のような構造に読み込みました:

typedef struct VolumeData{
 int nx;
 int ny;
 int nz;
 unsigned char *data; // size is nx*ny*nz
}

次に、この1次元グリッドデータから平面スライスを取得します。

例えば:

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);

このための簡単なアルゴリズムはありますか?前もって感謝します。

4

3 に答える 3

1

C 配列は常にメモリ内でシーケンシャルです。あなたが求めているのは、要素のサイズを追加するだけでなく、後続の要素のアドレス間のより複雑な関係が必要になるようです。

getAt()配列にインデックスを付けるために呼び出す関数(または何か)を取得するか、新しいスライスを動的に作成してデータをコピーできるように、さらに抽象化する必要があると思います。

于 2010-06-09T08:50:36.200 に答える
1

これは、あなたが言及した戻り値の型では不可能です。

説明します。

最初の関数では、ポインターを返します。呼び出し元は、連続してパックされたデータのアドレスを期待しています。元の構造がそれをサポートしているので、これは問題ありません。

2番目の関数では、連続的にパックされたプレーンのアドレスを返したい場合は、[1]並べ替え、つまり別の場所にコピーする[2]別の場所にコピーするため、メモリを割り当てる、[3]解放する必要があります。 2で割り当てが行われたため、メモリ。

パフォーマンスの観点からコピーが許容される場合、最良のアプローチは、作業を処理するスマート オブジェクトを使用することです。STL の std::vector がおそらく最適です。

非常に大きなデータがある場合、またはパフォーマンスが懸念される場合は、データをコピーせずに別のアプローチを設計する必要があります。カスタム インデクサーを実装する必要があります。つまり、必要な変換を回避します。

于 2010-06-09T08:52:32.673 に答える
1

2 番目と 3 番目の関数はどちらもデータ セットをリサンプリングします (基本的に、新しい参照でイメージを表現しています)。

したがって、データを再編成する必要があります。

  1. ny*nzYZ およびnx*nzXZのサイズの新しい配列を作成します
  2. 指定された平面にあるデータで配列を埋めます
  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;
}
于 2010-06-09T09:51:37.757 に答える