我正面临使用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,而应该使用clone
或copyTo
来避免混淆像素点。
谢谢,我试过Valgrind,这正是我需要的。我会更新我的帖子以获得更多信息(或者解决方案?) –
@RomainMartin我相信问题不在'gKernel'函数中。看起来内存在执行“gsmooth”之前已经损坏。例如。检查图片加载功能。 – Nikita
我相信你,但我找不到可能出现问题的地方。图片加载功能看起来很好,它只在开始时被调用一次,我试图用一个填充矩阵替换加载的图像,但仍然有相同的结果...我会再次检查并发布,如果我发现任何线索。 –