对于我的计算机视觉课程,我们目前正在研究Canny Edge Detection Algorithm。对于熟悉的人来说,该算法涉及使用图像的灰度来为每个像素创建梯度矢量。因此,我的代码有两个用于存储此信息的矩阵,一个是幅度,一个是角度。
double edge[height][width];
double max = 0;
for(int r = 0; r<height; r++)
{
for(int c = 0; c<width; c++)
{
if(r==0||c==0||r+1==height||c+1==width)
{
edge[r][c]=0;
}
else
{
edge[r][c]=sqrt(pow((2*greyscale[r-1][c])+greyscale[r-1][c+1]+greyscale[r-1][c-1]-(2*greyscale[r+1][c])-greyscale[r+1][c+1]-greyscale[r+1][c-1],2.0)+pow((2*greyscale[r][c-1])+greyscale[r+1][c-1]+greyscale[r-1][c-1]-(2*greyscale[r][c+1])-greyscale[r-1][c+1]-greyscale[r+1][c+1],2.0));
if(edge[r][c]>max)
{
max=edge[r][c];
}
}
}
}
//cout<<"makes edge"<<endl;
double atans[height][width]; //should work, but creates memory error when uncommented
for(int r = 0; r<height; r++)
{
for(int c = 0; c<width; c++)
{
cout<<r<<", "<<c<<endl;
if(r==0||c==0||r+1==height||c+1==width)
{
atans[r][c]=0;
}
else
{
atans[r][c] = atan2(2*greyscale[r-1][c]+greyscale[r-1][c+1]+greyscale[r-1][c-1]-2*greyscale[r+1][c]-greyscale[r+1][c+1]-greyscale[r+1][c-1],2*greyscale[r][c-1]+greyscale[r+1][c-1]+greyscale[r-1][c-1]-2*greyscale[r][c+1]-greyscale[r-1][c+1]-greyscale[r+1][c+1]);
}
}
}
我的代码使边缘矩阵很好,但是当我尝试制作atan矩阵时会出现分割错误。 有关如何解决此问题的任何建议?
答案 0 :(得分:2)
我假设您定义了greyscale[height][width]
。
然后,在行
atans[r][c] =
atan2(2*greyscale[r-1][c]+greyscale[r-1][c+1]+greyscale[r-1][c-1]-2*greyscale[r+1][c]-greyscale[r+1][c+1]
-greyscale[r+1][c-1],2*greyscale[r][c-1]+greyscale[r+1][c-1]+greyscale[r-1][c-1]-2*greyscale[r][c+1]
-greyscale[r-1][c+1]-greyscale[r+1][c+1]);
您越界了。
条件:
r+1==height||c+1==width
还不够。
测试应与height-1
和width-1
一起进行
答案 1 :(得分:1)
最可能的问题是对数组的访问超出范围。有valgrind
之类的工具可以在不更改代码的情况下检测到这一点。其他可能性包括使用调试器逐步执行代码,或在对数组的所有访问之前添加assert
。
另一种可能性是从使用纯数组转换为使用std::vector
的{{1}}或其他可以轻松支持边界检查的C ++集合。
另一种可能性是std::vector
和height
很大,因此数组需要访问的内存量要大于平台在堆栈上可以访问的内存量。如果内存不足而不是崩溃,则切换为动态分配或可能产生错误的方法是一个好主意。您也可以先记录他们的日志,看看这是否可能是问题。
我建议不要在堆栈上分配这样的数组,因为不同的平台具有不同的堆栈大小限制。因此,即使您的代码可以正常工作,它也使它很脆弱。
答案 2 :(得分:1)
以向量(最好是一维向量)分配数组。
问题是该行:
double atans[height][width];
如果您使用变量height
和width
,则此C ++无效,因为它是C99。
如果它们是常量,则它是有效的C ++,但是您正在将数组分配在堆栈上,并且有可能被炸毁。