2

おそらく大きい(256x256x256)3Dボリューム画像で作業しています。読み込んで操作したい 3 つのボリュームがあります。現在、各巻は数字のテキストファイルとして保存されており、ifstream. これを行列として保存します (これは、3D 配列の動的割り当てによって作成したクラスです)。次に、これら 3 つの行列、加算、乗算、さらにはフーリエ変換に対して演算を実行します。これまでのところ、すべてうまく機能していますが、6 つの入れ子になったループがあるため、特にフーリエ変換に非常に多くの時間がかかります。

これを高速化する方法を知りたいです。また、画像をテキストファイルに保存したかどうかも違います。それらをバイナリとして保存するか、他のより読みやすい/高速な形式で保存する必要がありますか? fstream読み込める最速の方法はありますか? 変更せずに毎回同じ 3 つの行列を使用します。それは違いがありますか?また、ポインターからポインターへのポインターは、3D ボリュームを格納するための最良の方法ですか? そうでない場合、他に何ができますか?

4

4 に答える 4

4

また、ポインターからポインターへのポインターは、3d ボリュームを格納するための最良の方法ですか?

いいえ、それは通常非常に非効率的です。

そうでない場合、他に何ができますか?

連続したブロックに格納し、計算されたオフセットをブロックに使用すると、パフォーマンスが向上する可能性があります。

私は通常、次のような構造を使用します。

class DataBlock {

  unsigned int nx;
  unsigned int ny;
  unsigned int nz;
  std::vector<double> data;

  DataBlock(in_nx,in_ny,in_nz) : 
   nx(in_nx), ny(in_ny), nz(in_nz) , data(in_nx*in_ny*in_nz, 0)
  {}

  //You may want to make this check bounds in debug builds
  double& at(unsigned int x, unsigned int y, unsigned int z) { 
    return data[ x + y*nx + z*nx*ny ];
  };

  const double& at(unsigned int x, unsigned int y, unsigned int z) const { 
    return data[ x + y*nx + z*nx*ny ];
  };

  private:
    //Dont want this class copied, so remove the copy constructor and assignment.
    DataBlock(const DataBlock&);
    DataBlock&operator=(const DataBlock&);
};
于 2013-05-17T08:07:54.783 に答える
3

大きな (256 3要素) 3D 画像ファイルをプレーン テキストとして保存するのは、リソースの無駄遣いです。

一般性を失うことなく、画像のプレーン テキスト ファイルがあり、ファイルの各行が 1 つの値で構成されている場合、行の終わりが見つかるまで数文字を読み取る必要があります (3 桁の数字の場合、は 4 バイトになります (数字は 3 バイト、改行は 1 バイト)。その後、これらの 1 桁を数値に変換する必要があります。バイナリを使用する場合、一定量のバイトを直接読み取ると、番号が得られます。バイナリ イメージとして読み書きすることができますし、そうすべきです。

そのためのフォーマットはいくつかありますが、私が推奨するのは VTK のメタ イメージ ファイル フォーマットです。この形式では、プレーン テキストのヘッダー ファイルと、実際の画像データを含むバイナリ ファイルがあります。ヘッダー ファイルからの情報を使用すると、イメージのサイズと使用するデータ型がわかります。次に、プログラムでバイナリ データを直接読み取り、3D 配列に保存します。

本当に高速化したい場合は、アプリケーションにとってかなり高速な CUDA または OpenCL を使用してください。

前述の VTK や ITK など、画像データの書き込み、保存、操作に役立つ C++ ライブラリがいくつかあります。

于 2013-05-17T08:22:14.713 に答える