cascade classifier memory
Hello,
I have a simple stupid question :)
We're using a CascadeClassifier to load LBP models (I say we cause I don't code the core, but it impacts me ;)). We use the method detectMultiScale.
I made some tests to check charge, cpu & memory load, etc on our application, and I noticed something: let's imagine we have a lots of model (1000 or more :D)
I can load them and keep them in a list/vector whatever, memory's ok.
Then, with a sample image, for each classifier I call the detectMultiScale method : the memory grows up very very quickly . But if delete the classifier at each loop after using it, the memory stays ok.
So I was wondering, do the CascadeClassifier keeps data in his instance after detectMultiScale ? Well, it can be in our own code (ooh yes!), but as I don't find anything, I ask for the library too ...
Thanx a lot :)
If I understand correctly, loading in 1000 models a time will at detection time try to run multiple thousand of feature calculations which will all be stored in memory. The approach of loading and deleting seems reasonable to me.
You mean I should better delete my CascadeClassifier object after using it, and reload it if necessary ? (sorry if I musunderstand too)
My purpose was to keep my 1000 (well not so much - for example) CascadeClassifiers in memory in order to avoir to reload them each time I need them. So I was wondering if the detectMultiScale method was a method that "only" do calcultation and returns results, or if it keeps data into CascadeClassifier object (which would explain why my memory increases)
Smells like a bug, multiple calls to detectMultiScale shouldn't raise the memory in such a way, guess some cleanup is missing.
Maybe you can figure it out by using valgrind, please call your program with valgrind --show-reachable=yes ./your_program and options .
I had already tried with options --leak-check=full --track-origins=yes, cause i was first searching a memory leak in our codes. But valgrind returned no error.
I have done it again with the option you suggested --show-reachable=yes, with 360 models , the result is
LEAK SUMMARY definitely lost: 0 bytes in 0 blocks
indirectly lost: 0 bytes in 0 blocks
possibly lost: 0 bytes in 0 blocks
still reachable: 55,629 bytes in 978 blocks
suppressed: 0 bytes in 0 blocks
And the heap summary is : in use at exit: 55,629 bytes in 978 blocks
total heap usage: 289,714 allocs, 288,736 frees, 1,163,377,807 bytes allocated
(sorry for the formatting, I don't manage to make it fine)
I keep looking into my code to be sure
Once you load a model, it is stored in memory, however, I do not think this will take so much memory, since the models are rather small in size... However, if you are also storing your results of each model in memory, that could rase a problem. I suggest using valgrind like @Guanta said! It will give overview of your memory usage.
@drKzs: hmm, was that now a call with a single image? 55kb overhead seems not very much and I guess it may also be caused by another library (e.g. png library) (however I am not an expert here). If that was the call for a single image, try it with two images and see if valgrind tells you more here. Are you also really sure the overhead doesn't come from your program? E.g. due to the saving of the results (i.e. the rectangles, maybe you draw them in a copy of the image, or sth else).
Well, being sure would be very presumptuous :) What it is sure, is I don't use the Rect objects at the moment, I only count them ; they are stored in a container declared within a "myDetect" method, so the container is deleted at the end of the method, what I checked. It's not a container of reference, so logically I don't need to clean any objectts... Other thing sure, when I comment the call of detectMultiScale whithin myDetect, it's ok (of course there's no calculation, but was just to see). I can test with differents images, it's good idea.
I move the code out of my methods. It's not a beautiful code nor the most efficient, just a sample to show how I notice the problem (once again, I struggle with formatting, i maybe shouldnot post code in comment ?)
vector< cv::CascadeClassifier* > myModels ; for (int i=0 ; i < 1000 ; i++) { myModels.push_back( new cv::CascadeClassifier() ) ; if ( !myModels.back()->load(modelPath) ) { cerr << "ERROR when loading model" << endl ; exit(1) ; }
}
for (uint i=0 ; i< myModels.size() ; i++) { cv::Mat image = cv::imread(inputImagePath); std::vector<cv::Rect> objects; cv::Size size ; size.width = 0; size.height = 0; myModels[i]->detectMultiScale(image, objects, 1.1, 2, 0 | cv::CASCADE_SCALE_IMAGE, size); //delete(myModels[i]) ; //if uncommented, ok }
Maybe your for-loop logic is wrong (not enough code presented by you). You need the delete if the for-loop where you go through all the images is the most outer for-loop (above the creation of the models), if not (i.e. between the 2 for-loops you just wrote), then you don't need to delete it, hopefully more clearer: Either:
foreach image { foreach model { create model } foreach model { detect and delete model} }
foreach model { create model } foreach image { foreach model { detect } } foreach model { delete model }
The second variant is of course the most favorable one. Guess you have that? The cascadeClassifier shouldn't save any statistics during the pure detection-part.