1

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

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

4

1 回答 1

3

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

的析构函数cv::Mat 总是在需要时释放内存除非它是从 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()它也不会释放)。MatIplImage

于 2012-06-22T12:49:43.830 回答