2014-11-04 4 views
0

일부 이미지에 대해 예상대로 코드 작업이 있지만 두 번째 이미지에서 영역을 찾아 채우기 위해 알고리즘을 사용하고 있지만 그 이유는 알 수 없습니다. 네 번째 이미지 난 항상이 오류가 발생합니다 :OpenCV double free 또는 corruption (out) : 중단됨 (코어 덤프 됨)

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

이 내 코드입니다 : 다음 발견 된 각 지역의 "fillRegion"메소드를 호출 '분류 기준'메소드를 호출

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"메서드에서 에러가 발생한다는 것을 알았습니다. 왜냐하면 "세그먼트"에서 주석을 작성하면 오류가 사라 졌기 때문에 오류가 무엇인지 알 수 없기 때문입니다.

답변

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

매트에 사용자 정의 복사본이 있습니까? 실제로 작동하는 생성자? 나도 몰라,하지만 그 라인에 오류가 있다면, 그것은 가능성이 충분하지 않을 수도 있습니다 컴파일러 생성 된 복사 생성자를 사용하는 것입니다. – 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 오류가 발생하지 않습니다. 이는 프로그램의 4 번 반복에서 할당 된 메모리 크기를 채우는 메모리 누수가 fillRegion에 있음을 의미합니다.

메모리 누수가 해결되지는 않지만 대신 Mat srcconst Mat& src으로 전달하는 것이 좋습니다. src에서 내부적으로 수정하지 않기 때문에 참조로 전달하면 불필요한 복사를 피할 수 있습니다.

는 메모리 누수가이 두 점검과 관련이 있다고 추측 내 : bot.y <= src.rows right.x <= src.cols

나는 그들이 대신 잘못된 점에 at를 호출 피하기 위해 (<)보다 확실히 덜해야한다고 생각합니다. 현재 Mat의 크기를 벗어난 지점에서 at을 호출하면 크기가 조정됩니까? 그렇다면 이러한 경계에 부딪 칠 때마다 이러한 이미지의 크기가 계속 조정됩니다. 기억 누출이 있습니다

한 가지 더 : 은 잠재적으로 (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

관련 문제