简体   繁体   English

OpenCV内存不足

[英]OpenCV insufficient memory

I am running the following code on Visual C++ 2008 and OpenCV 2.1. 我在Visual C ++ 2008和OpenCV 2.1上运行以下代码。 It works for a while (say 3 minutes) and then aborts with an error saying 它会工作一段时间(例如3分钟),然后中止并显示错误消息

"Insufficient Memory (Failed to allocate 92610 bytes) in unknown function, file ........\\ocv\\opencv\\src\\cxcore\\cxalloc.cpp, line 52" “未知函数中的内存不足(无法分配92610字节),文件......... \\ ocv \\ opencv \\ src \\ cxcore \\ cxalloc.cpp,第52行”

There must be some memory leak somewhere (probably with image creation) but I can't seem to get hold of it. 某处一定有内存泄漏(可能是图像创建),但是我似乎无法掌握它。

#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <iostream>
#include <math.h>

using namespace std;

void main()
{
    int i, j;
    int **arr = new int*[480], blob[6][8]={0};
    int max, maxi=-10, maxj=-10, div=80;
    int xmax=480, ymax=640;
    int frameH, frameW, fps, numFrames;
    double hue, sat, lum;
    int maxcolor, mincolor, maxcolval, mincolval;
    char key='a';
    CvScalar pix, destpix, destpix2, destpix3;
    IplImage *img, *dest, *hsv;

    for(i=0; i<480; i++)
        arr[i] = new int[640];

    CvCapture *capture = cvCaptureFromCAM(0);
    if(!capture)
    {
        cout<<"Cannot read video!!!!";
        exit(0);
    }

    frameH    = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
    frameW    = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
    fps       = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
    numFrames = (int) cvGetCaptureProperty(capture,  CV_CAP_PROP_FRAME_COUNT);
    printf("Width=%d Height=%d FPS=%d Count=%d\n", frameH, frameW, fps, numFrames);

    cvNamedWindow("win1", CV_WINDOW_AUTOSIZE);
    cvMoveWindow("win1", 10, 10);
    cvNamedWindow("win2", CV_WINDOW_AUTOSIZE);
    cvMoveWindow("win2", 600, 300);

    destpix.val[0]=0;
    destpix.val[1]=255;
    destpix.val[2]=0;
    destpix2.val[0]=0;
    destpix2.val[1]=0;
    destpix2.val[2]=0;
    destpix3.val[0]=255;
    destpix3.val[1]=255;
    destpix3.val[2]=255;

    while(key != 'q')
    {
        max=0;
        maxi=-10;
        maxj=-10;

        img = cvQueryFrame(capture);
        if(img == 0)break;

        dest = cvCloneImage(img);
        hsv = cvCloneImage(img);

        cvCvtColor(img, hsv, CV_BGR2HSV);

        for(i=0; i<xmax; i++)
            for(j=0; j<ymax; j++)
            {
                arr[i][j]=0;
                blob[i/div][j/div]=0;
            }           

        cout<<endl<<cvGet2D(hsv, 5, 5).val[0];
        //Looping through each pixel
        for(i=0; i<xmax; i++)
        {
            for(j=0; j<ymax; j++)
            {
                //Getting the current pixel (i, j)
                pix = cvGet2D(hsv, i, j);

                //Setting all pixels to black
                cvSet2D(dest, i, j, destpix2);

                hue = pix.val[0];
                sat = pix.val[1];
                lum = pix.val[2];

                //Looking for color red
                if((hue<5 || hue>177) && sat>120 && lum>60)
                {
                    arr[i][j] = 1;
                    cvSet2D(dest, i, j, destpix);
                }

                /*//Looking for color green
                if((hue>90 && hue<100) && sat>120 && lum>60)
                {
                    arr[i][j] = 1;
                    cvSet2D(dest, i, j, destpix);
                }*/

                /*//Looking for color blue
                if((hue>100 && hue<110) && sat>120 && lum>60)
                {
                    arr[i][j] = 1;
                    cvSet2D(dest, i, j, destpix);
                }*/

                /*//Looking for color yellow
                if((hue>30 && hue<40) && sat>120 && lum>60)
                {
                    arr[i][j] = 1;
                    cvSet2D(dest, i, j, destpix);
                }*/
            }   
        }

        //Counting the blobs in each grid
        for(i=0; i<xmax; i++)
        {
            for(j=0; j<ymax; j++)
            {
                if(arr[i][j])
                {
                    blob[i/div][j/div]++;
                }
            }
        }

        //Finding the grid with the largest blob
        for(i=0; i<xmax/div; i++)
            for(j=0; j<ymax/div; j++)
                if(blob[i][j]>max)
                {
                    max=blob[i][j];
                    maxi=i;
                    maxj=j;
                }

        if(max>200)
        {
            //Borders
            for(i=maxi*div; i<maxi*div+2; i++)
                for(j=maxj*div; j<maxj*div+div; j++)
                    cvSet2D(dest, i, j, destpix3);

            for(i=maxi*div+div-2; i<maxi*div+div; i++)
                for(j=maxj*div; j<maxj*div+div; j++)
                    cvSet2D(dest, i, j, destpix3);

            for(i=maxi*div; i<maxi*div+div; i++)
                for(j=maxj*div; j<maxj*div+2; j++)
                    cvSet2D(dest, i, j, destpix3);

            for(i=maxi*div; i<maxi*div+div; i++)
                for(j=maxj*div+div-2; j<maxj*div+div; j++)
                    cvSet2D(dest, i, j, destpix3);

            //Center
            for(i=maxi*div+(div/2)-5; i<maxi*div+(div/2)+5; i++)
                for(j=maxj*div+(div/2)-5; j<maxj*div+(div/2)+5; j++)
                    cvSet2D(dest, i, j, destpix3);
        }

        //Creating Windows
        //cvCvtColor(fin, dest, CV_HSV2BGR);
        key = cvWaitKey(20);
        cvShowImage("win1", dest);
        cvShowImage("win2", img);
    }

    cvWaitKey(0);
    cvReleaseCapture(&capture);
    cvReleaseImage(&dest);
    cvDestroyWindow("win1");
    cvDestroyWindow("win2");
}

