OpenCV内存泄露问题

来源:互联网 发布:逆向歧视知乎 编辑:程序博客网 时间:2024/04/28 13:51

 OpenCV内存泄露问题

http://zhaostudy2.blog.163.com/blog/static/135350205201010160541433/

C/C++ 除Bug 2010-11-16 13:05:22 阅读253 评论0   字号: 订阅

    前几个月写了一个视频摘要程序和一个视频质量诊断程序,其中用到了opencv,程序截图如下:

 

 

 

 

    由于是第一次使用opencv,所以开发过程中遇到了一些内存泄露问题。

    1. cvCloneImage()

        ......
        IplImag *img = cvCreateImage( cvSize(frame->width,frame->hight), frame->depth, frame->nChannels );
        img = cvCloneImage(frame);

    这里出现内存泄露,因为调用cvCloneImage()之前已经用cvCreateImage()为图像分配了内存空间,而cvCloneImage()函数是对源图像的所有数据的拷贝,包括图像头、数据、ROI等,这就导致原来分配的内存空间变成了内存碎片,造成内存泄露。.解决方法如下:

        IplImag *img = cvCloneImage(frame);

    或 

        IplImag *img = cvCreateImage( cvSize(frame->width,frame->hight), frame->depth, frame->nChannels );

        cvReleaseImage(&img);
        img = cvCloneImage(frame);

    或

        IplImag *img = cvCreateImage( cvSize(frame->width,frame->hight), frame->depth, frame->nChannels );
        img = cvCloneImage(frame);

        cvCopy(frame,img,NULL);

 

    2. cvGetCols()、cvGetRows()

    ......

    CvMat *srcMat = cvCreateMat(width, height, CV_8UC3);  // 创建一个三通道无符号整数类型的矩阵
    cvGetCols(frame,srcMat,0,width);

    这里出现内存泄露,因为cvGetCols()、cvGetRows() 是为目标矩阵分配一块新的数据内存区域,如果目标矩阵的数据区域之前已经分配了内存,则会原始数据内存区域将变成内存碎片,造成内存泄露。解决方法如下:

        CvMat *srcMat = cvCreateMat(width, height, CV_8UC3);  // 创建一个三通道无符号整数类型的矩阵

        cvReleaseData(srcMat);    // 先释放目标矩阵的数据区

        cvGetCols(frame,srcMat,0,width);

    或者

         cvCreateMatHeader(width, height, CV_8UC3);

         cvGetCols(frame,srcMat,0,width);

注意:cvgetrow、cvgetcol只是把数据区指针指向源图像frame的某一行(列)数据,而不是申请新内存块且复制某一行(列)到新内存块,所以此时只能读操作,不能写,否则会改变源图像的值。

 

    3. IplImag*、CvMat*、CvHistogram* 等结构体指针在使用后要释放。

         IplImage *frame= cvCreateImage(cvSize(width,height),8,1);

         CvMat *srcMat = cvCreateMat(width, height, CV_8U);

         ......

         CvHistogram *hist = cvCreateHist(1,&histSize,CV_HIST_ARRAY,ranges,1);

         ......

         cvReleaseMat(&srcMat);
         cvReleaseImage(&frame);  
         cvReleaseHist(&hist);

0 0