openCV 記憶體釋放要注意
引用自http://blog.csdn.net/xiaowei_cqu/article/details/7586847
1、內存洩露
內存洩露是說沒有釋放已經不能使用的內存,這裡一般指堆的內存才需要顯示的釋放。比如用malloc,calloc,realloc,new分配的 內存是在堆上的,需要用free,delete顯示的回收。內存洩露最明顯的一是程序很慢,在運行程序時你可以啟動任務管理器,會看到程序佔用的內存一直 「砰砰砰」的往上漲:
最後直接崩潰,或者你關閉程序的時候也會異常退出,出現
Debug Assertion Failed!
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
之類的問題。
除了new的對象我們知道要delete。OpenCV中使用cvCreateImage()新建一個IplImage*,以及使用cvCreateMat()新建一個CvMat*,都需要cvReleaseImage() cvReleaseMat()顯示的釋放
- IplImage* subImg=cvCreateImage( cvSize((img->width)*scale,(img->height)*scale), 8, 3 );
- CvMat *tempMat=cvCreateMat((img->width)*scale,(maxFace->height)*scale,CV_MAKETYPE(image->depth,image->nChannels));
- cvReleaseImage(&subImg);
- cvReleaseMat(&tempMat);
另外一些函數要用到 CvSeq*來存放結果(通常這些都要用cvCreateMemStorage()事先分配一塊內存CvMemStorage*),都要是釋放掉相應的內存,這是很難找的。
比如從二值圖像中尋找輪廓的函數cvFindContours():
- CvMemStorage* m_storage=cvCreateMemStorage(0);
- CvSeq * m_contour=0;
- cvFindContours( img, m_storage, &m_contour, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
- //釋放內存
- cvReleaseMemStorage(&m_storage);
以及人臉識別中檢測人臉的函數:
- CvMemStorage* m_storage=cvCreateMemStorage(0);
- CvHaarClassifierCascade* cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );
- CvSeq* faces = cvHaarDetectObjects( img, cascade, m_storage,1.1, 2, 0,cvSize(30, 30) );
- //釋放內存
- cvReleaseMemStorage( &faces->storage);
- cvReleaseHaarClassifierCascade( &cascade );
注意這裡我們可以使用
cvReleaseMemStorage( &faces->storage);
來釋放m_storate,也可以使用:
cvReleaseMemStorage(&m_storage);
釋放內存,這是等效的,但一定不要用兩次!!
2、一塊內存多次釋放
對應沒有釋放內存,對應就是一個內存釋放多次,如同上面的 cvReleaseMemStorage用了兩次。可能報錯的地方:
- __declspec(noinline)
- void __cdecl _CRT_DEBUGGER_HOOK(int _Reserved)
- {
- /* assign 0 to _debugger_hook_dummy so that the function is not folded in retail */
- (_Reserved);
- _debugger_hook_dummy = 0;
- }
或者: Unhandled exception at XXXXXXXXXX in XXX.exe: XXXXXXXXXXX: 堆已損壞。
除了上述的MemStorge問題,使用cvQueryFrame()取出CvCapture*每幀圖像,只需在最後釋放CvCapture*,不需要釋放IplImage*
- CvCapture* pCapture = cvCreateCameraCapture(-1);
- IplImage* pFrame=cvQueryFrame( pCapture );
- cvReleaseCapture(&pCapture);
*這篇是以前寫的,其實還是建議大家用C++接口的OpenCV,內存問題很少了~
Leave a Reply