"Insufficient memory" really means "There was an error when I tried to allocate memory". “内存不足”实际上意味着“尝试分配内存时出现错误”。

It's quite likely that you've actually corrupted something somewhere, rather than actually run out of memory, particularly with this style of code. 您很有可能实际上已经损坏了某处的某些内容,而不是实际上耗尽了内存,尤其是使用这种类型的代码时。

The documentation of CloneImage says: CloneImage的文档说:

Makes a full copy of image 制作图像的完整副本

IplImage* cvCloneImage( const IplImage* image ); IplImage * cvCloneImage(const IplImage * image);

image Original image. 图像原始图像。

The function cvCloneImage makes a full copy of the image including header, ROI and data 函数cvCloneImage制作图像的完整副本,包括标题,ROI和数据

You are creating a deep copy at every loop and save it using the same pointer. 您将在每个循环中创建一个深层副本,并使用相同的指针进行保存。 Every loop you loose track of the previos allocation without free the memory. 每个循环都会释放previos分配的内存,而不会释放内存。

EDIT 编辑

This function may help you: 此功能可以帮助您:

ReleaseImage 发行图片

Releases header and image data 释放标题和图像数据

void cvReleaseImage( IplImage** image ); void cvReleaseImage(IplImage ** image);

image Double pointer to the header of the deallocated image. image双重指针,指向已释放图像的标题。

The function cvReleaseImage releases the header and the image data. 函数cvReleaseImage释放标题和图像数据。 This call is a shortened form of 此呼叫是的缩写形式

 if( *image ) { cvReleaseData( *image ); cvReleaseImageHeader( image ); } 

Try to release the memory at the end of your while loop. 尝试在while循环结束时释放内存。

Old post, but surely this problem gave me a headache recently... 旧帖子,但是肯定这个问题最近让我头疼...

I totally had the same problem, I was just working with plain drawing functions. 我完全有同样的问题,我只是在使用普通绘图功能。 You here basically want to copy an image in every iteration. 您在这里基本上是想在每次迭代中复制一个图像。 Current situation is: 当前情况是:

dest = cvCloneImage(img) will allocate memory, clone the whole image into it and return the pointer to this new memory, THUS you will lose the pointer value dest had previously. dest = cvCloneImage(img)将分配内存,将整个图像克隆到其中,然后将指针返回到该新内存,这样您将丢失dest之前的指针值。 So, if you hadn't already released the memory with cvReleaseImage(img) by then, you'll have a memory leak. 因此,如果那时您还没有使用cvReleaseImage(img)释放内存,则会发生内存泄漏。

There has to be an easier way, and there really is: 必须有一种更简单的方法,实际上是:

    /* Copies source array to destination array */
    CVAPI(void)  cvCopy( const CvArr* src, CvArr* dst,
                         const CvArr* mask CV_DEFAULT(NULL) );

So you just need to use cvCopy(img, dest); 所以你只需要使用cvCopy(img, dest); What was in dest will be overwritten => no memory leak 目标中的内容将被覆盖=>没有内存泄漏

IplImage *img, *dest, *hsv; IplImage * img,* dest,* hsv;

Check the documentation and see if you are responsible for freeing the above pointers, before assigning them to new values. 在将它们分配给新值之前,请查看文档并查看是否有责任释放上述指针。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM