C++ opencv的Sysmalloc错误

C++ opencv的Sysmalloc错误,c++,opencv,matrix,malloc,C++,Opencv,Matrix,Malloc,我在使用opencv时遇到一个sysmalloc错误。调试时,我发现错误发生在以下位置: sm = cv::Mat::zeros(h,w,img.type()); 其中h和w分别为img行和w列。我展示了它们,它们还可以。以下是整个功能: cv::Mat gsmooth(cv::Mat img,int sigma,int radius,std::string methode) { cv::Mat sm; std::vector<double> hcol; s

我在使用opencv时遇到一个sysmalloc错误。调试时,我发现错误发生在以下位置:

sm = cv::Mat::zeros(h,w,img.type());
其中h和w分别为img行和w列。我展示了它们,它们还可以。以下是整个功能:

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

}
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);
}
我这样调用函数:new\u img=一些函数img,一些参数

我想知道这样做是否正确

我希望我已经说得够具体了,如果你需要更多的信息,请不要犹豫

编辑:使用Valgrind我发现当我尝试使用gKernel时出现了问题。 事实上,gsmooth被调用了两次,第一次调用一切正常,第二次调用时崩溃。Valgrind在函数的第一行指出了一个SIGSEGV错误:std::vector kernelsize

以下是整个功能:

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

}
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是size=2*radius+1的调用,sigma在第一次调用中等于60,在第二次调用中等于50


至少我学会了,我不应该用“=”复制cv::Mat,而应该用clone或copyTo来避免混淆像素的指针

您可能在某个地方损坏了内存,但不在上面的代码中。cv::Mat::zeros的使用看起来不错

用于查找问题的原因

更新


在前面的代码行中,我将m.at=someint替换为m.at=someint,从而解决了我的问题

它之所以有效,是因为Mat m不是由double type表示的。m应具有访问双元素的类型或类似类型。实际上,您的Mat m类型是CV_8U,它对应于您在修复中使用的uchar


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

谢谢,我试过Valgrind,这正是我需要的。我会用更多信息更新我的帖子,或者可能是解决方案?@RomainMartin我确信问题不在gKernel函数中。看起来在执行gsmooth之前内存已损坏。例如,检查图片加载功能。我相信你,但我找不到哪里有问题。图片加载功能看起来不错,一开始只调用了一次,我尝试用填充矩阵替换加载的图像,但仍然有相同的结果。。。如果我发现任何线索,我会再次检查并发布。我在代码的前几行中用m.at=someint替换了m.at=someint,从而解决了我的问题。但是我不明白为什么它和uchar一起工作而不是double,在大多数情况下我不需要double matrix,所以处理它是没有用的。除了增加我的图片的大小外,还有m。但在某些部分,我至少需要浮点数,所以我希望不会出现内存损坏的问题。如果有人能解释为什么它不起作用,我会让我的问题在几天内无人回答。不管怎样,谢谢尼基塔的帮助,你是对的。@RomainMartin看起来原因对我来说很清楚。请检查答案更新