Unsolved Memory leak (OpenCV + QML)
-
Hi! I’m trying to display OpenCV Mat in QML image.
I grab frames from camera with OpenCV, the frames are displayed successfully in QML, but memory usage increases with time. How can I fix it? Here is the my code:
main.cpp
#include <QGuiApplication> #include "videoprovider.h" int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); VideoProvider videoProvider; return app.exec(); }
VideoProvider.h
#ifndef VIDEOPROVIDER_H #define VIDEOPROVIDER_H #include <QObject> #include <QFuture> #include <QImage> #include <QQmlApplicationEngine> #include <QQuickImageProvider> #include <opencv2/opencv.hpp> class VideoProvider : public QObject, public QQuickImageProvider { Q_OBJECT public: explicit VideoProvider(); QPixmap requestPixmap(const QString &id, QSize *size, const QSize& requestedSize); signals: void frameChanged(); public slots: void framePainted(); private: QQmlApplicationEngine engine; bool readyfor; cv::Mat mat; QImage outputImage; void process(); }; #endif // VIDEOPROVIDER_H
VideoProvider.cpp
#include <QQmlContext> #include <QtConcurrent/QtConcurrent> #include <QDebug> #include <QThread> #include "videoprovider.h" #include <QQuickImageProvider> VideoProvider::VideoProvider() : QQuickImageProvider (QQuickImageProvider :: Pixmap) { engine.rootContext()->setContextProperty("videoProvider", this); engine.addImageProvider(QLatin1String ("videoCapture"), this); engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); readyfor = true; QtConcurrent::run(this, VideoProvider::process); } void VideoProvider::framePainted() { readyfor = true; } void VideoProvider::process() { cv::VideoCapture capture(0); while(true){ QThread::currentThread()->msleep(80); if(!readyfor) continue; mat.release(); capture >> mat; if(mat.empty()) { qDebug()<<"disconnect"; } else { readyfor = false; cv::cvtColor(mat, mat, cv::COLOR_BGR2RGB); outputImage = QImage((uchar*)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB888); emit frameChanged(); } } capture.release(); } QPixmap VideoProvider::requestPixmap(const QString &id, QSize *size, const QSize& requestedSize) { return QPixmap::fromImage(outputImage); }
main.qml
import QtQuick 2.6 import QtQuick.Window 2.2 Window { visible: true width: 640 height: 480 title: qsTr("Hello World") id: root Image { id: videoLayer anchors.fill: parent cache: false onSourceChanged:{ videoProvider.framePainted(); } } Connections { target: videoProvider property int frameCounter: 0 onFrameChanged: { videoLayer.source = "image://videoCapture/hoge" + frameCounter; frameCounter ^= 1; } } }
I found that it happened when I send signal (emit frameChanged();) to QML.
-