2014-11-04 3 views
0

Iḿ, работающий над алгоритмом поиска и заполнения областей на двоичном изображении, код работает как ожидалось для некоторых изображений, но я не знаю, почему, после четвертое изображение, которое я всегда получаю эту ошибку:OpenCV double free или corrupt (out): Aborted (core dumped)

* Error in `./heli': double free or corruption (out): 0x0000000001ccb610 * Aborted (core dumped)

Это мой код:

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

я вызываю метод «Сегмент», который затем вызывает метод «fillRegion» для каждого региона найден. Я знаю, что ошибка указана в методе fillRegion, потому что, если я прокомментирую ее из «сегмента», ошибка исчезла, но я просто не могу найти/не знаю, что на ней ошибка.

ответ

0

Если у вас есть GDB (и вы должны), выполните следующие действия:

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

Это покажет вам, где ваш код разбился.

+0

Хорошо, я это и говорю, что ошибка в этой строке по умолчанию: 'Mat newImg = Mat (img.rows, img.cols, CV_8UC3 , Scalar (0,0,0)); ' В частности, при вызове Mat :: release (чего я никогда не делаю) Но это ничего мне не говорит:/ –

+0

Имеет ли Mat свою пользовательскую копию конструктор, который на самом деле работает? Я не знаю, но если в этой строке есть ошибка, вероятность того, что она использует созданный компилятором конструктор копии, может быть недостаточно. – PaulMcKenzie

+0

@edua_glz Я бы предложил сделать следующее: 'Mat newImg (img.rows, img.cols, CV_8UC3, Scalar (0,0,0));' Нет необходимости ссылаться на конструктор копирования - просто создайте переменную , Вы делаете такой же надзор в нескольких других местах вашего кода, где вы без необходимости вызываете конструктор копирования при создании новых объектов. Как здесь: 'Vec3b cero = Vec3b (0,0,0);' Это должно быть просто 'Vec3b cero (0,0,0);' – PaulMcKenzie

0

Я не думаю, что это связано с конструктором копирования, кроме факта, что он не выделяет достаточно памяти. Как вы упомянули, комментируя звонок fillRegion в segment, вы избегаете ошибки seg. Вероятно, это означает, что в fillRegion происходит утечка памяти, которая заполняет выделенный объем памяти в течение 4 итераций вашей программы.

Хотя это не решит вашу утечку памяти, я предлагаю передать Mat src вместо const Mat& src. Передача по ссылке позволит избежать ненужной копии в этом случае, поскольку вы не внутренне изменяете что-либо в src.

Моя догадаться, что утечка памяти должна делать с этими двумя проверками: bot.y <= src.rows right.x <= src.cols

Я считаю, что они должны вместо этого быть строго меньше (<), чтобы избежать вызова at на недопустимый. При вызове at в точке, которая находится за пределами текущих размеров Mat, изменяется ли она? Если это так, то вы постоянно изменяете размер этих изображений всякий раз, когда вы нажимаете эти границы. У вас есть утечка памяти

Еще одна вещь: can getRandomColor() потенциально можно вернуть (0, 0, 0)? Если это так, эта программа может работать в бесконечном цикле

+0

Я сделал оба изменения, как вы предлагали, но ошибка все еще существует –

+0

Согласно документу здесь: http://docs.opencv.org/doc /tutorials/core/mat_the_basic_image_container/mat_the_basic_image_container.html#mat Конструктор копирования использует механизм подсчета ссылок и фактически не копирует данные. Тем не менее, я согласен, что OP должен проходить по ссылке const, чтобы избежать всего этого. – PaulMcKenzie

Смежные вопросы