Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Memory leak (OpenCV + QML)
Forum Updated to NodeBB v4.3 + New Features

Memory leak (OpenCV + QML)

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
2 Posts 2 Posters 2.2k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    DYYF
    wrote on last edited by
    #1

    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.

    1 Reply Last reply
    0
    • Pablo J. RoginaP Offline
      Pablo J. RoginaP Offline
      Pablo J. Rogina
      wrote on last edited by
      #2

      @DYYF have you tried any other examples for OpenCV + QML? i.e. here or here?
      I'm not sure why, but I don't like your videoprocessor object launching the QML engine. All the examples I've used to so far run the QML engine from main.cpp

      Upvote the answer(s) that helped you solve the issue
      Use "Topic Tools" button to mark your post as Solved
      Add screenshots via postimage.org
      Don't ask support requests via chat/PM. Please use the forum so others can benefit from the solution in the future

      1 Reply Last reply
      0

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved