Just value your mind

OpenCV memory leaking management in C/C++

If you’re new to OpenCV, you need to know exactly how to manage all the huge amounts of memory you’re using. C/C++ isn’t a garbage collected language (like Java), so you need to manually release memory as soon as its use is over. If you don’t, your program could use up hundreds of MBs of highly valuable RAM… and often even crash (out-of-memory errors?)

It can be a daunting task to hunt exactly where memory needs to be released. So I’ve compiled this short list of places where you should look out for memory leaks.

Create it, then Release it

If you create something, make sure you release it before “returning”. This is probably the very first thing you should check when fixing memory leak problems with OpenCV. For example, if you do a cvCreateImage, make sure you do a cvReleaseImage. There are many things you can create. Here are some functions that “create” and their corresponding “release” functions

cvCreateImage cvReleaseImage
cvCreateImageHeader cvReleaseImageHeader
cvCreateMat cvReleaseMat
cvCreateMatND cvReleaseMatND
cvCreateData cvReleaseData
cvCreateSparseMat cvReleaseSparseMat
cvCreateMemStorage cvReleaseMemStorage
cvCreateGraphScanner cvReleaseGraphScanner
cvOpenFileStorage cvReleaseFileStorage
cvAlloc cvFree



One warning though: If you create something and want to return it, don’t release it. Lets say a function that creates a checkerboard image and returns it. If you release the image before returning it, you’re freeing all memory that stores the image data. And when you try accessing memory that isn’t yours, you get a crash.

Release returned structures

This is the second thing you should check for. Often, once you return a structure (say, an image).. you forget about it.

Multiple Memory Allocations

This is the third thing you should check for: Allocating memory, and then changing the pointer itself. Here’s some example code:

IplImage* image = cvCreateImage(whatever);
image = CreateCheckerBoard(whatever);

cvReleaseImage(&image);

This function creates a memory leak. First, you allocate some memory for image. Then, you call the function CreateCheckerBoard. This function itself creates new memory. And image now points to this new memory. The memory created in the first step is lost forever. No variable points to it. A memory leak. To fix this, you need to modify the code like this:

IplImage* image = NULL;
image = CreateCheckerBoard(whatever);

cvReleaseImage(&image);

If you return a sequence, release its storage

There are many instances where you use the CvSeq data structure. And often you might want to return this structure for further use. If you release its storage (a CvMemStorage structure) within the function itself, you’d free the memory where the sequence is stored. And then you’d try and access it in the calling function. Again, crash.

A temporary fix would be to just erasing the cvReleaseMemStorage statement… but that would mean lots of memory.
To fix this, you don’t release the memory in the function itself. You release it in the calling function like this:

cvReleaseMemStorage(&thesequence->storage);

storage is a member of the CvMemStorage structure that always points to the memory where its stored.

Again, this is just an example. There are more structures where a similar situation could arise.

Dependence on other structures

I quite recently discovered this memory leak. To explain this, I’ll use an example: Lets say you find out the contours of an image. OpenCV would return a “linked list” type structure calledCvSeq. You decide to access the third element of this linked list. OpenCV returns a pointer to the third element. All going great till this moment.

Now you decide to save all the points of this contour (the third element) in a data structure of your own. Since this is an array of points, you do something like:

mystructure->points = thirdcontour->points;

You set the pointer to equal to the thirdcontour. This is the bug. If you release the storage of the sequence (which you should), mystructure has a bad pointer. To fix this, allocate new memory to mystructure->points and then copy contents ofthirdcontour->points… something like this:

mystructure->points = (CvPoint*)malloc(sizeof(CvPoint) * thirdcontour->total);
memcpy(mystructure->points,thirdcontour->points,sizeof(CvPoint)*thirdcontour->total);

This creates new memory for your structure and then copies each element there. Once you’ve done this, you can release the storage of the sequence without fear.

 

[Original source from: LiquidMetal, all rights reserved by original authors]
[Post updated at 09/03/2011] The original post has been updated here http://www.aishack.in/2010/01/opencv-memory-management/





QR code for this post, SCAN ME
QR:  OpenCV memory leaking management in C/C++

Posts may be of your interests

