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:arcLength 断言失败并出现 cv::Mat