【问题标题】:cv::Mat's release methodcv::Mat的释放方法
【发布时间】:2013-03-30 05:04:15
【问题描述】:

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

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

【问题讨论】:

  • 将你的代码封装在一个while(true){//loop}中并让它运行。同时,通过任务管理器监控您的记忆,以了解您的记忆。
  • 有特定的工具可以测量内存泄漏和其他编程错误(使用未初始化的变量等)。看看«valgrind»。

标签: c++ opencv free mat


【解决方案1】:

以下程序 sn-p 测试 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;
}

【讨论】:

  • 如果在最后一个例子中你展示了一种释放内存的方法,我想通过释放 imgRef 然后 img...?
  • 作物的参考是什么?比如Mat imgRef = img(roi);,如果我释放img,然后尝试释放imgRef,会发生什么?
【解决方案2】:

我使用这样的代码结构(OpenCV with C++)遇到了内存泄漏:

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 时,您必须确定您不再需要该对象。这可能是有人对我的答案投反对票的原因,但我使用这种方法解决了我的问题。那我为什么不分享呢?

【讨论】:

  • 你能澄清你投反对票的原因吗?是因为你没看懂我的意思吗?
【解决方案3】:

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

请参考这个帖子。

openCV mixing IplImage with cv::Mat

【讨论】:

    【解决方案4】:

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

    如果引用计数器大于 1(即,有一些其他对象对结构感兴趣),那么 cv::Mat::release()减少引用计数器。

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

    【讨论】:

    • 我有一个 cv::Mat v,即循环内的 v.create(),并且 v 的大小对于不同的迭代是不同的。然后对于下一次迭代,我喜欢删除旧的以创建新的。我可以使用 release() 或 deallocate() 吗?
    猜你喜欢
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 2017-01-12
    • 1970-01-01
    • 2014-06-21
    • 2016-11-14
    • 1970-01-01
    • 2017-06-07
    相关资源
    最近更新 更多