【问题标题】:openCV mixing IplImage with cv::MatopenCV 将 IplImage 与 cv::Mat 混合
【发布时间】:2012-06-24 17:48:25
【问题描述】:

我在使用 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);

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

【问题讨论】:

  • 解决办法是用cv::imread()代替cvLoadImage()

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


【解决方案1】:

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

cv::Matwill always deallocate memory when needed 的析构函数,除了当它是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 初始化的,它也不会释放)。

【讨论】:

  • 我认为 cv::Mat 从 IplImage 构造时不会释放内存。毕竟它不安全。
猜你喜欢
  • 2011-06-07
  • 2013-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-19
  • 1970-01-01
相关资源
最近更新 更多