从网络摄像头对视频进行图像处理操作时出现java.lang.OutOfMemory错误

时间:2014-01-21 09:02:13

标签: java memory-leaks out-of-memory javacv

我正在开发一个应用程序来执行一些图像处理,以检测从网络摄像头捕获的图像中的道路标志。 该程序运行良好2到3分钟,之后由于内存不足而崩溃。 我无法检索已经使用过的空间。

下面的代码段显示了我是如何释放空间的

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


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

mem是cvMemStorage,等高线是cvSeq,所有其他变量是IplImage。它们中的每一个都是一个全局变量,并且由不同的方法使用。

以下是使用不同变量的两种方法

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;


}

变量是在类

的构造函数中创建的
public detectSign() {
    mem=CvMemStorage.create();
    contours=new CvSeq();
    ptr=new CvSeq();
    originalImage=new IplImage();   
}

我正在使用javacv进行图像处理。

2 个答案:

答案 0 :(得分:2)

如何释放CV资源有多种方式,这取决于它是什么以及如何创建它。

我认为对于IplImage个实例,您应该拨打cvReleaseImage(image);而不是.deallocateReferences();

<强>更新: 而且,cvClear..()方法不会释放内存。您必须使用cvRelease..()方法。这可能是你的主要问题。

解决这两个问题,然后重试。

答案 1 :(得分:-1)

除了您正在调用一堆方法之外,您的代码段不会显示任何内容。

分析您的应用程序并查看正在使用内存的内容,这可能有助于您识别内存泄漏。