Reputation: 121
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
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
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