Memory leak problem using CvExtractSURF


I want to extract SURF points and create an XML with the information from a series of keyframes of a video.

This is the function that does the work:

void xVideo::extractSURFDescriptor(int f1){  
	ofxXmlSettings *surfXML = new ofxXmlSettings();  
	imageKeypoints = 0;  
	imageDescriptors = 0;  
	surfXML->addTag( "SURF" );  
	surfXML->pushTag( "SURF" , 0 );  
	ofxCvColorImage *image = new ofxCvColorImage();  
	image->allocate( getWidth(), getHeight() );  
	image->setFromPixels( getPixels(), getWidth(), getHeight() );  
	ofxCvGrayscaleImage *imageGray = new ofxCvGrayscaleImage();  
	imageGray->allocate( image->getWidth(), image->getHeight() );  
	imageGray->setFromColorImage( *image );  
	cvExtractSURF( imageGray->getCvImage(), 0, &imageKeypoints, &imageDescriptors, storage, params );	  
	CvSeqReader reader, kreader;  
	cvStartReadSeq( imageKeypoints, &kreader );  
	cvStartReadSeq( imageDescriptors, &reader );  
	int len = (int) ( imageDescriptors->elem_size/sizeof(float) );  
	for( int i = 0; i < imageDescriptors->total ; i++ ){  
		const CvSURFPoint* kp = (const CvSURFPoint*)kreader.ptr;  
		surfXML->addTag( "INFO" );  
		surfXML->pushTag( "INFO" , i );  
		surfXML->addValue( "X", kp->pt.x );  
		surfXML->addValue( "Y", kp->pt.y );  
		surfXML->addValue( "LAPLACIAN" , kp->laplacian );  
		const float* descriptor = (const float*)reader.ptr;  
		for (int d = 0 ; d < len ; d++) {  
			surfXML->addValue( "V", descriptor[d] );  
		CV_NEXT_SEQ_ELEM( kreader.seq->elem_size, kreader );  
		CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader );  
	surfXML->saveFile( title + "/xml/surf/s" + ofToString( f1 ) + ".xml" );  
	cvClearMemStorage( storage );  

I have storage and params initialize on the class constructor

	storage = cvCreateMemStorage( 0 );	  
	params = cvSURFParams( 500, 1 );  

and on the .h of the class

        CvMemStorage* storage;  
	CvSURFParams params;   
	CvSeq *imageKeypoints, *imageDescriptors;  

When the program enters this function he isn’t cleaning memory, I call the clear for image, imageGray and surfXML and do the cvClearMemStorage for the storage.

Can anyone help me?

thank you

cvclearmemstorage doesn’t release any memory it just deletes the contents of the mem storage, from opencv docs:

The function resets the top (free space boundary) of the storage to the very beginning. This function does not deallocate any memory. If the storage has a parent, the function returns all blocks to the parent.

what you want is cvReleaseMemStorage

The problem continues, i substitute

cvClearMemStorage( storage );  


cvReleaseMemStorage( &storage );  

and added

storage = cvCreateMemStorage( 0 );	  

to the beginning to the function and memory keeps increasing.

oh yes, the clear can be ok if you’re allocating in the constructor and using that memory after that.


imageGray = new ofxCvGrayscaleImage()  


ofxXmlSettings *surfXML = new ofxXmlSettings();  

though, is done every time so you need to delete it at the end:

delete imageGray;  
delete surfXML  

or even better, if you know the size of the image size at the beginning, you can just declare imageGray as a variable in the .h and allocate it at the beginning. the same goes for surfXML. it will be even faster since you don’t need to initialize the instances every time.

i thought the


would do release. I have put the delete on both images and the xml file and memory still grows :slight_smile:

hi~ glad to see discussion about surf here. i also find the memory leak problem with this method. i doubt it’s because imageKeypoints and imageDescriptors? because each cycle there are:
imageKeypoints = 0
imageDescriptors = 0
so maybe these memories are not released

it’s not enough to call clear() on the images. for every call to new, you need a matching delete:

ofImage* imageGrey = new ofImage();

delete imageGrey;

Hi UnZynpernet,

Finally you could fix the problem with memory. I am in the same case and not know where to shoot.



// create memory
imaStorage = cvCreateMemStorage(0);

//exec SURF
cvExtractSURF( oCVgrayImg.getCvImage(), 0, &imageKeypoints, &imageDescriptors, imaStorage, params);

//find homograpy
imaEncontrados = locatePlanarObject( objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, src_corners, dst_corners );

//delete an reset memory

And the memory dont grow… :slight_smile: