Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory leak using opencv : VideoCapture

I have developed an application with Qt Creator 2.4.1 (Qt 4.8.4) and OpenCV 2.4.2 that reads images from a folder and displays them.

It uses cv::VideoCapture and QGraphicsScene/QGraphicsView. It runs well, however I encounter a memory leak : if I look at the consumed memory in task manager, memory goes up each time a new image is read and end up crashing.

My main window was created with Qt Designer, it's a class that inherits QMainWindow. There is a QGraphicsView view_src on it and also a push button : buttonStart

Here is a sample of code : Class declaration :

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;
};

Class definition :

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()));
}

I don't understand why does memory usage goes up and up each time an image is read, I do release the image each time it is read, and release sequence once finished. But maybe I missed something ?

EDIT : The function QPixmap convert16uc1(Mat img) is the cause of the memory leak. I have to use this function because I am working with 16bits grayscale images, which Qt cannot read. I open images and perform image processing with OpenCV and display the images with Qt.

The code of the function is the following :

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);
}
like image 899
zarachbaal Avatar asked Dec 22 '25 08:12

zarachbaal


1 Answers

Most probably it is convert16uc1.

If you can't post convert16uc1 here, try saving the image temporarily in opencv using imwrite and loading the image in Qt. If the the memleak disappears. analyze convert16uc1.

Or don't call convert16uc1(src) but call addPixmap using some other constant image previously loaded in Qt.

like image 100
Valentin H Avatar answered Dec 24 '25 00:12

Valentin H