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);
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With