c++ - openCV 将 IplImage 与 cv::Mat 混合

标签 c++ c memory-management opencv memory-leaks

我在使用 opencv 时遇到过一些内存管理不明确的问题。 您可以使用新的 opencv c++ 类执行此操作:

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

现在我不明白的是,如果我执行以下操作,我会得到一个错误:

theimage.deallocate();

也许这是错误的。我做了一些实验,当我释放 Mat 对象时:

theimage.release();

IplImage 对象仍然保留在内存中。有什么方法可以告诉 cv::Mat 对象破坏 IplImage 对象,或者我的第一行代码是错误的(因为我已经丢失了 IplImage 对象的指针)? 我在互联网上看到了很多人们使用第一行代码的例子。许多人解释了如何转换,但没有人解释内存会发生什么!

问题是我有很多使用 IplImage 对象的类(我用它开始了我的项目)。而且我理解为什么 cv::Mat 比 IplImage 更好。

--编辑--

在互联网上我找到了以下混合解决方案:

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

我认为这可以解决我的一些问题,但会使我的代码有点不可读,而且在我看来仍然很危险。 如果 tmp 在 cv::Mat 之前被释放,我将使用一些损坏的对象(我没有测试,但我认为是这样)。简单的方法是使用拷贝:

cv::Mat theimage(tmp,true);

这是我找到的唯一解决方案,但对我来说感觉不对......

最佳答案

歧义来自于一个极其可怕的做法:将 C 接口(interface)与 OpenCV 的 C++ 接口(interface)混合。不要这样做,请改用 cv::imread()

cv::Mat 的析构函数 will always deallocate memory when needed , except 当它是 initialized from a IplImage 时,然后您可以使用deallocate() 释放它的资源。我写了一个简单的实验来验证这个信息:

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;
}

getchar() 调用暂停程序,以便您可以检查应用程序的内存占用情况。如果您注释掉 deallocate(),您会注意到加载图像后内存占用量并没有减少。

旁注,Mat::release()仅在需要时减少引用计数器并释放数据(但如果 Mat 是从 IplImage 初始化的,它也不会释放数据)。

关于c++ - openCV 将 IplImage 与 cv::Mat 混合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11156019/

相关文章:

c++ - 多面体/球体射线相交确定?

c - MacOS Mojave 中的 C 头文件在哪里?

c - 指向指针数组的指针和 Stack Smashing 错误

c - 在 Ubuntu 中从另一个 C 文件中运行一个 C 文件

ios - Swift 变量在内存中丢失但在调试中可见

iphone - 我需要显式分配我的 NSNumber 吗?

c++ - 如何获取 3D 世界中对象相对于父对象的绝对位置?

C++11 GCC 4.6.2 std::move

c++ - 如何从 C++ 中的函数返回两个值?

Linux malloc 段错误缺失