1
votes

I am struggling with release version of my opencv wrapper function. The function code runs fine, but upon function block completition, memory access violation happens. This problem does not appear in debug mode. The segfault happens upon freeing the heap.

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);

Here is the code where I create Mat object from user supplied data. I tried to create IplImage first (commented version in code) and use Mat constructor with IplImage argument, but eneded up with the same problem. I know I am doing something very wrong during the Mat construction, since manualy loading the image from disk does not cause the issue.

After creating the Mat object, all its parameters are correct and the image is fine. When comparing with the grey matrix created of it, it has refcount NULL, which I have read is perfectly fine since it is supposed to keep user data intact.

Please help.

UPDATE to give more information

Thank you for suggestions. I am obviously prone to create such errors, I am new to C/C++. Unfortunately, the access violation still persists.

Here is the complete wrapper function as it is. I tried to narrow down the problem, and skipping the HOG.compute function I do no longer get memory corruption. Skipping the memcpy acrobatics in the end, I still get the memory corrupted.

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;

}

I am running this function with following parameters:

Window size 32 Block size 16 Cell size 8 Block stride 8

Window stride 32

the rest of parameters is default.

I decided to include the look of the Mat object once constructed, I hope it can help.

This is the BGRA constructed from user data. It is supposed to be 640*640 BGRA

  • BGRAimg {flags=1124024344 dims=2 rows=640 ...} 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: Error: expression cannot be evaluated
  • 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: Error: expression cannot be evaluated
  • size {p=0x0012f44c } cv::Mat::MSize
  • p 0x0012f44c int * 640 int
  • step {p=0x0012f474 buf=0x0012f474 } cv::Mat::MStep
  • p 0x0012f474 unsigned int * 2560 unsigned int
  • buf 0x0012f474 unsigned int [2] [0] 2560 unsigned int [1] 4 unsigned int

And the Grey image that enters the HOG descriptors calculator

  • GREYimg {flags=1124024320 dims=2 rows=640 ...} 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: Error: expression cannot be evaluated
  • size {p=0x0012f40c } cv::Mat::MSize
  • p 0x0012f40c int * 640 int
  • step {p=0x0012f434 buf=0x0012f434 } cv::Mat::MStep
  • p 0x0012f434 unsigned int * 640 unsigned int
  • buf 0x0012f434 unsigned int [2] [0] 640 unsigned int [1] 1 unsigned int

I had to ommit the data and datastart fields, because unlike for the BGRA image MSVS actually shows some data in it.

UPDATE2

changed multi-threaded for multi-threaded DLL in project properities, and the issue is gone.

The problem persisted even if I was using code like this :

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));

Might this indicate my code was not the cause, and this is somewhat opencv x windows runtime issue, or did I just hide the problem ?

UPDATE3

After reading something about microsoft runtime, I decided to check how was my opencv built, and it is using /MD, and I was building with /MT. I hope this was the cause.

1

1 Answers

0
votes

this might not work like you expect:

sizeof(CV_8UC4)*Info->xRes

CV_8UC4 is an enum, not a type, you can't use sizeof() here.

if your data is continuous, you probably might just skip the stride param completely, or:

sizeof(Vec4b)*Info->xRes

another thing:

your BGRAimg has 4 channels, right ? so, use

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

instead