首页 文章

opencv Mat deallocation内存损坏

提问于
浏览
1

我正在努力解决我的opencv包装函数的发布版本 . 函数代码运行正常,但在功能块完成时,会发生内存访问冲突 . 调试模式下不会出现此问题 . segfault在释放堆时发生 .

int Myfunc(Arr1D_floatHdl FeatArrHdl, IMAQ_Image *img, someparams 
*Params)
{
ImageInfo *Info = NULL;
//IplImage *CVImage = NULL;
Info = (ImageInfo*)img->address;
CheckImage(Info, Info);
//CVImage = cvCreateImageHeader( cvSize(Info->xRes, Info->yRes), IPL_DEPTH_8U, 4);
//CVImage->imageData = (char*)Info->imageStart;
//CVImage->widthStep = Info->xRes*sizeof(IPL_DEPTH_8U);
cv::Mat BGRAimg = cv::Mat(Info->yRes, Info->xRes, CV_8UC4, (char*)Info->imageStart, sizeof(CV_8UC4)*Info->xRes);
//cv::Mat BGRAimg(CVImage);
//cv::Mat BGRAimg = imread( "MyImg.png", cv::IMREAD_COLOR );
cv::Mat GREYimg;
cv::cvtColor(BGRAimg, GREYimg, CV_BGR2GRAY);

这是我从用户提供的数据创建Mat对象的代码 . 我试图首先创建IplImage(在代码中注释版本)并使用Mat构造函数和IplImage参数,但是遇到了同样的问题 . 我知道我在Mat构造期间做了一些非常错误的事情,因为从磁盘手动加载图像不会导致问题 .

创建Mat对象后,其所有参数都正确,图像正常 . 当与它创建的灰色矩阵进行比较时,它已经引用了NULL,我已经读过它非常好,因为它应该保持用户数据不变 .

请帮忙 .

UPDATE to give more information

谢谢你的建议 . 我显然容易产生这样的错误,我是C / C的新手 . 不幸的是,访问冲突仍然存在 .

这是完整的包装函数 . 我试图缩小问题范围,并跳过HOG.compute函数,我不再让内存损坏 . 最后跳过memcpy杂技,我仍然得到内存损坏 .

int GetHOGFeatures(Arr1D_floatHdl FeatArrHdl, IMAQ_Image *img, HogParams *Params) //returns -1 on HOG window parameters missmatch
{
ImageInfo *Info = NULL;
Info = (ImageInfo*)img->address;
CheckImage(Info, Info);

cv::Mat BGRAimg = cv::Mat(Info->yRes, Info->xRes, CV_8UC4, (char*)Info->imageStart, sizeof(cv::Vec4b)*Info->xRes);
cv::Mat GREYimg;
cv::cvtColor(BGRAimg, GREYimg, CV_BGRA2GRAY);

//set params into hog object
cv::HOGDescriptor hog;
hog.winSize = cv::Size(Params->winsize_width, Params->winsize_height);
hog.blockSize = cv::Size(Params->blocksize_width, Params->blocksize_height);
hog.blockStride = cv::Size(Params->blockstride_x, Params->blockstride_y);
hog.cellSize = cv::Size(Params->cellsize_width, Params->cellsize_height);
hog.nbins = Params->nBins;
hog.derivAperture = Params->derivAperture;
hog.winSigma = Params->win_sigma;
hog.L2HysThreshold = Params->threshold_L2hys;
hog.gammaCorrection = (Params->gammaCorrection != 0);

MgErr error = mgNoErr;

cv::vector<float> ders;
cv::vector<cv::Point> locations;

try
{
    //winstride - step of window
    //padding - borderpadding
    //raises exception with incorrect params ... todo replace trycatch with paramchecking
    hog.compute(GREYimg, ders, cv::Size(Params->winstride_x, Params->winstride_y), cv::Size(0,0), locations);
}
catch(...)
{
    return -1;
}
//copy out the data into LabView
error = DSSetHandleSize(FeatArrHdl, sizeof(int32_t) + ders.size()*sizeof(float));
memcpy((*FeatArrHdl)->Arr, ders.data(), sizeof(float)*ders.size());
(*FeatArrHdl)->dimSize = ders.size();

return error;

}

我正在使用以下参数运行此函数:

窗口大小32块大小16单元大小8块大步8

窗口 Span 32

其余参数是默认的 .

我决定在构建之后包含Mat对象的外观,我希望它可以提供帮助 .

这是根据用户数据构建的BGRA . 它应该是640 * 640 BGRA

  • BGRAimg cv :: Mat flags 1124024344 int dims 2 int rows 640 int cols 640 int

  • data 0x12250040 "e9%" unsigned char * 101 'e' unsigned char

  • refcount 0x00000000 int * CXX0030:错误:无法计算表达式

  • datastart 0x12250040 "e9%" unsigned char * 101 'e' unsigned char

  • dataend 0x123e0040“”unsigned char * 0 unsigned char

  • datalimit 0x123e0040“”unsigned char * 0 unsigned char

  • allocator 0x00000000 cv :: MatAllocator * __vfptr CXX0030:错误:表达式无法评估

  • size cv :: Mat :: MSize

  • p 0x0012f44c int * 640 int

  • cv :: Mat :: MStep

  • p 0x0012f474 unsigned int * 2560 unsigned int

  • buf 0x0012f474 unsigned int [2] [0] 2560 unsigned int [1] 4 unsigned int

进入HOG描述符计算器的灰色图像

  • GREYimg cv :: Mat flags 1124024320 int dims 2 int rows 640 int cols 640 int

  • refcount 0x0c867ff0 int * 1 int

  • dataend 0x0c867ff0“”unsigned char * 1''unsigned char

  • datalimit 0x0c867ff0“”unsigned char * 1''unsigned char

  • allocator 0x00000000 cv :: MatAllocator * __vfptr CXX0030:错误:表达式无法评估

  • size cv :: Mat :: MSize

  • p 0x0012f40c int * 640 int

  • cv :: Mat :: MStep

  • p 0x0012f434 unsigned int * 640 unsigned int

  • buf 0x0012f434 unsigned int [2] [0] 640 unsigned int [1] 1 unsigned int

我不得不省略数据和数据广告字段,因为与BGRA图像不同,MSVS实际上显示了一些数据 .

UPDATE2

在项目特性中改变了多线程DLL的多线程,问题就消失了 .

即使我使用这样的代码,问题仍然存在:

int dim = 32;
BYTE *mydata = NULL;
mydata = (BYTE*)malloc(sizeof(BYTE)*dim*dim);
Mat img;
img = Mat(Size(dim,dim), CV_8U, mydata, dim*sizeof(BYTE));

可能这表明我的代码不是原因,这有点opencv x windows运行时问题,还是我只是隐藏了问题?

UPDATE3

在阅读了关于微软运行时的内容之后,我决定检查我的opencv是如何构建的,并且它正在使用/ MD,而我正在使用/ MT构建 . 我希望这是原因 .

1 回答

  • 0

    这可能不像你期望的那样工作:

    sizeof(CV_8UC4)*Info->xRes
    

    CV_8UC4是一个枚举,而不是一个类型,你不能在这里使用sizeof() .

    如果你的数据是连续的,你可能只是完全跳过步幅参数,或者:

    sizeof(Vec4b)*Info->xRes
    

    另一件事:

    你的BGRAimg有4个 Channels ,对吗?所以,使用

    cv::cvtColor(BGRAimg, GREYimg, CV_BGRA2GRAY);
    

    代替

相关问题