OpenCV双重免费或腐败(退出):中止(核心转储)

时间:2014-11-04 15:46:10

标签: c++ opencv memory

我在研究二进制化图像上找到并填充区域的算法,代码按照预期的方式工作,但是我不知道为什么,在第四张图像之后我总是得到这个错误:

  

*错误在./heli' ;:双重免费或损坏(退出):0x0000000001ccb610 *   中止(核心倾销)

这是我的代码:

void fillRegion(Mat src, Mat &dst, Point origin, Vec3b color)
{
    int size = 0;
    list<Point> cadena;
    cadena.push_back(origin);
    while(!cadena.empty())
    {
        Point current = cadena.front();
        cadena.pop_front();
        Point top,bot,right,left;
        top = bot = right = left = current;
        top.y -= 1;
        bot.y += 1;
        right.x += 1;
        left.x -= 1;
        Vec3b cero = Vec3b(0,0,0);

        if(top.y >= 0 && dst.at<Vec3b>(top) == cero && src.at<uchar>(top)!= 0)
        {
            dst.at<Vec3b>(top) = color;
            cadena.push_back(top);
        }
        if(bot.y <= src.rows && dst.at<Vec3b>(bot) == cero && src.at<uchar>(bot)!= 0)
        {
            dst.at<Vec3b>(bot) = color;
            cadena.push_back(bot);
        }
        if(right.x <= src.cols && dst.at<Vec3b>(right) == cero && src.at<uchar>(right)!= 0)
        {
            dst.at<Vec3b>(right) = color;
            cadena.push_back(right);
        }
        if(left.y >= 0 && dst.at<Vec3b>(left) == cero && src.at<uchar>(left)!= 0)
        {
            dst.at<Vec3b>(left) = color;
            cadena.push_back(left);
        }
    }
}

void segment(Mat src, Mat &dst)
{
    for(int x = 0; x < src.cols; x++)
    {
        for(int y = 0; y < src.rows;  y++)
        {
            Point p = Point(x,y); 
            if(src.at<uchar>(p) != 0 && dst.at<Vec3b>(p) == Vec3b(0,0,0) )
            {
                fillRegion(src,dst,p,getRandomColor());
            }
        }    
    }
}
int main(int argc, char *argv[])
{
    namedWindow("Original", WINDOW_NORMAL); 
    namedWindow("Resultado", WINDOW_NORMAL);
    vector<string> archivos = vector<string>();
    getdir("../images",archivos);
    int tam = archivos.size();
    for(uint i = 0; i < tam; i++)
    {
        Mat img = imread(archivos[i],CV_LOAD_IMAGE_GRAYSCALE);
        Mat newImg = Mat(img.rows,img.cols, CV_8UC3, Scalar(0,0,0));;
        threshold(img,img,125,255,THRESH_BINARY);
        imshow("Original", img);
        segment(img,newImg);
        imshow("Resultado", newImg);
        waitKey(0);
    }
}

我打电话给&#34; Segment&#34;方法,然后调用&#34; fillRegion&#34;找到每个区域的方法。 我知道错误发生在&#34; fillRegion&#34;方法,因为如果我从&#34;段&#34;中评论它,错误就消失了,但我无法找到/不知道它上面的错误是什么。

3 个答案:

答案 0 :(得分:0)

如果你有gdb(你应该),请执行以下操作:

gdb
run "your file name here"
core /[name of core file]
bt (stands for backtrace)

这将告诉您代码崩溃的位置。

答案 1 :(得分:0)

我不认为它与复制构造函数有关,除了它无法分配足够的内存这一事实。正如您所提到的,在fillRegion中注释掉segment调用可以避免seg错误。这可能意味着fillRegion中存在内存泄漏,这会在程序的4次迭代中填满分配的内存大小。

虽然这不会解决您的内存泄漏,但我建议将Mat src改为const Mat& src。在这种情况下,通过引用传递将避免不必要的副本,因为您没有在src内部修改任何内容。

我猜这个内存泄漏与这两个检查有关:     bot.y <= src.rows     right.x <= src.cols

我认为他们应该严格地小于(<)以避免在无效点上调用at。在当前at维度之外的点上调用Mat时,是否会调整大小?如果是这种情况,那么无论何时达到这些边界,您都会不断调整这些图像的大小。你的内存泄漏

还有一件事:getRandomColor()可能会返回(0, 0, 0)吗?如果是这样,该程序可能会遇到无限循环

答案 2 :(得分:0)

对于像我一样遇到这种情况的任何人,在代码的最后一行添加exit(0)作为我在ubuntu 16.04上修复的段错误。