openCV mixing IplImage with cv::Mat

2019-02-15 21:50发布

问题:

I have experienced some memory managment ambiguitys with opencv. You could 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 an error:

theimage.deallocate();

maybe this is wrong. I have made some experiments and when I release the Mat object:

theimage.release();

the IplImage object still remains in the memory. Is there some way to say to the cv::Mat object destroy the IplImage object or is my first line of code wrong (since there I have lost the pointer for the IplImage object) ? I have seen a lot of exemples in the internet where people use the first line of code. Many explains how to convert but no one explains what happens with the memory !

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

--EDIT--

In the internet I have found following solution for the mixing:

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

I think this could solve some of my problems but makes my code a bit unreadable and is in my opinion stil dangerous. If tmp gets deallocated before cv::Mat I will use some corrupt objects (I didn t test that but I think it is so). The easy way would be to use a copy:

cv::Mat theimage(tmp,true);

this is the only solution that I found but for me it feels wrong...

回答1:

The ambiguity comes from an extremelly horrible practice: mixing the C interface with the C++ interface of OpenCV. Don't do it, use cv::imread() instead.

The destructor of cv::Mat will always deallocate memory when needed, except when it is initialized from a IplImage, then it's up to you to free it's resources with deallocate(). I wrote a simple experiment to verify 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;
}

The getchar() calls pause the program so you can check the memory footprint of the application. If you comment out deallocate() you'll notice that the memory footprint doesn't decrease after loading the image.

On a side note, Mat::release() only decreases the reference counter and deallocates the data if needed (but it will also not deallocate in case the Mat was initialized from IplImage).