C++ opencv的Sysmalloc错误
我在使用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
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看起来原因对我来说很清楚。请检查答案更新