zoukankan      html  css  js  c++  java
  • cvCreateImageHeader导致内存不足的问题

    cvCreateImage --cvReleaseImage

    这两个函数在使用中我原以为前面创建,后面释放了,就不会存在什么内存的问题。而且平时用的时候也没出现过由于创建图像头导致内存不足。因为平时只是对一两副图片作处理,所以问题不大,但到了处理连续的视频图像时,问题就来了,PF使用率会一直上升,直到内存不足,迫使程序终止。(Insufficient memory(Out of memory) in function cvAlloc)。即使是把cvCreateImageHeader封装在函数中,仍然会出现这样的问题。

    我的代码是这样的(在循环中反复创建释放):

    1. CvRect rect;  
    2. IplImage* subimg = cvCreateImageHeader(  
    3.     cvSize(rect.width,rect.height),  
    4.     srcimg->depth,  
    5.     srcimg->nChannels  
    6. );  
    7. subimg->origin = srcimg->origin;  
    8. subimg->widthStep = srcimg->widthStep;  
    9. subimg->imageData = srcimg->imageData +rect.y * srcimg->widthStep + rect.x * srcimg->nChannels;  
    10. //        对子图像作处理部分      //  
    11. cvReleaseImageHeader(&subimg);  
    CvRect rect;
    IplImage* subimg = cvCreateImageHeader(
        cvSize(rect.width,rect.height),
        srcimg->depth,
        srcimg->nChannels
    );
    subimg->origin = srcimg->origin;
    subimg->widthStep = srcimg->widthStep;
    subimg->imageData = srcimg->imageData +rect.y * srcimg->widthStep + rect.x * srcimg->nChannels;
    //        对子图像作处理部分      //
    cvReleaseImageHeader(&subimg);

    这样的处理让我一直找不到内存泄露的原因到底在哪儿。找了一个星期终于发现在图像头的释放上,解决办法就是:

    1. cvReleaseImage(&subimg);  
    cvReleaseImage(&subimg);

    先开始有点摸不着头脑,继续搜索关于图像头创建释放导致内存不足的问题,发现像遇到我这样的问题的人好像并不多,可能是我是新手的缘故。上面的解决办法我自己也不是很清楚,后来查查发现原来是这样:

    1,如果是从新创造一个IplImage,则用IplImage* cvCreateImage( CvSize size, int depth, int nChannels ),它创建头并分配数据。或者IplImage* cvCreateImageHeader创建图像头,并用指针为其分配图像数据时。

    注:当不再使用这个新图像时,要调用void cvReleaseImage( IplImage** image )将它的头和图像数据释放!

    2,如果有图像数据没有为图像头分配存储空间(即,没有为IplImage*指针分配动态存储空间),则先调用IplImage* cvCreateImageHeader( CvSize size, int depth, int nChannels )创建图像头,再调用void cvSetData( CvArr* arr, void* data, int step )指定图像数据,可以理解为将这个新图像的数据指针指向了一个已存在的图像数据上,不存在图像数据存储空间的分配操作。

    注:当不再使用这个新图像时,要调用void cvReleaseImageHeader( IplImage** image )将它的图像头释放!

    3,如果有图像数据也有图像头(用于IplImage为静态分配存储空间的情况),则先调用IplImage* cvInitImageHeader( CvSize size, int depth, int nChannels )更改图像头,再调用void cvSetData( CvArr* arr, void* data, int step )指定图像数据。

    注:因为这个新图像使用的是其它图像的数据和已有的图像头,所以不能使用cvReleaseImage将它的头和图像数据释放,也不能使用cvReleaseData将它的图像数据释放!

  • 相关阅读:
    SDUT 猴子分桃
    SDUT 母牛的故事
    SDUT 小鑫の日常系列故事(六)——奇遇记 递推算法
    SDUT 爬楼梯
    SDUT 王小二切饼
    linux 排序命令sort
    shell 判断语句
    shell统计指定范围内的所有质数以及它们的和
    shell 1到指定数累加
    shell九九乘法表
  • 原文地址:https://www.cnblogs.com/hualimengyu/p/3454183.html
Copyright © 2011-2022 走看看