2013-12-18 185 views
1

我很努力与我的opencv包装函数的发布版本。 函数代码运行正常,但是在功能块完成时,会发生内存访问冲突。 在调试模式下不会出现此问题。段错误发生在释放堆上。opencv Mat释放内存损坏

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,我已经阅读完全正常,因为它应该保持用户数据不变。

请帮忙。

UPDATE提供更多信息

谢谢你的建议。我显然倾向于创建这样的错误,我是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 ::垫 标志1124024344 INT 变暗2个INT 行640 INT COLS 640 INT
  • 数据0x12250040 “E9%” 无符号字符* 101 'E' 无符号字符
  • 的refcount 00000000 INT * CXX0030:错误:表达无法评估
  • datastart 0x12250040 “E9%” 无符号字符* 101 'E' 无符号字符
  • DATAEND 0x123e0040 “” 无符号字符* 0无符号字符
  • datalimit 0x123e0040 “” 无符号字符* 0无符号字符
  • 分配器00000000 CV :: MatAllocator * __vfptr CXX0030:错误:表达无法评估
  • 大小{P = 0x0012f44c} CV ::垫:: MSIZE
  • p 0x0012f44c INT * 640 INT
  • 步骤{p = 0x0012f474 BUF = 0x0012f474} CV ::垫:: MSTEP
  • p 0x0012f474无符号整型* 2560无符号整型
  • BUF 0x0012f474无符号整型[2] [0] 2560无符号整型 [1] 4无符号整型

而进入所述HOG描述符计算器

  • GREYimg {标志= 1124024320个变暗= 2行= 640灰色图像... } CV ::垫 标志1124024320 INT 变暗2个INT 行640 INT COLS 640 INT
  • 的refcount 0x0c867ff0 INT * 1 INT
  • d ataend 0x0c867ff0 “” 无符号字符* 1 '' 无符号字符
  • datalimit 0x0c867ff0 “” 无符号字符* 1 '' 无符号字符
  • 分配器00000000 CV :: MatAllocator * __vfptr CXX0030:错误:表达无法计算
  • 大小{p = 0x0012f40c} CV ::垫:: MSIZE
  • p 0x0012f40c INT * 640 INT
  • 步骤{p = 0x0012f434 BUF = 0x0012f434} CV ::垫:: MSTEP
  • p 0x0012f434无符号int * 640无符号整型
  • BUF 0x0012f434无符号整型[2] [0] 640无符号整型 [1] 1无符号整型

我不得不ommit数据和datastart字段,因为不像用于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建设。我希望这是原因。

回答

0

这可能不起作用像您期望:

sizeof(CV_8UC4)*Info->xRes 

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

如果你的数据是连续的,你可能会直接跳过步幅PARAM完全,或:

sizeof(Vec4b)*Info->xRes 

另一件事:

您BGRAimg有4个通道,对不对?因此,使用

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

代替