创建多个矩阵时出现分段错误(核心已转储)

时间:2018-12-04 15:11:07

标签: c++ canny-operator

对于我的计算机视觉课程,我们目前正在研究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矩阵时会出现分割错误。 有关如何解决此问题的任何建议?

3 个答案:

答案 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-1width-1一起进行

答案 1 :(得分:1)

最可能的问题是对数组的访问超出范围。有valgrind之类的工具可以在不更改代码的情况下检测到这一点。其他可能性包括使用调试器逐步执行代码,或在对数组的所有访问之前添加assert

另一种可能性是从使用纯数组转换为使用std::vector的{​​{1}}或其他可以轻松支持边界检查的C ++集合。

另一种可能性是std::vectorheight很大,因此数组需要访问的内存量要大于平台在堆栈上可以访问的内存量。如果内存不足而不是崩溃,则切换为动态分配或可能产生错误的方法是一个好主意。您也可以先记录他们的日志,看看这是否可能是问题。

我建议不要在堆栈上分配这样的数组,因为不同的平台具有不同的堆栈大小限制。因此,即使您的代码可以正常工作,它也使它很脆弱。

答案 2 :(得分:1)

以向量(最好是一维向量)分配数组。

问题是该行:

double atans[height][width];

如果您使用变量heightwidth,则此C ++无效,因为它是C99。

如果它们是常量,则它是有效的C ++,但是您正在将数组分配在堆栈上,并且有可能被炸毁。