我在编程生活中遇到了最奇怪的问题。我正在对大约 800x800x600 个元素的 3D 体积进行图像分析,从每个像素中提取一个基于灰度的粗麻布矩阵,并在检测体积中描述的纤维的对齐之后计算一些代数(使用Eigen )。
为了构建卷,我使用了一个 double[x][y][z] 数组,该数组是从 nhdr+raw 文件中读取的。到目前为止,对于域问题的介绍非常有用。
我执行将大体积分成子体积的分析(总执行时间约为 14 小时,但这是意料之中的,就像科学分析软件一样)。在某个时刻,当我处于数组的 x=(max-2) (我在边界前 2 个像素处停止分析)索引处时,对于几个元素([792][247][76] 和 [ 792][84][56],但在那些之后可能还有其他人,可能仍然是 x=max),我的特征函数突然失败。
Debuggin 我发现要构建 Hessian 矩阵的偏导数,我访问元素 [x+2][y][z] 并从中获得 NaN,因此显然 Eigen 在对其进行操作时发疯了。
最奇怪的是,如果在软件开始时(加载卷之后),如果我打印那个确切元素的值,它就存在并且它也有一个有意义的值。这怎么可能??我多次运行该软件,对于相同的两个像素,相同位置的相同错误,所以即使猜测它可能是 RAM 错误,它不应该由于我的 PC 中发生的其他事情而以某种方式波动和改变位置吗?
我进一步进行了测试。我在子卷上循环,一切都很好(我继续跟踪一个固定的 volume[][][] 元素的值,故障本身就是在这个元素上表现出来的)像素值在以下函数之外保持不变,那个像素一个像素地分析子体积。据我所知,我感兴趣的像素值是 51941(并且在进入给定子卷的以下函数之前),我在值发生变化时设置了警戒线。
这里发生了什么 > 子卷中的像素值开始:51941 元素:5982;636,260,62; 循环中的像素值:1.65031e-22
在 5982 次循环(整个子卷需要大约 300 万次)之后,值发生了变化,并且在下面的代码中我没有触及它!什么可能导致这样的事情?
Matrix3d HesseAnalysis(int subX, int subY, int subZ, int maxX, int maxY, int maxZ){
//int maxX = subX+deltaX;
//int maxY = subY+deltaY;
//int maxZ = subZ+deltaZ;
int counter=0;
for (int x=subX;x<(maxX-2);x++){
for (int y=subY;y<(maxY-2);y++){
for (int z=subZ;z<(maxZ-2);z++){
if(volume[792][247][76]!=51941){
cout << "Element :" << counter << "; " << x << "," << y << "," << z << ";" << endl;
cout << "Pixel value in loop: " << volume[792][247][76]<< endl;
exit(0);
}
fxx=((volume[x+2][y][z]-volume[x][y][z])/2-(volume[x][y][z]-volume[x-2][y][z])/2)/2;
fyy=((volume[x][y+2][z]-volume[x][y][z])/2-(volume[x][y][z]-volume[x][y-2][z])/2)/2;
fzz=((volume[x][y][z+2]-volume[x][y][z])/2-(volume[x][y][z]-volume[x][y][z-2])/2)/2;
fxy=((volume[x+1][y+1][z]-volume[x+1][y-1][z])-(volume[x-1][y+1][z]-volume[x-1][y-1][z]));
fxz=((volume[x+1][y][z+1]-volume[x+1][y][z-1])-(volume[x-1][y][z+1]-volume[x-1][y][z-1]));
fyz=((volume[x][y+1][z+1]-volume[x][y+1][z-1])-(volume[x][y-1][z+1]-volume[x][y-1][z-1]));
//compose hessian matrix for the pixel, remember that
hessian << fxx, fxy, fxz,
fxy, fyy, fyz,
fxz, fyz, fzz;
//extract eigenvalues and choose the eigenvector related to the smallest eigenvalue,
//and do the outer product of it with itself
EigenSolver<Matrix3d> solver(hessian);
int minorEigen = minorEigenvalue(solver.eigenvalues().real());
Vector3d v3 =solver.eigenvectors().col(minorEigen).real();
V3outerV3 = v3*v3.transpose();
OuterProducts[(x-subX)-2][(y-subY)-2][(z-subZ)-2]= V3outerV3;
counter++;
}
}
}