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. Sending OpenCV images continuously from C++ to Qml
Forum Updated to NodeBB v4.3 + New Features

Sending OpenCV images continuously from C++ to Qml

Scheduled Pinned Locked Moved Solved QML and Qt Quick
18 Posts 6 Posters 9.0k Views 2 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.
  • Y Offline
    Y Offline
    Yunus
    wrote on 8 Aug 2019, 11:19 last edited by Yunus 8 Aug 2019, 11:20
    #1

    Hi all, I am stuck in a subject and I need help. I have a while loop in C++ part and it is taking frames from the camera continuously using OpenCV library and at the same time my qml UI is also working. Both are working in different threads so there is no problem up to now.

    I want to send my OpenCV images to Qml part continuously. I can convert OpenCV images to QImage. For example, I can send QString to qml easily using emit function. Is there a simple way like this for images. I looked at several examples but I couldnt find an efficient one. Here is the examples which I tried:

    Here
    and here

    S 1 Reply Last reply 8 Aug 2019, 11:31
    1
    • Y Yunus
      8 Aug 2019, 11:19

      Hi all, I am stuck in a subject and I need help. I have a while loop in C++ part and it is taking frames from the camera continuously using OpenCV library and at the same time my qml UI is also working. Both are working in different threads so there is no problem up to now.

      I want to send my OpenCV images to Qml part continuously. I can convert OpenCV images to QImage. For example, I can send QString to qml easily using emit function. Is there a simple way like this for images. I looked at several examples but I couldnt find an efficient one. Here is the examples which I tried:

      Here
      and here

      S Offline
      S Offline
      sierdzio
      Moderators
      wrote on 8 Aug 2019, 11:31 last edited by sierdzio 8 Aug 2019, 11:31
      #2

      @yunus said in Sending OpenCV images continuously from C++ to Qml:

      I looked at several examples but I couldnt find an efficient one

      So even the image provider was too slow?

      Try subclassing QQuickItem then, and paint the image directly there as a texture, it should be faster. An example of this (warning: very old code! But should work) https://github.com/sierdzio/closecombatfree/blob/master/src/qmlBase/ccfqmlbasemap.cpp. Once you register the item you can use it in QML as if it was a built-in component.

      Alternatively, there is also QNanoPainter.

      (Z(:^

      1 Reply Last reply
      2
      • Y Offline
        Y Offline
        Yunus
        wrote on 8 Aug 2019, 11:38 last edited by Yunus 8 Aug 2019, 11:39
        #3

        @sierdzio said in Sending OpenCV images continuously from C++ to Qml:
        @sierdzio Thanks for ur reply. I couldnt even try image provider. I can send image to qml but not continuously. I am new on Qt and I need a simple example to do that.

        1 Reply Last reply
        0
        • S Offline
          S Offline
          sierdzio
          Moderators
          wrote on 8 Aug 2019, 11:42 last edited by
          #4

          Look at the documentation, then. It contains several examples https://doc.qt.io/qt-5/qquickimageprovider.html

          (Z(:^

          Y 1 Reply Last reply 8 Aug 2019, 13:40
          3
          • G Offline
            G Offline
            GrecKo
            Qt Champions 2018
            wrote on 8 Aug 2019, 12:20 last edited by
            #5

            You should implement an object capable of adding frames on a QAbstractVideoSurface, here is a quick explanation on how to do it : https://forum.qt.io/post/474269 (ignore the QScreen::grabWindow part). The non trivial part is converting your frames to QVideoFrame.

            You could then use this object as a source of a QML VideoOutput.

            1 Reply Last reply
            2
            • S sierdzio
              8 Aug 2019, 11:42

              Look at the documentation, then. It contains several examples https://doc.qt.io/qt-5/qquickimageprovider.html

              Y Offline
              Y Offline
              Yunus
              wrote on 8 Aug 2019, 13:40 last edited by Yunus 8 Aug 2019, 13:41
              #6

              @sierdzio Okey I tried to use ImageProvider example in here. Okey I can send my image but how can i update images when I changed the QImage in cpp part. Here is my files:

              LiveImageProvider.cpp

              // LiveImageProvider.cpp
              #include "liveimageprovider.h"
              #include <QDebug>
              /**
              * @brief Image provider that is used to handle the live image stream in the QML viewer.
               */
              LiveImageProvider::LiveImageProvider() : QQuickImageProvider(QQuickImageProvider::Image)
              {
                  this->no_image = QImage(":/images/no_image.png");
                  this->blockSignals(false);
              }
              
              
              QImage LiveImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
              {
                  QImage result = this->image;
              
                  if(result.isNull()) {
                      result = this->no_image;
                  }
              
                  if(size) {
                      *size = result.size();
                  }
              
                  if(requestedSize.width() > 0 && requestedSize.height() > 0) {
                      result = result.scaled(requestedSize.width(), requestedSize.height(), Qt::KeepAspectRatio);
                  }
              
                  return result;
              }
              
              void LiveImageProvider::updateImage(const QImage &image)
              {
                  if(this->image != image) {
                      this->image = image;
                      emit imageChanged();
                  }
              }
              

              LiveImageProvider.h

              // LiveImageProvider.h
              #ifndef LIVEIMAGEPROVIDER_H
              #define LIVEIMAGEPROVIDER_H
              
              #include <QImage>
              #include <QQuickImageProvider>
              
              class LiveImageProvider : public QObject, public QQuickImageProvider
              {
                  Q_OBJECT
              public:
                  LiveImageProvider();
              
                  QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize) override;
              
              public slots:
                  void updateImage(const QImage &image);
                  int ulan();
              
              signals:
                  void imageChanged();
              
              private:
                  QImage image;
                  QImage no_image;
              };
              
              #endif // LIVEIMAGEPROVIDER_H
              

              main.qml

              import QtQuick 2.9
              import QtQuick.Window 2.2
              import QtQuick.Controls 1.0
              
              
              Window {
                  visible: true
                  width: 1200
                  height: 900
                  title: qsTr("Hello World")
                  Image {
                    id: liveImage
                    property bool counter: false
                  
                    asynchronous: true
                    source: "image://live/image"
                    anchors.fill: parent
                    fillMode: Image.PreserveAspectFit
                    cache: false
                  
                  
                    function reload() {
                      counter = !counter
                      source = "image://live/image?id=" + counter
                    }
                    }
              }
              
              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on 8 Aug 2019, 19:09 last edited by
                #7

                Hi,

                Out of curiosity, do you do any processing with OpenCV ?
                If not, what about using QtMultimedia and the Camera type ?

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                Y 1 Reply Last reply 9 Aug 2019, 06:42
                2
                • S Offline
                  S Offline
                  sierdzio
                  Moderators
                  wrote on 8 Aug 2019, 19:11 last edited by
                  #8

                  Hm indeed, looks like the image provider API does not contain any useful API to update the view continuously. You could hack around it with the solution you linked (https://forum.qt.io/topic/38978/solved-send-qimage-from-c-to-qml-via-qquickimageprovider-or-using-a-signal/4), which requests a new image periodically using a timer. But probably a better solution is to prepare a video surface like @GrecKo suggests, or to reimplement QQuickItem. Sorry for leading you down a suboptimal path!

                  (Z(:^

                  Y 1 Reply Last reply 9 Aug 2019, 06:46
                  3
                  • SGaistS SGaist
                    8 Aug 2019, 19:09

                    Hi,

                    Out of curiosity, do you do any processing with OpenCV ?
                    If not, what about using QtMultimedia and the Camera type ?

                    Y Offline
                    Y Offline
                    Yunus
                    wrote on 9 Aug 2019, 06:42 last edited by Yunus 8 Sept 2019, 06:51
                    #9

                    @sgaist Yeah, I m doing lots of task in Opencv and I need to send opencv images to qml continuously. I used this example. But I can only send images triggering with qml buttons. I want to send the images continuously like video.

                    1 Reply Last reply
                    0
                    • S sierdzio
                      8 Aug 2019, 19:11

                      Hm indeed, looks like the image provider API does not contain any useful API to update the view continuously. You could hack around it with the solution you linked (https://forum.qt.io/topic/38978/solved-send-qimage-from-c-to-qml-via-qquickimageprovider-or-using-a-signal/4), which requests a new image periodically using a timer. But probably a better solution is to prepare a video surface like @GrecKo suggests, or to reimplement QQuickItem. Sorry for leading you down a suboptimal path!

                      Y Offline
                      Y Offline
                      Yunus
                      wrote on 9 Aug 2019, 06:46 last edited by
                      #10

                      @sierdzio Thanks for ur help. I will try the example using timer I hope it works :(

                      J.HilkJ 1 Reply Last reply 9 Aug 2019, 07:43
                      0
                      • Y Yunus
                        9 Aug 2019, 06:46

                        @sierdzio Thanks for ur help. I will try the example using timer I hope it works :(

                        J.HilkJ Offline
                        J.HilkJ Offline
                        J.Hilk
                        Moderators
                        wrote on 9 Aug 2019, 07:43 last edited by
                        #11

                        @yunus

                        You can also take a look at one of my projects:
                        https://github.com/DeiVadder/Sindepile-Challenge-QML

                        I used that one to experiment with the QImageProvoder class and I update the ui each time a new image is available, not based on a timer.

                        If you don't really care about performance, you could also simply force an update each time possible, by reacting to the frameSwapped signal


                        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                        Q: What's that?
                        A: It's blue light.
                        Q: What does it do?
                        A: It turns blue.

                        Y 1 Reply Last reply 9 Aug 2019, 08:05
                        0
                        • J.HilkJ J.Hilk
                          9 Aug 2019, 07:43

                          @yunus

                          You can also take a look at one of my projects:
                          https://github.com/DeiVadder/Sindepile-Challenge-QML

                          I used that one to experiment with the QImageProvoder class and I update the ui each time a new image is available, not based on a timer.

                          If you don't really care about performance, you could also simply force an update each time possible, by reacting to the frameSwapped signal

                          Y Offline
                          Y Offline
                          Yunus
                          wrote on 9 Aug 2019, 08:05 last edited by
                          #12

                          @j-hilk @sierdzio Thank you so much. I am very glad to both. I think I fixed my problem. I solved using Imageprovider and QTimer using example here. And also @J-Hilk project is working well. I ll use one of these. Thank you Qt Forum, I am very happy to be able to fix this problem

                          1 Reply Last reply
                          1
                          • G Offline
                            G Offline
                            GrecKo
                            Qt Champions 2018
                            wrote on 9 Aug 2019, 08:07 last edited by
                            #13

                            QQuickImageProvider is not the correct solution to display videos. Implementing a source for a VideoOutput is the sanest thing to do.
                            If we are advising convoluted ways to display a video, I'd like to propose writing a QAbstractTableModel containing each pixel value in its cells, and display that with a TableView and 1x1 Rectangle delegates.

                            Y J.HilkJ 2 Replies Last reply 9 Aug 2019, 08:14
                            2
                            • G GrecKo
                              9 Aug 2019, 08:07

                              QQuickImageProvider is not the correct solution to display videos. Implementing a source for a VideoOutput is the sanest thing to do.
                              If we are advising convoluted ways to display a video, I'd like to propose writing a QAbstractTableModel containing each pixel value in its cells, and display that with a TableView and 1x1 Rectangle delegates.

                              Y Offline
                              Y Offline
                              Yunus
                              wrote on 9 Aug 2019, 08:14 last edited by
                              #14

                              @grecko I also want the right way but I am new on Qt. Do you have an example to advise me about your method

                              1 Reply Last reply
                              0
                              • G GrecKo
                                9 Aug 2019, 08:07

                                QQuickImageProvider is not the correct solution to display videos. Implementing a source for a VideoOutput is the sanest thing to do.
                                If we are advising convoluted ways to display a video, I'd like to propose writing a QAbstractTableModel containing each pixel value in its cells, and display that with a TableView and 1x1 Rectangle delegates.

                                J.HilkJ Offline
                                J.HilkJ Offline
                                J.Hilk
                                Moderators
                                wrote on 9 Aug 2019, 08:14 last edited by
                                #15

                                @grecko awesome idea, may I suggest an add-on .

                                Will need some work on the model, but I suggest only updating every other row, for a 90's era interlacing effect!
                                😉


                                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                Q: What's that?
                                A: It's blue light.
                                Q: What does it do?
                                A: It turns blue.

                                1 Reply Last reply
                                1
                                • G Offline
                                  G Offline
                                  GrecKo
                                  Qt Champions 2018
                                  wrote on 9 Aug 2019, 08:27 last edited by
                                  #16

                                  @Yunus Here's a post where I explain it textually : https://forum.qt.io/post/474269

                                  Here is some sample code I wrote some time ago : https://gist.github.com/oKcerG/a5b59c7583c85ff03bdec238eed8bcd8

                                  The import part is the videoSurface setter which starts the videoSurface, and then I periodically present a frame on it.

                                  Make sure to chose a correct QVideoSurfaceFormat, and don't do like I did for generating a QVideoFrame ( QPixmap -> QImage -> QImage in the correct format -> QVideoFrame), that's way too much conversions, but I did that only as a quick proof of concept.

                                  There must be a more direct way to convert cv::Mat to QVideoFrame, there might even be a copyless solution but that's not my domain of expertise.

                                  1 Reply Last reply
                                  2
                                  • Y Offline
                                    Y Offline
                                    Yunus
                                    wrote on 9 Aug 2019, 08:34 last edited by
                                    #17

                                    Thank you I ll try

                                    1 Reply Last reply
                                    0
                                    • M Offline
                                      M Offline
                                      Muhammet Ali Asan
                                      wrote on 5 Nov 2019, 15:51 last edited by
                                      #18

                                      As far as I understand you want to read video from camera, process frames using OpenCV then display output in QML. This solution you used is not good. It uses timer with a second interval and each timeout event will send image to QML.
                                      2 Disadvantages :

                                      • You are hardcoding your processing speed to 1 fps. Even camera provides more frames you are reading only 1 frame. To catch everything your timer ticks should be more frequent than your video reader.

                                      • In a low power system or with a camera with low fps there will be synchronization problems.

                                      You should use QAbstractVideoFilter . There is a good example in the page. Basically it allows you to process image while it is being sent to VideoOutput by Camera in Qml. And it will be definitely more easier and efficient than your solution.

                                      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