0

我正在做一个弥散 MRI 项目,遇到一个需要帮助的 c++ 问题。

背景:我有一个 .nii 图像作为参考,我希望控制节点(它是样条曲线的一部分)在图像的受限 ROI 内执行随机游走。澄清一下:.nii 图像是显示大脑白质 (WM) 的蒙版,我想要一个具有 4 个控制节点的样条曲线在此蒙版内随机移动,直到它们达到最小化成本函数的状态。目前我正在做的只是更新一个随机控制节点以根据高斯分布在随机方向上移动,然后检查它是在 WM 内部还是外部,如果在 WM 之外则重新绘制。但这可能会导致许多我想避免的不必要的平局。

我的问题:有没有更好的方法来做到这一点?我有一个想法,将我的 ROI 的所有像素坐标收集到一个单独的数组或矩阵中,我可以从该矩阵的索引中绘制出来?如果我想用四个全新的控制点重新初始化我的样条线,这种方法也会很有帮助。(我以后也需要实现)

当前使用方法的代码:

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

我希望这是足够的信息。谢谢你的时间。

4

1 回答 1

0

你有什么类型的成本函数(如果我从你的代码中读取它只是不落在白质之外的像素的总和?)?如果它是平滑且连续的,你可以尝试梯度下降来找到最小值(因为你的看起来是离散的,但是有没有办法让你近似梯度下降?)。这应该比随机游走更有效。

如果保持随机性很重要,那么在不进行大量重新绘制的情况下做到这一点的最佳方法是重新规范您可以选择的分布范围。如果我理解正确,您已经有了白质面膜,所以应该允许您这样做的一种方法是:

1.) 根据以您当前位置为中心的高斯为所有白质像素分配一个概率

2.) 重新归一化这些概率,使它们总和为 1

3.) 从均匀分布中拉出一个随机数,找出它对应的像素

4.) 将控制点移到那里

因此,例如,如果您有四个可能的白质像素,您可以移动到0.1, 0.17, 0.2, and 0.23各个位置(x1,y1), (x2,y2), (x3, y3), (x4, y4),所有其他可能的像素(基于您的高斯随机步骤)都是非白质像素,这将迫使您重新绘制,然后您将通过除以它们的总和来重新调整您的概率(0.7在这种情况下)。然后从均匀分布中拉出一个随机数(假设你拉了0.3)。这将对应于(x2, y2)基于重新归一化概率的第二个点,您可以将控制点移到那里。

如您所见,这需要执行相当多的计算步骤,但会确保您只提取一个随机目标进行更新;因此,性能的任何改进都将取决于这些额外计算的相对成本与您实际重新采样的频率。我也写得很快,所以你可能会想出一种更有效的方法来将随机选择的范围限制在好的像素上。

于 2013-09-25T15:17:43.450 回答