c++ - 使用 opencv : VideoCapture 内存泄漏

标签 c++ qt opencv memory-leaks

我用 Qt Creator 2.4.1 (Qt 4.8.4) 和 OpenCV 2.4.2 开发了一个应用程序,它从文件夹中读取图像并显示它们。

它使用 cv::VideoCapture 和 QGraphicsScene/QGraphicsView。它运行良好,但是我遇到了内存泄漏:如果我在任务管理器中查看消耗的内存,每次读取新图像时内存都会增加并最终崩溃。

我的主窗口是用Qt Designer创建的,它是一个继承QMainWindow的类。上面有一个 QGraphicsView view_src 和一个按钮:buttonStart

这是一个代码示例:类声明:

using namespace std;
using namespace cv;

namespace Ui {
    class FenetrePrinc;
}

class FenetrePrinc : public QMainWindow {
    Q_OBJECT
public:
    explicit FenetrePrinc(QWidget *parent = 0);
    ~FenetrePrinc();

public slots:
    virtual void start();
    virtual void tick();
    virtual void stop_timer();

private:
    Ui::FenetrePrinc *ui;

    QString filename;
    QGraphicsScene *scene_src;
    QGraphicsItem *img_src;

    VideoCapture sequence;

    Mat src;
};

类定义:

FenetrePrinc::FenetrePrinc(QWidget *parent) : QMainWindow(parent), ui(new Ui::FenetrePrinc){

    ui->setupUi(this);
    scene_src = new QGraphicsScene();
    timer = new QTimer(this);

    img_src = scene_src->addPixmap(QPixmap("vide.jpg"));
    ui->view_src->setScene(scene_src);

    connect(ui->buttonStart, SIGNAL(clicked()), this, SLOT(start()));
}

FenetrePrinc::~FenetrePrinc(){
    delete scene_src;
    delete img_src;
    delete ui;
}

void FenetrePrinc::start(){
    if(src.empty())
        sequence.open(filename.toStdString());

    connect(timer, SIGNAL(timeout()), this, SLOT(tick()));
    timer->start(1000/24);   //24 frames per second

    disconnect(ui->buttonStart, SIGNAL(clicked()), this, SLOT(start()));
    connect(ui->buttonStart, SIGNAL(clicked()), this, SLOT(stop_timer()));
}

void FenetrePrinc::tick(){
    sequence >> src;

    if(src.empty())
    {
        sequence.release();
        stop_timer();
        return;
    }

    scene_src->removeItem(img_src);
    img_src = scene_src->addPixmap(convert16uc1(src));

    src.release();
}

void FenetrePrinc::stop_timer(){
    timer->stop();
    disconnect(timer, SIGNAL(timeout()), this, SLOT(tick()));

    disconnect(ui->buttonStart, SIGNAL(clicked()), this, SLOT(stop_timer()));
    connect(ui->buttonStart, SIGNAL(clicked()), this, SLOT(start()));
}

我不明白为什么每次读取图像时内存使用量都会上升,我确实在每次读取图像时释放图像,并在完成后释放序列。但也许我错过了什么?

编辑:函数QPixmap convert16uc1(Mat img) 是内存泄漏的原因。我必须使用此功能,因为我正在处理 Qt 无法读取的 16 位灰度图像。我使用 OpenCV 打开图像并执行图像处理,然后使用 Qt 显示图像。

函数代码如下:

QPixmap FenetrePrinc::convert16uc1(const cv::Mat& source)
{
  quint16* pSource = (quint16*) source.data;
  int pixelCounts = source.cols * source.rows;

  QImage dest(source.cols, source.rows, QImage::Format_RGB32);

  char* pDest = (char*) dest.bits();

  for (int i = 0; i < pixelCounts; i++)
  {
    quint8 value = (quint8) ((*(pSource)) >> 8);
    *(pDest++) = value;  // B
    *(pDest++) = value;  // G
    *(pDest++) = value;  // R
    *(pDest++) = 0;      // Alpha
    pSource++;
  }
  return QPixmap::fromImage(dest);
}

最佳答案

很可能是 convert16uc1

如果您不能在此处发布 convert16uc1,请尝试使用 imwrite 将图像临时保存在 opencv 中并在 Qt 中加载图像。如果memleak消失了。分析 convert16uc1

或者不调用 convert16uc1(src) 而是调用 addPixmap 使用之前在 Qt 中加载的一些其他常量图像。

关于c++ - 使用 opencv : VideoCapture 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30526041/

相关文章:

c++ - 从 Qt 程序运行外部进程,有一些变化

c++ - Syntastic 提示文件丢失

Android Studio Opencv Canny检测

android - Android OpenCV:手部检测

c++ - 使用模板参数重载 C++ 方法 : how to make this work for subclass of template?

python - 在导入的模块中使用外部类方法

c++ - "pin a native member"是什么意思?

java - 将帧(android 中的 mat 数据)从 android 传递到 native c++ 并检测人脸

c++ - 使用全局 std::array 引用作为模板参数时如何简化参数?

c++ - classList 数组不会向用户打印输出