OpenCV cv::Mat 使用 std::vector 导致潜在的内存泄漏

Posted

技术标签:

【中文标题】OpenCV cv::Mat 使用 std::vector 导致潜在的内存泄漏【英文标题】:OpenCV cv::Mat causing potential memory leak with std::vector 【发布时间】:2013-08-12 14:41:08 【问题描述】:

就目前而言,我正在尝试以 cv::Mats 的形式将整个图像列表保存在向量内,以供以后处理。现在我有一些看起来像这样的东西:

do

 image = readimage();
 cv::Mat mat = cv::Mat((length, width, CV_8UC4, image));
 cv::Mat temp = mat.clone();
 saved_images.push_back();

 mat.release();
 temp.release();
 freeimagememory(image);

while(hasimage);

这确实有效。对于非常小的图像列表,它将很好地存储它们。然而,当我处理大量图像时,程序总是崩溃说 Abort() 被调用,并且经过检查它说它正在抛出一个 cv::exception。

有人知道这是为什么吗?我曾考虑将向量更改为指向 cv::Mats 的指针向量,以节省空间(克隆似乎很昂贵),但我不确定这将如何运作。

谁能帮忙?

EDIT1:引发的确切错误是未能分配 X 字节。我认为这是因为它以某种方式耗尽了所有可用内存(即使我坐在 8 gigs 内存上并且肯定有可用内存)。

EDIT2:

下面的代码似乎也可以工作。

std::vector<cv::Mat*> ptrvec;
do

 image.readimage();
 ptrvec.push_back(new cv::Mat((length, width, CV_8UC4, image)));
 freeimagememory(image);

while(hasimage);

这个没有内存问题(我可以将所有我想要的图像推送到它)但是当我尝试这样做时遇到访问冲突

cv::imshow("Test Window", *ptrvec[0]);

EDIT3:

我是否有可能达到 32 位的上限?我完全有能力将它重新编译成 64 位项目。

【问题讨论】:

抛出的 cv::exception 是什么?程序崩溃时,一个向量中存储了多少张图片? ~3000 被存储。当它中断并单击“中断”时,它会将我引导至新代码。 系统可能内存不足。图片的尺寸是多少? ~2 GB。我认为它已经通过了 32 位可执行文件的允许最大内存。这是正确的吗? 它可能使用超过 2GB 的空间,因为您的 Mat 对象向量作为未压缩数据存储在内存中。图片的尺寸是多少,例如高度与长度?例如,一个 640 像素 x 480 像素的彩色 (RGB) 图像将在内存中占用大约 640 x 480 x 3 = 921,600 Bytes ~ 1 MB 【参考方案1】:

当您将 3000 张 800 x 600 的彩色图像存储在一个矢量中时,您可能会耗尽内存。将 Mat 指针存储在内存中不会解决您的问题,因为数据仍分配在 RAM 中。

检查您的系统中是否有足够的内存来存储所有图像。如果不行,可以批量上传图片,比如先处理前500张,再处理后500张,等等

在您的程序中,您在 堆栈 上分配向量。当您需要大块内存(您的情况)时,建议在 heap 上进行分配。所以可以尝试在堆上分配向量(前提是你有足够的内存来存储向量)。请参阅stack vs heap 或this cpp-tutorial 了解更多信息。

【讨论】:

我很确定向量是使用动态内存实现的,应该是堆吧? 是的,好点,我认为你是对的。矢量对象本身可以在堆栈或堆上。但是,用于存储向量元素的内存始终在堆上动态分配。

以上是关于OpenCV cv::Mat 使用 std::vector 导致潜在的内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV 3.0中IplImage* 转cv::Mat

打印 cv::Mat opencv

OpenCV:arcLength 断言失败并出现 cv::Mat

OpenCV2:总结篇 cv::Mat

如何在 Python 中使用 OpenCV 创建 Mat 矩阵?

使用 OpenCV 在 C++ 中将 std::list 转换为 cv::Mat