opencv cvtcolor 内存泄露

c++的opencv4.7版本,做成dll供MFC调用,dll中使用多线程处理多张图片,在加入如下几行代码后,程序每运行一遍,所占内存增加0.05MB,实际图片是1.6MB的。

Mat dst;
        fout << "dst 的地址" << &(dst.data) << endl;
        cvtColor(src, dst, COLOR_GRAY2BGR);
        fout << "dst 的地址" << &(dst.data) << endl;
        
        dst.release();
        delete dst.data;
        dst.data = nullptr;

有谁遇到这个难题啦?
我的多线程处理函数如下,m_work_img是我的一个公用mat,每次从这里面取图片。

void XDXCustomQueueProcess::Deal_Image(int index)
{
    try {
        //Sleep(5000);   //不可以在m_work_img克隆之前睡眠,会导致m_work_img一直没更新
        fout << "进入图像处理线程,线程号:" << std::this_thread::get_id() << "图片序号为: " << index << endl;
        unique_lock<mutex> lg0(m_lock);
        Mat src = m_work_img.clone();
        fout << "m_work_img 的地址"<<&(m_work_img.data) << endl;
        fout << "src 的地址" << &(src.data) << endl;
        lg0.unlock();
        Mat dst;
        fout << "dst 的地址" << &(dst.data) << endl;
        cvtColor(src, dst, COLOR_GRAY2BGR);
        fout << "dst 的地址" << &(dst.data) << endl;
        
        dst.release();
        dst = Mat();    //根据别人建议修改,也没改善

OpenCV和std:thread内存泄漏
可以参考下


https://www.5axxw.com/questions/content/ooxlnt

过查资料和验证,我在cvtcolor前面加入cv::setNumThreads(1);或者cv::setNumThreads(0);
关闭opencv的并行运算,可解决。大概是我自己的多线程跟opencv函数内部的多线程搞混,导致有内存没释放。

dst没有被正确释放

不用delete也不需要设置 dst.data = nulptr吧,这不是由opencv负责内存管理的吗

Mat dst;
fout << "dst 的地址" << &(dst.data) << endl;
cvtColor(src, dst, COLOR_GRAY2BGR);
fout << "dst 的地址" << &(dst.data) << endl;

// 不需要调用 dst.release();
// 不需要 delete dst.data;
dst.data = nullptr;
这样每次运行时占用的内存应该不会增加。

【以下回答由 ChatGPT 生成】

问题解答:

从您提供的代码来看,出现内存泄漏的原因可能是由于未正确释放dst对象的内存。以下是一种可能的解决方法:

Mat dst;
fout << "dst 的地址:" << &(dst.data) << endl;
cvtColor(src, dst, COLOR_GRAY2BGR);
fout << "dst 的地址:" << &(dst.data) << endl;

delete [] dst.data;    // 释放dst.data指向的内存
dst.release();

这里我们使用delete []运算符来释放动态分配的内存,然后调用release()函数将dst对象所占用的内存清空。

另一方面,在多线程函数中,我们并不需要手动释放dst对象的内存,因为析构函数会自动处理内存释放。因此,删除以下代码行:

dst.release();
dst = Mat();

请注意,在多线程函数中,在m_work_img对象的使用之前,需要确保该对象已更新并赋予新的值,以避免在克隆时出现问题。

希望这些建议可以帮助您解决内存泄漏问题。如果您还有任何问题,请随时提问。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

cvtColor你这么写不会泄漏的。问题更可能出现在clone()生成的src这里,你看下最后加个src.release()操作看下。
还有一种可能是内存碎片的问题,特别是频繁的开辟小空间,短时间内增长是正常的,但是到了一定程度,内存会降下来。

有没有发现你的这个src Mat src = m_work_img.clone();一直没有被释放,考虑下是否应该释放src。

我自己回答一下,经过查资料和验证,我在cvtcolor前面加入cv::setNumThreads(1);或者cv::setNumThreads(0);
关闭opencv的并行运算,可解决。大概是我自己的多线程跟opencv函数内部的多线程搞混,导致有内存没释放。
https://www.likecs.com/ask-1210062.html

根据你提供的代码,我注意到你在每次处理图像后使用了dst.release()delete dst.data来释放内存。然而,这种方式是不正确的,因为dst是通过Mat对象的析构函数自动释放内存的。你不需要手动释放内存。

另外,你在每次处理图像后将dst设置为Mat(),这也是不必要的。dst.release()已经足够将其释放。

关于内存增加的问题,可能是由于多线程处理导致的。每个线程都会创建自己的dst对象,这可能会导致内存增加。你可以尝试在每个线程处理完图像后,将dst对象释放,以减少内存占用。

另外,你在输出地址时使用了&(dst.data),这只是输出了dst.data的地址,并不代表整个dst对象的地址。如果你想输出整个dst对象的地址,可以使用&dst

最后,你在多线程处理函数中使用了fout来输出信息。请确保在多线程环境下使用fout时进行适当的同步,以避免竞争条件和数据错误。

希望这些信息对你有帮助!如果你有任何其他问题,请随时提问。

OpenCV是一个广泛使用的开源计算机视觉库。其中cvtColor函数是进行颜色空间转换的函数之一。然而,在使用OpenCV进行图像处理时,经常会发现一些内存泄漏的问题。其中,cvtColor函数也存在一些可能导致内存泄漏的问题。

  1. 内存泄漏的原因

在使用cvtColor函数时,如果没有正确释放内存,就可能导致内存泄漏。cvtColor函数会在处理颜色空间转换时,创建一些中间变量。这些中间变量在使用过后,需要手动释放,否则就会出现内存泄漏的问题。

  1. 解决内存泄漏的方法

为了解决cvtColor函数可能导致的内存泄漏问题,可以采用以下方法:

2.1. 使用Mat对象

Mat是OpenCV中一个重要的数据类型,用于表示图像矩阵。在使用cvtColor函数时,可以将中间变量保存在Mat对象中,然后手动释放Mat对象,以释放中间变量所占用的内存。示例如下:

Mat src_image = imread("test.jpg");
Mat dst_image;
cvtColor(src_image, dst_image, COLOR_BGR2GRAY);
// 中间变量不需要手动释放

在这种情况下,中间变量就被保存在了dst_image对象中,不需要手动释放。

2.2. 使用智能指针

C++中提供了智能指针这一概念,可以有效地防止内存泄漏的问题。在使用cvtColor函数时,可以使用智能指针来管理中间变量。示例如下:

Mat src_image = imread("test.jpg");
Mat* dst_image = new Mat;
{
    Ptr<Mat> src = makePtr<Mat>(src_image);
    Ptr<Mat> dst = makePtr<Mat>(*dst_image);
    cvtColor(*src, *dst, COLOR_BGR2GRAY);
}
delete dst_image;

在这个示例中,使用了智能指针Ptr来保存Mat对象。由于Ptr会自动管理指针的生命周期,因此无需手动释放中间变量所占用的内存。

总之,cvtColor函数可能会导致内存泄漏的主要原因是由于没有正确释放中间变量所占用的内存。为了避免这种情况的发生,可以使用Mat对象或智能指针来管理中间变量。这些方法可以帮助我们更好地使用OpenCV进行图像处理,并避免由内存泄漏引起的程序崩溃等问题。