mfc中使用opencv显示图片并释放内存

最近接触了opencv,想在mfc下使用opencv,但opencv中有内存释放的问题,可查了一些东西,没有提到在mfc下的内存释放怎么做的问题,求教一下到底该怎么做?
ps:我用的是基于对话框的,vs10+opencv2.4.0

前一天把系统整个重写了一遍,脉络清晰了很多,也终于解决了以前很多崩溃,异常退出的问题。这里小小总结一下自己遇到的麻烦。

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()显示的释放

[cpp] view plaincopyprint?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);

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():

[cpp] view plaincopyprint?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);
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);
以及人脸识别中检测人脸的函数:

[cpp] view plaincopyprint?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 );

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用了两次。可能报错的地方:

[cpp] view plaincopyprint?__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;
}

__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*

[cpp] view plaincopyprint?CvCapture* pCapture = cvCreateCameraCapture(-1);
IplImage* pFrame=cvQueryFrame( pCapture );
cvReleaseCapture(&pCapture);

CvCapture* pCapture = cvCreateCameraCapture(-1);
IplImage* pFrame=cvQueryFrame( pCapture );
cvReleaseCapture(&pCapture);
*这篇是以前写的,其实还是建议大家用C++接口的OpenCV,内存问题很少了~追问

谢了兄弟,还有一个问题我把wingdi。h包含进来,编译结果大量报错

是什么情况?

温馨提示:内容为网友见解,仅供参考
无其他回答

mfc中使用opencv显示图片并释放内存
内存泄露是说没有释放已经不能使用的内存,这里一般指堆的内存才需要显示的释放。比如用malloc,calloc,realloc,new分配的内存是在堆上的,需要用free,delete显示的回收。内存泄露最明显的一是程序很慢,在运行程序时你可以启动任务管理器,会看到程序占用的内存一直“砰砰砰”的往上涨:最后直接崩溃,或...

MFC中用OPENCV如何将图片显示在指定位置
void *pImageMemory=GlobalLock(hImageMemory);\/\/保存实际读取的文件大小 DWORD dwReadedSize;\/\/读取图片到全局内存当中 ReadFile(hFile, pImageMemory, dwFileSize, &dwReadedSize, NULL);GlobalUnlock(hImageMemory); \/\/解锁内存 CloseHandle(hFile); \/\/关闭文件句柄 IStream *pIStream;\/\/创建一个...

MFC中如何在一个picture 控件中显示一张opencv读入的图片?
如果下面能正确显示,上面的逻辑是正确的,我觉得应该是 IplImage* img_src = cvLoadImage("img4.jpg",CV_LOAD_IMAGE_GRAYSCALE);这里失败了;图片路径用绝对路径试试;或者获取一下程序所以目录,再加上文件名;

求助,MFC 使用picture control显示图像出现问题
使用openCV的 cv::Mat 读取图片之后,需要在picture control控件中将图片显示出来。其过程是这样的:1、将 cv::Mat 转换格式为 IplImage,2、然后将 IplImage 转换格式为 CvvImage,因为 CvvImage 类中有函数 DrawToHDC(),可以直接完成MFC空间中的绘图。

用VC++的MFC实现图像的打开,显示,保存,擦除功能的代码
用opencv库,里面所有符合你要的功能函数都有,而且网上很多opencv的例子,随便就能搜索到,给你推荐这个网站http:\/\/blog.csdn.net\/abcjennifer\/article\/details\/7313711;opencv 配置网址在这里:http:\/\/www.cnblogs.com\/freedomshe\/archive\/2012\/04\/25\/2470540.html 希望能帮到你。^_^ ...

openCV采集摄像头图片并保存的方法
void CVideomfcDlg::callback1(IplImage *image){ IplImage* image1 = image;int i,j;assert (image);\/\/获取当前系统时间 SYSTEMTIME st2=;GetLocalTime(&st2);char sss[18]=; \/\/这个是用来存储所要保存的图片名的,用的是一个笨办法,先定义,再修改其中的数组值。sss[7]=st2.wHour\/10...

使用MFC获取USB摄像头图像保存并在单窗口指定位置显示
openCV采集摄像图片并保存 我用代码 include "cv.h"include "highgui.h"void main(){ CvCapture* capture;capture=cvCreateCameraCapture(0);assert(capture!=NULL);IplImage* frame;cvNamedWindow("camera",1);while(1){ frame=cvQueryFrame(capture);if(!frame)break;cvShowImage("camera",frame);if...

MFC list control,如何自绘显示图片? 效果如图
用CImageList,你可以在msdn查下CImageList。把你的图片资源保存到CImageList里。

MFC固有窗口下如何加载IplImage图像
hr = m_pVW->put_Owner((OAHWND)m_hWnd); \/\/窗口所有者:传入的窗口句柄 if (FAILED(hr)) return 0;hr = m_pVW->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN);\/\/设置窗口类型 if (FAILED(hr)) return hr;if (m_pVW){ \/\/让图像充满整个指定窗口 CRect rc;::GetClientRect(m_h...

openCV代码在vc++中实现图片缩放功能
cvNamedWindow(imgName[1], CV_WINDOW_AUTOSIZE);\/\/创建用于显示目标图像的窗口 cvShowImage(imgName[0], src);\/\/显示源图像 cvShowImage(imgName[1], dst);\/\/显示目标图像 cvWaitKey(-1);\/\/等待用户响应 cvReleaseImage(&src);\/\/释放源图像占用的内存 cvReleaseImage(&dst);\/\/释放目标图像占用的...

相似回答