私は拡散 MRI プロジェクトに取り組んでおり、助けが必要な C++ の問題があります。
背景: 制御ノード (スプラインの一部) が画像の制約付き ROI 内でランダム ウォークを実行する参照として .nii 画像があります。明確にするために: .nii 画像は脳白質 (WM) を示すマスクです。コスト関数を最小化する状態に達するまで、4 つの制御ノードを持つスプラインがこのマスク内でランダムに移動するようにします。現在、私が行っているのは、ガウス分布に従ってランダムな方向に移動するようにランダム コントロール ノードを更新し、WM の内側または外側にあるかどうかを確認し、WM の外側にある場合は再描画することです。しかし、これは私が避けたい多くの不必要なドローにつながる可能性があります.
私の質問に対して:これを行うためのより良い方法はありますか?ROI のすべてのピクセル座標を、代わりにそのマトリックスのインデックスから描画できる別の配列またはマトリックスに収集するという考えがありますか? この方法は、スプラインを 4 つのまったく新しい制御点で再初期化したい場合にも役立ちます。(これも将来実装する必要があります)
現在使用されているメソッドのコード:
blitz::Array<Catmull,1> FIBERs; // Fiber with control nodes (knots) which I want to move
NIFTI<INT16>* niiWM = new NIFTI<INT16>; // .nii Image which contains WM mask
void SimulatedAnnealing_OneStep( void )
{
iF = floor( FIBERs.extent(0)*uniformGen.random()); // select randomly a FIBER
NewProposal(iF);
Pen = CheckWM(iF);
while(Pen >= 1){
NewProposal(iF);
Pen = CheckWM(iF);
}
}
void NewProposal( int ifff)
{
static int iK;
static POINT delta;
delta.Set( MOVE_sigma*normalGen.random(), MOVE_sigma*normalGen.random(), 0 );
iK = floor(uniformGen.random()*6);
if( iK==2 || iK==3 ) // Moving the middle control points within the WM
{ // FIBERs(ifff) is a randomly selected fiber (outside this method) which we are moving
FIBERs(ifff).KNOTs[iK].x += delta.x;
FIBERs(ifff).KNOTs[iK].y += delta.y;
FIBERs(ifff).KNOTs[iK].z += delta.z;
FIBERs(ifff).KNOTs[iK].x = fmin( fmax( FIBERs(ifff).KNOTs[iK].x,0), Nx );
FIBERs(ifff).KNOTs[iK].y = fmin( fmax( FIBERs(ifff).KNOTs[iK].y, 0), Ny );
FIBERs(ifff).KNOTs[iK].z = fmin( fmax( FIBERs(ifff).KNOTs[iK].z, 0), Nz );
}
}
int CheckWM( int iff )
{
int j,Pe;
int Vx, Vy, Vz;
Pe = 0;
for(j=0; j<FIBERs(iff).P.extent(0) ;j++){ // Loop through the segments on the curve
Vx = floor( FIBERs(iff).P(j).x ); // midpoint of the segment
Vy = floor( FIBERs(iff).P(j).y );
Vz = floor( FIBERs(iff).P(j).z );
if ((*niiWM->img)(Vx,Vy,Vz) == 0){ // Penalize when outside the WM
Pe += 1;}
}
return Pe;
}
これで十分な情報であったことを願っています。御時間ありがとうございます。