繁体   English   中英

OpenCV的Sysmalloc错误

[英]Sysmalloc error with opencv

我正在使用opencv遇到sysmalloc错误。 当我调试时,我发现错误发生在这里:

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

}

该函数由另一个具有cv :: Mat img,两个int和“ mirror”或“ none”的.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.* *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。

我确定我的错误是愚蠢的,也许我不能像这样声明一个零矩阵,但是我不知道该怎么做,而且我也没有找到与此问题相关的话题。

总的来说,我对使用opencv的malloc问题非常困惑。 大多数时候,我使用函数在参数中获取cv :: Mat并使用它返回在函数内部声明的新矩阵,如下所示:

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被调用了两次,第一个调用一切正常,并且崩溃发生在第二个调用期间。 Valgrind在函数的第一行指出了SIGSEGV错误: 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);
}

我不明白为什么声明向量可能导致Segfault? 正如您在我的gsmooth函数中看到的那样,调用gKernel的大小为2 *半径+1,并且sigma在第一次调用中等于60,而在第二次调用中等于50。

至少我了解到,我不应该使用'='复制cv :: Mat,而应该使用clonecopyToclone ,以免干扰像素的指针。

可能您损坏了某处的内存,但没有损坏上面的代码。 使用cv::Mat::zeros看起来不错。

使用Valgrind查找问题的原因。

更新

我通过在代码的前几行中将m.at = someint替换为m.at = someint来解决了我的问题

之所以起作用,是因为Mat m没有用double类型表示。 m应该具有CV_64F类型或类似类型才能访问double元素。 实际上,您的Mat m类型是CV_8U ,它对应于您在修订中使用的uchar

要更改Mat m类型,可以使用convertTo方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM