6

我想确认cv::Mat::release()方法是否类似于free()C 编程中的方法,即它从内存中释放矩阵数据。

特别是,我想了解此方法在内存泄漏方面的行为,并确保在可能的程序中没有泄漏。

4

4 回答 4

8

如果引用计数器等于 1,那么是的,cv::Mat::release()会将其减为零并释放结构(如free在 C 中)。

如果引用计数器大于一(即,有其他对象对结构感兴趣),则只会cv::Mat::release()递减引用计数器。

您可以通过调用该方法来增加结构的引用计数器cv::Mat(即,标记您对它感兴趣并且您不希望它被释放) 。cv::Mat::addref()

于 2013-04-08T08:06:11.073 回答
6

您不必手动释放 cv::Mat 对象,因为它是自动管理的,除非您已从 Iplimage 初始化 Mat,在这种情况下您应该手动释放它 deallocate()。

请参考这个线程。

openCV 将 IplImage 与 cv::Mat 混合

于 2013-04-08T09:27:04.880 回答
5

我使用这样的代码结构(带有 C++ 的 OpenCV)出现内存泄漏:

int i;
while(true){
    Mat x = imread("C:/pics"+i+".jpg");
    //do something with x
}

经过 100 次左右的迭代后,它总是崩溃,然后我将代码更改为:

int i;
while(true){
    Mat x = imread("C:/pics"+i+".jpg");
    //do something with x
    x.refcount = 0;
    x.release();
}

它停止崩溃并进行了完整的迭代。但是当手动将 refcount 设置为 0 时,您必须确定您不再需要该对象。这可能是有人对我的答案投反对票的原因,但我使用这种方法解决了我的问题。那我为什么不分享呢?

于 2014-04-13T10:10:06.363 回答
0

以下程序片段测试 Mat::release() 的行为(改编自opencv-org-answer

using namespace std;
using namespace cv;

int main(int argc, char **argv) {
    cout << "test_mat_release.cpp" << endl;

    {
        //memory is released
        const char *pzInputImg = "data/em_sample.png";

        Mat img;
        img = imread(pzInputImg);
        assert(img.data);
        img.release();
        assert(!img.data);
    }
    {
        //memory is released
        Mat img(100, 100, CV_32FC1);
        assert(img.data);
        img.release();
        assert(!img.data);
    }

    {   
        //Since Mat does not owns data , data is not released
        //you have to explicitly release data
        int cols=17;
        int rows=15;
        unsigned char * data = new unsigned char[rows*cols*3];
        Mat img(rows, cols, CV_8UC3, data);
        assert(img.data);
        img.release();
        assert(!img.data);
        delete [] data;
    }



    Mat imgRef;
    {
        //memory is not released
        //since there img.data is now shared with imgRef
        Mat img(100, 100, CV_32FC1);
        imgRef=img;
        assert(img.data);
        assert(img.data == imgRef.data);
        img.release();
        assert(img.empty());
        assert(!img.data);
        //img.data is NULL, but imgRef.data is not NULL, so data is not de-allocated
        assert(!imgRef.empty());
        assert(imgRef.data);
    }
    return 0;
}
于 2016-10-29T23:49:02.203 回答