OpenCV mixing IplImage with cv :: Mat

I came across some ambiguity in memory management with opencv. You can do this with the new opencv C ++ classes:

cv::Mat theimage = cvLoadImage("rawimage.pgm",CV_LOAD_IMAGE_ANYDEPTH); 

now what i don't understand, if i do the following i will get the error:

 theimage.deallocate(); 

Perhaps this is wrong. I did some experimentation, and when I released the Mat object:

 theimage.release(); 

the IplImage object is still in memory. Is there a way to tell the cv :: Mat object to destroy the IplImage object, or is my first line of code incorrect (since I lost a pointer to the IplImage object there)? I have seen many examples on the Internet where people use the first line of code. Many explain how to convert, but no one explains what happens to memory!

The problem is that I have many classes that use the IplImage object (I started using this project). And I understand why cv :: Mat is better than IplImage.

- EDIT -

On the Internet, I found the following mixing solution:

 cv::Ptr<IplImage> tmp = cvLoadImage("rawimage.pgm",CV_LOAD_IMAGE_ANYDEPTH); cv::Mat theimage(tmp); 

I think this may solve some of my problems, but it makes my code a bit unreadable and, in my opinion, dangerous. If tmp is freed up to cv :: Mat, I will use some damaged objects (I have not tested this, but I think it is). A simple way would be to use a copy:

 cv::Mat theimage(tmp,true); 

this is the only solution i found but for me it is wrong ...

+1
source share
1 answer

The ambiguity comes from extreme horrible practice : mixing the C interface with the C ++ OpenCV interface. Do not do this, use cv::imread() instead.

The cv::Mat destructor will always free memory if necessary , except when it is initialized from IplImage , then for you to free resources using deallocate() . I wrote a simple experiment to check this information:

 void load() { cv::Mat img = cvLoadImage("out.png", 1); std::cout << "* IMG was loaded\n"; getchar(); img.deallocate(); } int main() { load(); std::cout << "* IMG was deallocated\n"; getchar(); return 0; } 

A call to getchar() pauses the program, so you can check the amount of application memory. If you comment out deallocate() , you will notice that after loading the image, the amount of memory does not decrease.

On the note side, Mat::release() only decreases the reference counter and frees the data if necessary (but it also does not get freed if Mat was initialized from IplImage ).

+3
source

All Articles