老外發現的opencv中cvtexture中的三個bug出處:http://tech.groups.yahoo.com/group/OpenCV/messages/18038?threaded=1&m=e&var=1&tidx=1
Hello everybody, I ever delivered two articles about GLCM, asking about how to use it(exactly the meaning of the structure member and the meaning of
the function parameters, see 17848).It seems few people are dealing with it and so no one answered me. It is said that you can count on
yourself if no one can be relied on. So I read the whole source code. Fortunately, I have comprehended 90% of them and found 3 bugs
which are listed below. Anyone who is dealing with texture analysis is welcome to get contact with me. We can communicate with each
other. And two heads are always better than one head. Best wishes to everyone~!
In the file “cvtexture.cpp”
(1).In the function “cvCreateGLCM()”,when we allocate memory to the pointer of structure GLCM, “newGLCM”. A mistake was made here.
The original code is:
CV_CALL(newGLCM=(CvGLCM*)cvAlloc(sizeof(newGLCM))); memset( newGLCM, 0, sizeof(newGLCM) );
The right one is:
CV_CALL( newGLCM = (CvGLCM*)cvAlloc(sizeof(CvGLCM))); memset( newGLCM, 0, sizeof(CvGLCM) ); (2).In the function “icvCreateGLCM_LookupTable_8u_C1R()”,when we allocate memory to one member of structure GLCM, double ***matrices.
Here appears another mistake. They should be replaced by the commentary.
CV_CALL(matrices[stepLoop]=(double**)cvAlloc( sizeof(matrices[0])*matrixSideLength ));//BUG!//CV_CALL(matrices[stepLoop]=(double**)cvAlloc( sizeof(matrices[0][0])*matrixSideLength )); CV_CALL(matrices[stepLoop][0]=(double*)cvAlloc (sizeof(matrices[0][0])matrixSideLength*matrixSideLength ));//BUG!//CV_CALL(matrices[stepLoop][0]=(double*)cvAlloc ( sizeof(double)*matrixSideLength*matrixSideLength ));memset(matrices[stepLoop]0],0,matrixSideLength*matrixSideLength*sizeof(matrices[0][0]) );//BUG //memset(matrices[stepLoop][0],0,atrixSideLength*matrixSideLength*sizeof(double));
(3)In the function “icvCreateGLCMDescriptors_AllowDoubleNest()”,the last statement “delete [] marginalProbability;
”should be replaced by “cvFree( (void**)&marginalProbability);” Because the forward statement
“double*marginalProbability=(double*)cvAlloc(matrixSideLength*sizeof(marginalProbability[0]));”.
Allocation of memory should be coincided with the release of memory.“malloc” with “free”,and “new” with“delete”.
That’s all. Thank you for your attention~!
我按照上面所說的修改完三個bug所確實可以運行,但有個嚴重的問題,那就是記憶體流失,檢測一個幾分鐘的視頻記憶體都被吸光了,機子動不了,只能關機重啟。
經過斷點排查,原來cvReleaseGLCM函數中還有一個bug,就是if(*GLCM) EXIT; // repeated deallocation: just skip it.
應該改為
if(!(*GLCM)) EXIT; // repeated deallocation: just skip it.
近期使用二值化映像進行提取紋理特徵,發現會報錯,原來函數icvCreateGLCMDescriptors_AllowDoubleNest有漏洞,修改如下:
原始代碼:
marginalProbabilityEntropy += marginalProbability[ actualSideLoop1 ]*log(marginalProbability[ actualSideLoop1 ]);double HXYValue = marginalProbability[ actualSideLoop1 ] * marginalProbability[ actualSideLoop2 ];
應該修改為:
marginalProbabilityEntropy += marginalProbability[ sideLoop1 ]*log(marginalProbability[ sideLoop1 ]);double HXYValue = marginalProbability[ sideLoop1 ] * marginalProbability[ sideLoop2 ];
這樣,opencv的紋理檢測就完善了。