52 Comments On “ OpenCV memory leaking management in C/C++”

  1. [...] OpenCV memory leaking management in C/C++ [...]

  2. Utkarsh says:

    hi there! Glad I was of some help :)
    Sorry wasn’t able to respond for a long time… my computer isn’t functioning… so haven’t been able to update/access my blog for a long long time.

  3. Utkarsh says:

    :) about the permission, no problems with that.. you put up a link to the original article!

  4. Hi, good post. I have been wondering about this issue,so thanks for posting. I’ll certainly be subscribing to your site.

  5. [...] อ่านรายละเอียดทั้งหมดได้ที่: OpenCV memory leaking management in C/C++ [...]

  6. Risal Nasar says:

    Thanks a lot for the help… !!!
    I was facing memory leak problems.

    ———
    IplImage *frame1, *frame2;
    frame1 = cvQueryFrame(capture);
    frame2 = cvQueryFrame(capture);

    frame1 = frame2; // Memory leak
    ———–
    Before changing the pointer frame1 to be equal to pointer frame2, do this :
    cvReleaseImage(&frame1);

  7. Risal Nasar says:

    The above method does’nt seems to work, Andol. It says frame cannot be released untill capture is released. How do I tackle this problem.

    • Andol says:

      ———
      IplImage *frame1, *frame2;
      frame1 = cvQueryFrame(capture);
      frame2 = cvQueryFrame(capture);
      //———————–
      frame1 = NULL;
      //———————–
      frame1 = frame2; // Memory leak
      ———–

    • Andol says:

      and, cvReleaseImage() is not necessary here.

      • Risal Nasar says:

        cvReleaseImage(&frame1) resulted in error since frame1 was referring to a part of the video capture named “capture”.
        ————————————
        The right example should be:
        ————————————
        IplImage *tpl1 = NULL;
        IplImage *tpl2 = NULL;

        tpl1 = cvCreateImage( cvSize( tpl_width, tpl_height ),frame->depth, frame->nChannels );

        tpl2 = cvCreateImage( cvSize( tpl_width, tpl_height ),frame->depth, frame->nChannels );

        tpl1 = tpl2; // Memory leak
        —————-
        Before changing the pointer tpl1 to be equal to pointer tpl2, do this :
        —————-
        if(tpl1 != NULL){
        cvReleaseImage(&tpl1);
        }
        tpl1 = tpl2; // No memory leak

  8. mohan says:

    hi ,
    #include
    #include “cv.h”
    #include “highgui.h”
    int main( int argc, char **argv )
    { CvCapture *capture = 0;
    IplImage *frame = 0;
    int key = 0;
    capture = cvCaptureFromCAM( 0 );
    //capture=cvCaptureFromCAM(-1);
    //capture=cvCreateCameraCapture(0);
    if ( !capture )
    { fprintf( stderr, “Cannot open initialize webcam!\n” );
    return 1;
    }
    cvNamedWindow( “result”, CV_WINDOW_AUTOSIZE );
    while( key != ‘q’ )
    {
    frame = cvQueryFrame( capture );
    if( !frame ) break;
    cvShowImage( “result”, frame );
    key = cvWaitKey( 1 );
    }
    cvDestroyWindow( “result” );
    cvReleaseCapture( &capture );

    return 0;
    }

    while i run the above program i got the black screen in window in my laptop(windows 7),
    but i run the same program in windows vista the video can be display,,,
    why the video did not display in windows7,,,

    plz help me,,, i am waiting for your reply,,,

    • Andol says:

      well Mohan, i have to say that probably you should check the system variables first, to make sure settings are all right, obviously the program is ok.

  9. mohan says:

    hi..
    i saw that the system variables are correct already but i got the black screen again.. please help me in this..
    Thanks for your reply.

    • Andol says:

      Trying some examples in openCV’s esample folder, if the black screen continues, then probably the problem is in operation system,system sdk,display drivers or openCV installation.

  10. aibo says:

    Black Screen Problem!!!

    Hi all, im using the java wrapper for openCV under windows. I have successfully installed openCV v1.0 (i tested the newest versions and they dont work properly), i have set the variable system Path properly pointing to the “bin” directory of my openCV installation software, i have also pasted the openCV.dll into the bin directory, i have placed properly the “hypermedia” and “processing” folders to the appropriate locations, i have attached all the appropriate jar files needed by openCV, i have tested all these in XP and Vista..

    Despite all these steps i did, all the examples provided by the openCV for the java version (face detection, BlobDetection, Aplets, etc) work properly without linking or runtime exceptions BUT I HAVE BLACK SCREEN TO ALL OF THEM!!!

    What should i do more???
    Even the face detection works, i see the bounding box tracking the movement of my head but i dont have image, just blank background colour.

    Any suggestions? Please Help..

  11. Mohan says:

    hi Andol,,, i got the solution,,
    i installed OpenCV_1.1pre1a ,,, working properly in windows 7 64bit,,,

  12. dnul says:

    Dude, this is great you really helped me.

  13. Neithan says:

    I’m having problems using a Visual Studio Solution over Windows Vista for a Hough Line detection

    This is may code:

    IplImage* src = cvLoadImage(“C:\\Draw.jpg”,0);
    CvMemStorage* storage = cvCreateMemStorage( 0);

    CvSeq* lines = 0;
    lines = cvHoughLines2( src, storage, CV_HOUGH_PROBABILISTIC, 1,CV_PI/180, 20, 30, 5);

    for(int i = 0; i total; i++ )
    {
    CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i);
    // Here I use the point information
    }

    cvReleaseImage( &src);
    cvReleaseMemStorage( &storage); // Here is the bug

    • Andol says:

      @ Neithan check out this:
      /* This is a standalone program. Pass an image name as a first parameter of the program.
      Switch between standard and probabilistic Hough transform by changing “#if 1″ to “#if 0″ and back */
      #include
      #include
      #include

      int main(int argc, char** argv)
      {
      const char* filename = argc >= 2 ? argv[1] : “pic1.png”;
      IplImage* src = cvLoadImage( filename, 0 );
      IplImage* dst;
      IplImage* color_dst;
      CvMemStorage* storage = cvCreateMemStorage(0);
      CvSeq* lines = 0;
      int i;

      if( !src )
      return -1;

      dst = cvCreateImage( cvGetSize(src), 8, 1 );
      color_dst = cvCreateImage( cvGetSize(src), 8, 3 );

      cvCanny( src, dst, 50, 200, 3 );
      cvCvtColor( dst, color_dst, CV_GRAY2BGR );
      #if 0
      lines = cvHoughLines2( dst, storage, CV_HOUGH_STANDARD, 1, CV_PI/180, 100, 0, 0 );

      for( i = 0; i < MIN(lines->total,100); i++ )
      {
      float* line = (float*)cvGetSeqElem(lines,i);
      float rho = line[0];
      float theta = line[1];
      CvPoint pt1, pt2;
      double a = cos(theta), b = sin(theta);
      double x0 = a*rho, y0 = b*rho;
      pt1.x = cvRound(x0 + 1000*(-b));
      pt1.y = cvRound(y0 + 1000*(a));
      pt2.x = cvRound(x0 – 1000*(-b));
      pt2.y = cvRound(y0 – 1000*(a));
      cvLine( color_dst, pt1, pt2, CV_RGB(255,0,0), 3, CV_AA, 0 );
      }
      #else
      lines = cvHoughLines2( dst, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI/180, 50, 50, 10 );
      for( i = 0; i < lines->total; i++ )
      {
      CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i);
      cvLine( color_dst, line[0], line[1], CV_RGB(255,0,0), 3, CV_AA, 0 );
      }
      #endif
      cvNamedWindow( “Source”, 1 );
      cvShowImage( “Source”, src );

      cvNamedWindow( “Hough”, 1 );
      cvShowImage( “Hough”, color_dst );

      cvWaitKey(0);

      return 0;
      }

      • Neithan says:

        The problem of your code is that you are not releasing memory and if you want to process an array of N (N is a huge number) the memory fails … :(

        but thank you anyway

    • Andol says:

      @Neithan To release the memory of ‘storage’, it is also available to define it once, and then use ‘storage = NULL’ to clean it before using it.

      • Neithan says:

        Memory is not being released with using storage = NULL … the problem is that I have to create and release a storage more than 1000 times, and between the creation and the release I use the Hough Detection method that lacks the storage.

        Thank You again

    • Andol says:

      @Neithan check new codes below, which have been running properly without memory leaking, by using ‘cvReleaseMemStorage()’. a better way of using ‘memstorage’ is to define it before and outside cycles and release it after cycles. cheers

      int main()
      {
      int c = 0;
      int i = 0;
      CvCapture* capture = cvCaptureFromCAM(0);
      if(!cvQueryFrame(capture)){ cout< <"Video capture failed, please check the camera."< CvSize sz = cvGetSize(cvQueryFrame( capture));
      cout << "capture size: " << sz.width < IplImage* src = cvCreateImage( sz, 8, 3 );
      IplImage* gray = cvCreateImage(sz,8,1);
      cvCvtColor(src,gray,CV_BGR2GRAY);
      cvNamedWindow("info",1);

      CvMemStorage* myStorage = cvCreateMemStorage(0);
      CvSeq* lines = 0;

      while (c!=27)
      {
      lines = cvHoughLines2(gray,myStorage,CV_HOUGH_STANDARD,1,CV_PI/180,100,0,0);
      cout<< " lines total" << lines->total;
      for(i=0; i total; i++)
      {
      float* line = (float*)cvGetSeqElem(lines,i);
      float rho = line[0];
      float theta = line[1];
      CvPoint pt1, pt2;
      double a = cos(theta), b = sin(theta);
      double x0 = a*rho, y0 = b*rho;
      pt1.x = cvRound(x0 + 1000*(-b));
      pt1.y = cvRound(y0 + 1000*(a));
      pt2.x = cvRound(x0 – 1000*(-b));
      pt2.y = cvRound(y0 – 1000*(a));
      cvLine( src, pt1, pt2, CV_RGB(255,0,0), 3, CV_AA, 0 );
      }

      src = cvQueryFrame(capture);
      cvShowImage(“info”,src);
      c = cvWaitKey(10);
      }
      cvReleaseImage(&src);
      cvReleaseMemStorage(&myStorage);
      cvReleaseCapture(&capture);
      cvDestroyAllWindows();
      }

      • Neithan says:

        The same code is not working for different versions of OpenCv (1.0 and 2.0)… so I moved to the old version again (1.0) and now I’m not having problems.

        Thank you all for your help

  14. [...] jest, aby pamiętać o czyszczeniu pamięci. Bardzo dobrą stroną dotyczącą tego tematu jest: http://www.andol.info/hci/963.htm, a w wielkim [...]

  15. Nice post and this mail helped me alot in my college assignement. Thank you seeking your information.

  16. Enzo says:

    Just about everyone encounters memory/recources problems when using OpenCV, it’s just a result of using raw pointers.

    I have created an object oriented image structure to wrap IplImage with shared_ptr.

    It is very fast, easy to use and makes code infinitely easier to read.

    The structure is called blImage and is part of my blImageAPI, which can be found at: http://www.barbato.us/2010/10/14/image-data-structure-based-shared_ptr-iplimage/

    This makes IplImage so easy to use, you can do the following:

    int main(int argc, char *argv[])
    {
    // Create a blank 8-bit color image
    blImage< blColor3 > MyImage;

    // Load an image from file
    MyImage.LoadImageFromFile(“C:\\tux.png”);

    // Create a floating point grayscale
    // version of our colored image
    blImage MyImage2 = MyImage;

    // We can easily access pixel data very efficiently
    for(int i = 0; i < MyImage2.size1(); ++i)
    for(int j = 0; j < MyImage2.size2(); ++j)
    MyImage2[i][j] += 100;

    blImage MyImage3 = MyImage2;

    // Let’s take the first derivative in both directions
    cvSobel(MyImage2,MyImage2,1,1);

    cvNamedWindow(“tux”,CV_WINDOW_AUTOSIZE);
    cvShowImage(“tux”,MyImage3);
    cvWaitKey(0);
    return 0;
    }

    Good luck and enjoy

  17. Utkarsh says:

    Hi! Can you update the link to the original article on this post? I’ve moved it here – http://www.aishack.in/2010/01/opencv-memory-management

    Thanks!

  18. sethu says:

    Hi Andol,
    I would like to how to track the detected features using Kalman filter.
    Right now, I detected some features like vehicles, headlights. I need to track them using kalman filter.

  19. Great article, i was searching for something like this !

    Adding to what you wrote, there are some not so linear cases like

    classifier = (CvHaarClassifierCascade*) cvLoad(classifier_file, 0, 0, 0);

    cvReleaseHaarClassifierCascade(&classifier);

    One of the most easiest things in OpenCV is having memory leaks…

Leave a comment

You can use these XHTML tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Copyrights 2006-2014 © Andol Li | Theme Tree2, re-designed by Andol Li| Powered by WordPress
WWW.ANDOL.INFO- 91 queries in 1.540 seconds. Go to TOP