From 999481273e1e703386fe557e75a4d9dddff4fa62 Mon Sep 17 00:00:00 2001 From: Maria Dimashova Date: Wed, 10 Aug 2011 07:02:50 +0000 Subject: [PATCH] fixed memory leak in SIFT wrapper (#1288) --- modules/features2d/src/sift.cpp | 81 ++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 32 deletions(-) diff --git a/modules/features2d/src/sift.cpp b/modules/features2d/src/sift.cpp index c0736409b..179097f63 100644 --- a/modules/features2d/src/sift.cpp +++ b/modules/features2d/src/sift.cpp @@ -1673,6 +1673,48 @@ void SIFT::operator()(const Mat& image, const Mat& mask, } } +void release_features_data( CvSeq* featuresSeq ) +{ + for( int i = 0; i < featuresSeq->total; i++ ) + { + feature * ft = CV_GET_SEQ_ELEM( feature, featuresSeq, i ); + free( ft->feature_data ); + } +} + +// Calculate orientation of features. +// Note: calc_feature_oris() duplicates the points with several dominant orientations. +// So if keypoints was detected by Sift feature detector then some points will be +// duplicated twice. +void recalculateAngles( vector& keypoints, IplImage*** gauss_pyr, + int nOctaves, int nOctaveLayers ) +{ + CvMemStorage* storage = cvCreateMemStorage( 0 ); + CvSeq* featuresSeq = cvCreateSeq( 0, sizeof(CvSeq), sizeof(struct feature), storage ); + + for( size_t i = 0; i < keypoints.size(); i++ ) + { + feature ft; + keyPointToFeature( keypoints[i], ft, SiftParams( nOctaves, nOctaveLayers ) ); + cvSeqPush( featuresSeq, &ft ); + } + + calc_feature_oris( featuresSeq, gauss_pyr ); + + keypoints.resize( featuresSeq->total ); + for( int i = 0; i < featuresSeq->total; i++ ) + { + feature * ft = CV_GET_SEQ_ELEM( feature, featuresSeq, i ); + keypoints[i] = featureToKeyPoint( *ft ); + } + + // Remove duplicated keypoints. + KeyPointsFilter::removeDuplicated( keypoints ); + + release_features_data( featuresSeq ); + cvReleaseMemStorage( &storage ); +} + // descriptors void SIFT::operator()(const Mat& image, const Mat& mask, vector& keypoints, @@ -1696,43 +1738,17 @@ void SIFT::operator()(const Mat& image, const Mat& mask, IplImage img = fimg; ImagePyrData pyrImages( &img, commParams.nOctaves, commParams.nOctaveLayers, SIFT_SIGMA, SIFT_IMG_DBL ); - // Calculate orientation of features. - // Note: calc_feature_oris() duplicates the points with several dominant orientations. - // So if keypoints was detected by Sift feature detector then some points will be - // duplicated twice. + if( descriptorParams.recalculateAngles ) + recalculateAngles( keypoints, pyrImages.gauss_pyr, commParams.nOctaves, commParams.nOctaveLayers ); + CvMemStorage* storage = cvCreateMemStorage( 0 ); CvSeq* featuresSeq = cvCreateSeq( 0, sizeof(CvSeq), sizeof(struct feature), storage ); - if( descriptorParams.recalculateAngles ) - { - for( size_t i = 0; i < keypoints.size(); i++ ) - { - feature* ft = (feature*) calloc( 1, sizeof( struct feature ) ); - keyPointToFeature( keypoints[i], *ft, SiftParams( commParams.nOctaves, commParams.nOctaveLayers ) ); - cvSeqPush( featuresSeq, ft ); - } - calc_feature_oris( featuresSeq, pyrImages.gauss_pyr ); - - keypoints.resize( featuresSeq->total ); - for( int i = 0; i < featuresSeq->total; i++ ) - { - feature * ft = CV_GET_SEQ_ELEM( feature, featuresSeq, i ); - keypoints[i] = featureToKeyPoint( *ft ); - } - - // Remove duplicated keypoints. - KeyPointsFilter::removeDuplicated( keypoints ); - - // Compute descriptors. - if( featuresSeq->total > 0 ) - cvSeqRemoveSlice( featuresSeq, cvSlice(0, featuresSeq->total) ); - } - for( size_t i = 0; i < keypoints.size(); i++ ) { - feature* ft = (feature*) calloc( 1, sizeof( struct feature ) ); - keyPointToFeature( keypoints[i], *ft, SiftParams( commParams.nOctaves, commParams.nOctaveLayers ) ); - cvSeqPush( featuresSeq, ft ); + feature ft; + keyPointToFeature( keypoints[i], ft, SiftParams( commParams.nOctaves, commParams.nOctaveLayers ) ); + cvSeqPush( featuresSeq, &ft ); } compute_descriptors( featuresSeq, pyrImages.gauss_pyr, SIFT_DESCR_WIDTH, SIFT_DESCR_HIST_BINS ); CV_DbgAssert( (int)keypoints.size() == featuresSeq->total ); @@ -1751,5 +1767,6 @@ void SIFT::operator()(const Mat& image, const Mat& mask, } } + release_features_data( featuresSeq ); cvReleaseMemStorage( &storage ); }