adarsh
adarsh

Reputation: 121

java.lang.OutOfMemory error when doing image processing operation on video from webcam

I'm developing an application that does some image processing to detect road signs from images captured from the webcam. The program runs nicely for 2 to 3 minutes, after which it crashes due to lack of memory. I'm not able to retrieve the space that have already been used.

The codes snippet below shows how I'm trying to free the space

public void clearVariables() {
    cvClearMemStorage(mem);
    cvClearSeq(contours);
    cvClearSeq(ptr);


    originalImage.deallocateReferences();
    intensityChannel.deallocateReferences();
    eliminationImage.deallocateReferences();
    contourImg.deallocateReferences();
}

mem is cvMemStorage, contours is a cvSeq and all the other variable are IplImage. Each of them is a global variable and the are used by different methods.

Here are two methods that use different variables

public IplImage findContours(IplImage eliminationImage) {

    contourImg=cvCreateImage(originalImage.cvSize(),originalImage.depth(),originalImage.nChannels());
    contourImg=originalImage.clone();

    cvClearMemStorage(mem);

    cvClearSeq(contours);

    cvFindContours(eliminationImage, mem, contours, Loader.sizeof(CvContour.class) , CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0));

    int areaImage=originalImage.height()*originalImage.width();

    do {
        ptr=cvApproxPoly(contours, Loader.sizeof(CvContour.class), mem, CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.02, 0);

        CvRect bRect=cvBoundingRect(contours,0);

        int x=bRect.x();
        int y=bRect.y();
        int h=bRect.height();
        int w=bRect.width();         

        int areaRect=bRect.height()*bRect.width();
        double ratio=(double)w/h;


        if ((areaImage / 1500 > areaRect) || (ratio < 1.3) || (ratio > 0.25)) {
            cvRectangle(contourImg, cvPoint(x, y), cvPoint(x+w, y+h), CvScalar.RED, 1, CV_AA, 0);
        }
        ///check size end

        if (contours.h_next()==null){break;}
        contours=contours.h_next();

    }
    while(!contours.isNull());

    cvClearSeq(ptr);
    cvClearMemStorage(mem);
    return contourImg;

}



public IplImage elimination(IplImage thresholdImage)
{

    eliminationImage=cvCreateImage(originalImageSize,originalImageDepth,1);
    long areaImage=originalImage.height()*originalImage.width();

    cvClearMemStorage(mem); 

    cvClearSeq(contours);

    cvFindContours(thresholdImage, mem, contours, Loader.sizeof(CvContour.class) , CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);

     while(!contours.isNull() && contours!=null){


         CvRect bRect=cvBoundingRect(contours,0);


         int x=bRect.x();
         int y=bRect.y();
         int h=bRect.height();
         int w=bRect.width();

         int areaRect=bRect.height()*bRect.width();
         double ratio=(double)w/h;

         if((areaRect<(areaImage/1500))||(ratio>1.3)||(ratio<0.25))

         {
           //if too small

         }
         else
         {


             CvSeq points = cvApproxPoly( contours, Loader.sizeof( CvContour.class ), mem, CV_POLY_APPROX_DP, cvContourPerimeter( contours ) * 0.02, 0 );
             cvDrawContours(eliminationImage, points, CvScalar.WHITE, CvScalar.WHITE, 0, 8, CV_FILLED);
             cvClearSeq(points);

         }

        if(contours.h_next()==null){break;}
         contours=contours.h_next();

     }

    cvClearMemStorage(mem);
    cvClearSeq(contours);
    return eliminationImage;


}

the variables are created in the constructor of the class

public detectSign() {
    mem=CvMemStorage.create();
    contours=new CvSeq();
    ptr=new CvSeq();
    originalImage=new IplImage();   
}

I'm using javacv for the image processing.

Upvotes: 1

Views: 186

Answers (2)

Daniel S.
Daniel S.

Reputation: 6650

There are different ways how to release CV resources, which depend on what it is and how it was created.

I think that for the IplImage instances, you should call cvReleaseImage(image); instead of .deallocateReferences();.

UPDATE: Moreover, the cvClear..() methods do not deallocate memory. You have to use the cvRelease..() methods instead. This might be your main problem.

Fix these two problems and try again.

Upvotes: 2

Kayaman
Kayaman

Reputation: 73568

Your code snippet doesn't show anything, except that you're calling a bunch of methods.

Profile your application and see what's using the memory, that might help you identify the memory leaks.

Upvotes: -1

Related Questions