2017-03-03 53 views
0

我正面臨使用opencv的sysmalloc錯誤。當我調試時發現錯誤發生在這裏:Sysmalloc錯誤與opencv

sm = cv::Mat::zeros(h,w,img.type()); 

其中h和w分別是img行和w cols。我展示了他們,他們沒事。這裏是整個函數:

cv::Mat gsmooth(cv::Mat img,int sigma,int radius,std::string methode) 
{ 
    cv::Mat sm; 
    std::vector<double> hcol; 
    std::vector<double> hrow; 
    if(sigma == NULL) 
    { 
     sigma =1; 
    } 
    if(radius == NULL) 
    { 
     radius = ceil(2.5*sigma); 
    } 
    if(methode.c_str()==NULL) 
    { 
     methode ="none"; 
    } 

    if(sigma == 0) 
    { 
     sm = img; 
    } 
    else 
    { 

     hcol= gKernel(2*radius+1,sigma); 
     hrow= gKernel(2*radius+1,sigma); 
     int h=img.rows; 
     int w=img.cols; 
     int c=img.channels(); 
     switch (c) 
     { 
       case 1: 
        sm= cv::Mat::zeros(h,w,img.type()); 
        break; 
       case 2: 
        sm= cv::Mat::zeros(h,w,CV_32SC2); 
        break; 
       default: 
        sm= cv::Mat::zeros(h,w,CV_32SC3); 
     } 
     if(!methode.compare(std::string("mirror"))) 
     { 
      cv::Mat mattmp=mirror(img,radius,radius); 
      sm=conv2(mattmp,hcol,hrow); 

      int ma=img.rows; 
      int na=img.cols; 
      int nb=hcol.size(); 
      int mb=hrow.size(); 
      sm=sm.rowRange((mb-1)/2,(mb-1)/2+ma).colRange((nb-1)/2,(nb-1)/2+na); 
     } 
     else 
     { 
      cv::Mat sm_; 
      sm_=conv2(img,hcol,hrow); 
      int H=sm.rows; 
      int W=sm.cols; 
      int h=img.rows; 
      int w=img.cols; 
      int y=ceil(H/h); 
      int x=ceil(W/w); 
      sm=sm.rowRange(y,y+h).colRange(x,x+w); 
     } 

    } 
    hcol.clear(); 
    hrow.clear(); 
    return(sm); 

} 

的功能就是通過與個人簡歷::墊IMG,兩個int和「鏡子」或「無」另一個的.cpp電話。參數看起來是正確的:img矩陣被正確加載,而另一個只是int。

完整的錯誤是:*malloc.c:2372: sysmalloc: Assertion '(old_top== (((mbinptr) (((char *) &((av)->bins[((1) - 1)*2)) -__builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk,fd_nextsize))+((2*(sizeof(size_t))) -1)) & ~((2*sizeof(size_t))) -1)))&& ((old_top)-> size & 0x1) && ((unsigned long) old_end & pagemask) ==0)' failed.*

我在使用Qt 5.2,GCC 4.6和g ++ 4.4的Ubuntu 14.04.5,我已經使用OpenCV的2.4.13由於與編織LIB兼容性問題。

我敢肯定,我的錯誤是愚蠢的東西,也許我不能宣佈零這樣一個矩陣,但我不知道該怎麼做,否則,我沒有找到這個問題的任何話題的親戚。

一般來說,我很堅持使用opencv的malloc問題。大部分的時間,我使用的功能越來越簡歷::墊在參數並用它來返回函數內聲明的一個新的矩陣,就像這樣:

cv::Mat function somefunction(cv::Mat img, some arguments) 
{ 
    cv::Mat res; 
    //operations 
    return(res); 
} 

和我這樣調用該函數:new_img=some_function(img, some_arguments);

我不知道這是正確的做法嗎?

我希望我已經足夠具體,不要猶豫,如果你需要更多的信息。

編輯:使用Valgrind我發現問題發生在我嘗試使用gKernel時。 事實上gsmooth是兩次調用,第一次是一切正常,並在第二次調用期間發生崩潰。 std::vector<double> kernel(size);

這裏是整個函數:

std::vector<double> gKernel(int size, float sigma) 
{ 
    std::vector<double>kernel(size); 
    double r,s =2.0* sigma * sigma; 
    double sum=0.0; 
    int radius=(size -1)/2; 
    int index=0; 
    for(int y=-radius; y<=radius;y++) 
    { 
     r=sqrt(y*y); 
     kernel[index]=(exp(-(r*r)/s))/(sqrt(2*M_PI*s)); 
     sum+=kernel[index]; 
     index++; 
    } 
    for(int i=0;i<size;i++) 
    { 
     kernel[i]/=sum; 
    } 
    return(kernel); 
} 

我不明白爲什麼聲明一個向量可能會導致段錯誤Valgrind的在函數的第一行指出SIGSEGV錯誤? 正如你在我的gsmooth函數中看到的那樣,gKernel的調用大小= 2 *半徑+1,第一次調用sigma等於60,第二次調用50。

至少我瞭解到,我不應該使用'='複製cv :: Mat,而應該使用clonecopyTo來避免混淆像素點。

回答

1

也許你在某處已經損壞了內存,但不是在上面的代碼中。使用cv::Mat::zeros看起來不錯。使用Valgrind找到問題的原因。

UPDATE

我用替換m m.at = someint解決了我的問題。在=在我的代碼前面的行someint

它的工作,因爲你的Mat m沒有被double類型表示。 m應具有類型CV_64F或類似訪問double元素。其實您的Mat m類型是CV_8U,它對應於您在修復中使用的uchar

要更改Mat m的類型,您可以使用convertTo方法。

+0

謝謝,我試過Valgrind,這正是我需要的。我會更新我的帖子以獲得更多信息(或者解決方案?) –

+0

@RomainMartin我相信問題不在'gKernel'函數中。看起來內存在執行「gsmooth」之前已經損壞。例如。檢查圖片加載功能。 – Nikita

+0

我相信你,但我找不到可能出現問題的地方。圖片加載功能看起來很好,它只在開始時被調用一次,我試圖用一個填充矩陣替換加載的圖像,但仍然有相同的結果...我會再次檢查併發布,如果我發現任何線索。 –