【问题标题】:opencv Mat deallocation memory corruptionopencv Mat 释放内存损坏
【发布时间】:2014-01-07 09:22:24
【问题描述】:

我正在为我的 opencv 包装函数的发布版本而苦苦挣扎。 功能代码运行良好,但功能块完成后,发生内存访问冲突。 在调试模式下不会出现此问题。段错误发生在释放堆时。

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(代码中的注释版本)并使用带有 IplImage 参数的 Mat 构造函数,但遇到了同样的问题。 我知道我在 Mat 构建过程中做错了什么,因为从磁盘手动加载图像不会导致问题。

创建Mat对象后,其所有参数正确,图像正常。当与它创建的灰色矩阵进行比较时,它的 refcount NULL,我读过它非常好,因为它应该保持用户数据完整。

请帮忙。

更新以提供更多信息

感谢您的建议。我显然很容易产生这样的错误,我是 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

窗口步幅 32

其余参数为默认值。

我决定将 Mat 对象的外观包含在内,希望对您有所帮助。

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

  • BGRAimg {flags=1124024344 dims=2 rows=640 ...} cv::Mat 标志 1124024344 int 调暗 2 int 行 640 整数 cols 640 整数
  • 数据 0x12250040 "e9%" 无符号字符 * 101 'e' 无符号字符
  • 引用计数 0x00000000 int * CXX0030:错误:无法评估表达式
  • datastart 0x12250040 "e9%" unsigned char * 101 'e' 无符号字符
  • dataend 0x123e0040 "" unsigned char * 0 个无符号字符
  • datalimit 0x123e0040 "" unsigned char * 0 个无符号字符
  • 分配器 0x00000000 cv::MatAllocator * __vfptr CXX0030:错误:无法评估表达式
  • 尺寸 {p=0x0012f44c } cv::Mat::MSize
  • p 0x0012f44c 整数 * 640 整数
  • 步骤 {p=0x0012f474 buf=0x0012f474 } cv::Mat::MStep
  • p 0x0012f474 无符号整数 * 2560 无符号整数
  • buf 0x0012f474 无符号整数 [2] [0] 2560 无符号整数 [1] 4 无符号整数

以及进入 HOG 描述符计算器的灰度图像

  • GREYimg {flags=1124024320 dims=2 rows=640 ...} cv::Mat 标志 1124024320 int 调暗 2 int 行 640 整数 cols 640 整数
  • 引用计数 0x0c867ff0 整数 * 1 个整数
  • dataend 0x0c867ff0 "" unsigned char * 1 '' 无符号字符
  • datalimit 0x0c867ff0 "" unsigned char * 1 '' 无符号字符
  • 分配器 0x00000000 cv::MatAllocator * __vfptr CXX0030:错误:无法评估表达式
  • 尺寸 {p=0x0012f40c } cv::Mat::MSize
  • p 0x0012f40c 整数 * 640 整数
  • 步骤 {p=0x0012f434 buf=0x0012f434 } cv::Mat::MStep
  • p 0x0012f434 无符号整数 * 640 无符号整数
  • buf 0x0012f434 无符号整数 [2] [0] 640 无符号整数 [1] 1 个无符号整数

我不得不省略 data 和 datastart 字段,因为与 BGRA 图像不同,MSVS 实际上在其中显示了一些数据。

更新2

在项目属性中为多线程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

在阅读了有关 microsoft runtime 的内容后,我决定检查我的 opencv 是如何构建的,它使用 /MD,而我正在使用 /MT 构建。我希望这是原因。

【问题讨论】:

    标签: c++ opencv


    【解决方案1】:

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

    sizeof(CV_8UC4)*Info->xRes
    

    CV_8UC4 是枚举,不是类型,这里不能使用 sizeof()。

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

    sizeof(Vec4b)*Info->xRes
    

    另一件事:

    你的 BGRAimg 有 4 个频道,对吧?所以,使用

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

    改为

    【讨论】:

      猜你喜欢
      • 2023-03-18
      • 2016-05-08
      • 2011-08-21
      • 1970-01-01
      • 1970-01-01
      • 2012-07-27
      • 2016-12-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多