cv :: La mémoire mat n’est pas libérée même après avoir appelé release ()?

J’ai écrit une méthode dans laquelle un descripteur d’image (comme OpenCV SIFT ou VLFeat Dense SI FT) calcule les descripteurs pour un ensemble d’images (enregistré dans les std::vector files ). Le descripteur est appelé via ComputeDescriptors(image, descriptorMasortingx) où il remplit descriptorMasortingx avec les descripteurs calculés à partir de.

Ensuite, je samples au hasard des descripteurs d’ samples (généralement 50) et pousse la masortingce sampledDescriptors dans les descripteurs std::vector descriptors .

C’est le code:

 void SIFTDescriptor::ComputeDescriptorsRange(const std::vector &files, std::vector &descriptors){ cv::Mat1f imgDescriptors; cv::Mat img; for(int i=0 ; i<files.size() ; i++){ std::cout<<"Describing "<<files[i]<0) ImgUtility::resize(img,resizeDim); ComputeDescriptors(img,imgDescriptors); if(samples > 0 && samples < imgDescriptors.rows){ std::cout<<"Sampling "<<imgDescriptors.rows<<" descriptors..."<<std::endl; cv::Mat1f sampledDescripotrs; std::vector v(imgDescriptors.rows); std::iota (std::begin(v), std::end(v), 0); //fill v with 0 ... imgDescriptors.rows std::random_device rd; std::mt19937 g(rd()); std::shuffle(v.begin(), v.end(), g); for(int j=0 ; j<samples; j++){ sampledDescripotrs.push_back(imgDescriptors.row(v[j])); } descriptors.push_back(sampledDescripotrs); sampledDescripotrs.release(); } else descriptors.push_back(imgDescriptors); //copy of a smart pointer, not expensive imgDescriptors.release(); std::cout<<"descriptors["<<i<<"]="<<descriptors[i].rows<<std::endl; std::cout<<descriptors[i]<<std::endl; } 

Cela permet d’optimiser la mémoire, en particulier pour les descripteurs denses tels que VLFeat Dense SIFT, où des milliers de descripteurs sont extraits. Avec des milliers d’images, nous manquerions de mémoire en un rien de temps. Au lieu de cela, avec cette solution, nous ne conservons que 50 descripteurs par image (ce qui est suffisant pour ma formation).

Cependant, pour des raisons étranges, OpenCV SIFT n’utilise pas beaucoup de mémoire, mais avec VLFeat Dense SIFT, la mémoire augmente rapidement, même si les samples sont égaux dans les deux cas!

Ma seule explication est que la mémoire utilisée par imgDescriptors à chaque boucle n’est pas libérée, même en utilisant imgDescriptors (ce qui ne devrait pas être nécessaire de toute façon puisque cv::Mat1f devrait être un peu un pointeur intelligent et donc se désallouer à la fin de la boucle), mais je ne comprends pas comment c’est possible.

Ceci est le code ComputeDescriptor pour une SIFT dense dans VLFeat:

 void DSIFTVLFeat::ComputeDescriptors(cv::Mat &img, cv::Mat1f &descriptors){ descriptors.release(); // transform image in cv::Mat to float vector cv::Mat imgFloat; img.convertTo(imgFloat, CV_32F, 1.0/255.0); if(!imgFloat.isContinuous()) throw std::runtime_error("imgFloat is not continous"); for(int i=binSize; i<=maxBinSize; i+=2){ VlDsiftFilter *dsift = vl_dsift_new_basic (img.rows, img.cols, step, i); vl_dsift_process (dsift, imgFloat.ptr()); cv::Mat scaleDescs(vl_dsift_get_keypoint_num(dsift), 128, CV_32F, (void*) vl_dsift_get_descriptors(dsift)); descriptors.push_back(scaleDescs); scaleDescs.release(); free(dsift); } } 

J’ai découvert par moi-même le problème: apparemment free(dsift) ne free(dsift) pas les descripteurs créés, alors je les empilais sur le tas sans les libérer.

L’appel de vl_sift_delete(dsift) semble avoir résolu le problème.