2013-12-18 99 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); 

代替