Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Passing Mat in form of signal
QtWS25 Last Chance

Passing Mat in form of signal

Scheduled Pinned Locked Moved Solved General and Desktop
16 Posts 4 Posters 6.2k Views
  • 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.
  • KiraK Offline
    KiraK Offline
    Kira
    wrote on last edited by Kira
    #1

    Hello All,
    I am trying to implement threading in qt. I am using it for sample camera application.
    I have read on some post that sub classing of QThread is not preferred in the newer version of QT. So implementing it in form of worker thread and calling slot through signal and slot mechanism.

    I have defined a thread where it captures the frame from camera and emit a signal consisting of mat object as:
    emit frameReceived(capFrame);

    Now i have to pass this to myLabel where i can update the value on label
    I am using following signal and slot:
    connect(worker, SIGNAL(frameReceived(Mat)),this, SLOT(update_lblCapture()));
    Run time error:
    QObject::connect: Cannot queue arguments of type 'Mat'
    (Make sure 'Mat' is registered using qRegisterMetaType().)

    For the error i followed the below link:
    http://doc.qt.io/archives/qt-4.8/custom-types.html

    My questions are following:

    1. From the link above how i can registered mat which is always defined
    2. If i able to emit the mat object how will i be able it to pass to update QLabel slot in the main window
    3. What is correct approach for give below implementation
    J.HilkJ 1 Reply Last reply
    0
    • KiraK Kira

      Hello All,
      I am trying to implement threading in qt. I am using it for sample camera application.
      I have read on some post that sub classing of QThread is not preferred in the newer version of QT. So implementing it in form of worker thread and calling slot through signal and slot mechanism.

      I have defined a thread where it captures the frame from camera and emit a signal consisting of mat object as:
      emit frameReceived(capFrame);

      Now i have to pass this to myLabel where i can update the value on label
      I am using following signal and slot:
      connect(worker, SIGNAL(frameReceived(Mat)),this, SLOT(update_lblCapture()));
      Run time error:
      QObject::connect: Cannot queue arguments of type 'Mat'
      (Make sure 'Mat' is registered using qRegisterMetaType().)

      For the error i followed the below link:
      http://doc.qt.io/archives/qt-4.8/custom-types.html

      My questions are following:

      1. From the link above how i can registered mat which is always defined
      2. If i able to emit the mat object how will i be able it to pass to update QLabel slot in the main window
      3. What is correct approach for give below implementation
      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by J.Hilk
      #2

      @Kira said in Passing Mat in form of signal:

      My questions are following:

      1. From the link above how i can registered mat which is always defined
      2. If i able to emit the mat object how will i be able it to pass to update QLabel slot in the main window

      1: in your main.cpp: something like this : qRegisterMetaType<cv::Mat>();
      2: you need to convert your mat to a QImage Or QPixmap, take a look here @Hub


      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.

      KiraK 1 Reply Last reply
      4
      • VRoninV Offline
        VRoninV Offline
        VRonin
        wrote on last edited by
        #3

        What is Mat? it's not a Qt or std class so you'll need to be more specific.

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        KiraK 1 Reply Last reply
        0
        • J.HilkJ J.Hilk

          @Kira said in Passing Mat in form of signal:

          My questions are following:

          1. From the link above how i can registered mat which is always defined
          2. If i able to emit the mat object how will i be able it to pass to update QLabel slot in the main window

          1: in your main.cpp: something like this : qRegisterMetaType<cv::Mat>();
          2: you need to convert your mat to a QImage Or QPixmap, take a look here @Hub

          KiraK Offline
          KiraK Offline
          Kira
          wrote on last edited by Kira
          #4

          @J.Hilk :
          Hi i have added the following in main function
          QApplication a(argc, argv);
          qRegisterMetaTypecv::Mat();
          MainWindow w;
          w.show();
          So I am getting the following error
          Type is not registered, please use the Q_DECLARE_METATYPE macro to make it known to Qt's meta-object system

          So I tried declaring the following at end of my worker thread class
          Q_DECLARE_METATYPE(cv::Mat);
          But it gives me the same error message

          J.HilkJ 1 Reply Last reply
          0
          • KiraK Kira

            @J.Hilk :
            Hi i have added the following in main function
            QApplication a(argc, argv);
            qRegisterMetaTypecv::Mat();
            MainWindow w;
            w.show();
            So I am getting the following error
            Type is not registered, please use the Q_DECLARE_METATYPE macro to make it known to Qt's meta-object system

            So I tried declaring the following at end of my worker thread class
            Q_DECLARE_METATYPE(cv::Mat);
            But it gives me the same error message

            J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by J.Hilk
            #5

            @Kira

            move it befor your main
            and register it before you create QApplication.

            Q_DECLARE_METATYPE(cv::Mat)
            
            int main (int argc, char *argv[]){
                qRegisterMetaType<cv::Mat>();
                 QApplication a(argc, argv);
                 MainWindow w;
                 w.show();
            }
            

            And @VRonin is correct, I just assumed Mat = OpenCV libary, if thats not the case, the above changes completely


            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.

            KiraK 1 Reply Last reply
            1
            • VRoninV VRonin

              What is Mat? it's not a Qt or std class so you'll need to be more specific.

              KiraK Offline
              KiraK Offline
              Kira
              wrote on last edited by
              #6

              @VRonin : Sorry its cv::Mat (opencv matrix) to store images.

              1 Reply Last reply
              0
              • J.HilkJ J.Hilk

                @Kira

                move it befor your main
                and register it before you create QApplication.

                Q_DECLARE_METATYPE(cv::Mat)
                
                int main (int argc, char *argv[]){
                    qRegisterMetaType<cv::Mat>();
                     QApplication a(argc, argv);
                     MainWindow w;
                     w.show();
                }
                

                And @VRonin is correct, I just assumed Mat = OpenCV libary, if thats not the case, the above changes completely

                KiraK Offline
                KiraK Offline
                Kira
                wrote on last edited by VRonin
                #7

                @J.Hilk : Hi i tried the above syntax mentioned it gives the error as follows:

                Progaram:

                Q_DECLARE_METATYPE(cv::Mat)
                
                int main(int argc, char *argv[])
                {
                    qRegisterMetaType<cv::Mat>();
                    QApplication a(argc, argv);
                    //qRegisterMetaType<cv::Mat>();
                    MainWindow w;
                    w.show();
                
                    return a.exec();
                }
                

                Error:
                Type is not registered, please use the Q_DECLARE_METATYPE macro to make it known to Qt's meta-object system

                1 Reply Last reply
                0
                • VRoninV Offline
                  VRoninV Offline
                  VRonin
                  wrote on last edited by
                  #8

                  If it's cv::Mat you have another, deeper, problem. Its copy constructor does not copy at all, it copies by reference and it does not detach as Qt classes do. So when you pass a cv::Mat to slot in a thread you are not passing a different object from the one you have on the main thread and you might have a race condition.
                  You should put a slot inbetween that calls cv::Mat::clone

                  Source:
                  https://docs.opencv.org/trunk/d3/d63/classcv_1_1Mat.html#a294eaf8a95d2f9c7be19ff594d06278e

                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                  ~Napoleon Bonaparte

                  On a crusade to banish setIndexWidget() from the holy land of Qt

                  KiraK 1 Reply Last reply
                  4
                  • J.HilkJ Offline
                    J.HilkJ Offline
                    J.Hilk
                    Moderators
                    wrote on last edited by
                    #9

                    If your goal is to show the the Matrix as a QImage in a QLable, do step 2 first and convert it to a QImage and send that via Signal, QImage should be a declared Metatype from the getGo. And do use QImage and not QPixmap or you open an other can of worms!


                    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.

                    KiraK 1 Reply Last reply
                    2
                    • VRoninV VRonin

                      If it's cv::Mat you have another, deeper, problem. Its copy constructor does not copy at all, it copies by reference and it does not detach as Qt classes do. So when you pass a cv::Mat to slot in a thread you are not passing a different object from the one you have on the main thread and you might have a race condition.
                      You should put a slot inbetween that calls cv::Mat::clone

                      Source:
                      https://docs.opencv.org/trunk/d3/d63/classcv_1_1Mat.html#a294eaf8a95d2f9c7be19ff594d06278e

                      KiraK Offline
                      KiraK Offline
                      Kira
                      wrote on last edited by
                      #10

                      @VRonin : Thanks for the information. Will take care of the same.

                      1 Reply Last reply
                      0
                      • J.HilkJ J.Hilk

                        If your goal is to show the the Matrix as a QImage in a QLable, do step 2 first and convert it to a QImage and send that via Signal, QImage should be a declared Metatype from the getGo. And do use QImage and not QPixmap or you open an other can of worms!

                        KiraK Offline
                        KiraK Offline
                        Kira
                        wrote on last edited by
                        #11

                        @J.Hilk : Thanks for the information. Will try to move with the second approach and try to implement the same.

                        Actually i am trying to implement multithreading to implement various functionality of camera.
                        So i wanted to capture the image and update the label in separate thread. There are various cases where i'll need to apply some algorithm of opencv over the frame and display it. Approach two is seems good for the above mentioned example but when i'll have to perform other process. I have to pass frame to slot for processing.

                        Please Note: In some of the examples they don't recommend subclassing thread directly, instead declare a worker and handle the thread mechanism through signal and slot.

                        1 Reply Last reply
                        0
                        • KiraK Offline
                          KiraK Offline
                          Kira
                          wrote on last edited by VRonin
                          #12

                          @J-Hilk : Thanks for the help just got the stuff working.
                          The syntax in your first comment was the solution with bit of modification
                          Original:
                          qRegisterMetaType<cv::Mat>();

                          Modified:
                          qRegisterMetaType< Mat >("Mat");

                          Thanks once again. Keeping this thread as open for while, will marked as solved once i can display the frame correctly after receiving the mat object via signal.

                          1 Reply Last reply
                          3
                          • KiraK Offline
                            KiraK Offline
                            Kira
                            wrote on last edited by
                            #13

                            @J-Hilk :Hi i was able to run threading example as suggest by you but there is one issue i tried searching online but could not get relevant solution

                            I am referring to below link for threading example:
                            https://fabienpn.wordpress.com/2013/05/01/qt-thread-simple-and-stable-with-sources/

                            With the changes suggested i was able to run the opencv code by changing to the dowork() in the example and passing the mat frame.
                            void Worker::doWork()
                            {
                            qDebug()<<"Starting worker process in Thread "<<thread()->currentThreadId();

                            mutex.lock();
                            bool abort = _abort;
                            mutex.unlock();
                            
                            if (abort) {
                                qDebug()<<"Aborting worker process in Thread "<<thread()->currentThreadId();
                                return;
                            }
                            
                            while(1)
                            {
                                   //Capture the frame from camera
                                  //Emit the captured frame
                            }
                            
                            // Set _working to false, meaning the process can't be aborted anymore.
                            mutex.lock();
                            _working = false;
                            mutex.unlock();
                            
                            qDebug()<<"Worker process finished in Thread "<<thread()->currentThreadId();
                            
                            emit finished();
                            

                            }

                            //Handling the following on start button clicked
                            void MainWindow::on_btn_start_clicked()
                            {
                            worker->abort();
                            thread->wait();
                            worker->requestWork();
                            }
                            //It works fine when i start the application.
                            When i again click on the start button sample application gives the following output
                            Request worker start in Thread 0x3020
                            Starting worker process in Thread 0x2f50
                            Request worker aborting in Thread 0x3020
                            Aborting worker process in Thread 0x2f50
                            Worker process finished in Thread 0x2f50

                            // When i check the logs of my application it gives the following output
                            Request worker start in Thread 0x1288
                            Starting worker process in Thread 0x28b0
                            Request worker aborting in Thread 0x1288

                            And after this the UI freezes. Also i had put a debug command in the while loop mentioned, above it starts printing it messages.

                            Note: When i remove the thread->wait() everything works fine and get the following logs:
                            Request worker start in Thread 0x27dc
                            Starting worker process in Thread 0xc50
                            Request worker aborting in Thread 0x27dc
                            Request worker start in Thread 0x27dc
                            Request worker aborting in Thread 0x27dc
                            Request worker start in Thread 0x27dc

                            My only concern in the above sample it shows the worker process thread and also aborting of it but in my case there is no such message. And if i put thread->wait() for the output UI freezes. I have searched for relevant examples on thread->wait() but was unable to figure the exact issue.

                            jsulmJ 1 Reply Last reply
                            0
                            • KiraK Kira

                              @J-Hilk :Hi i was able to run threading example as suggest by you but there is one issue i tried searching online but could not get relevant solution

                              I am referring to below link for threading example:
                              https://fabienpn.wordpress.com/2013/05/01/qt-thread-simple-and-stable-with-sources/

                              With the changes suggested i was able to run the opencv code by changing to the dowork() in the example and passing the mat frame.
                              void Worker::doWork()
                              {
                              qDebug()<<"Starting worker process in Thread "<<thread()->currentThreadId();

                              mutex.lock();
                              bool abort = _abort;
                              mutex.unlock();
                              
                              if (abort) {
                                  qDebug()<<"Aborting worker process in Thread "<<thread()->currentThreadId();
                                  return;
                              }
                              
                              while(1)
                              {
                                     //Capture the frame from camera
                                    //Emit the captured frame
                              }
                              
                              // Set _working to false, meaning the process can't be aborted anymore.
                              mutex.lock();
                              _working = false;
                              mutex.unlock();
                              
                              qDebug()<<"Worker process finished in Thread "<<thread()->currentThreadId();
                              
                              emit finished();
                              

                              }

                              //Handling the following on start button clicked
                              void MainWindow::on_btn_start_clicked()
                              {
                              worker->abort();
                              thread->wait();
                              worker->requestWork();
                              }
                              //It works fine when i start the application.
                              When i again click on the start button sample application gives the following output
                              Request worker start in Thread 0x3020
                              Starting worker process in Thread 0x2f50
                              Request worker aborting in Thread 0x3020
                              Aborting worker process in Thread 0x2f50
                              Worker process finished in Thread 0x2f50

                              // When i check the logs of my application it gives the following output
                              Request worker start in Thread 0x1288
                              Starting worker process in Thread 0x28b0
                              Request worker aborting in Thread 0x1288

                              And after this the UI freezes. Also i had put a debug command in the while loop mentioned, above it starts printing it messages.

                              Note: When i remove the thread->wait() everything works fine and get the following logs:
                              Request worker start in Thread 0x27dc
                              Starting worker process in Thread 0xc50
                              Request worker aborting in Thread 0x27dc
                              Request worker start in Thread 0x27dc
                              Request worker aborting in Thread 0x27dc
                              Request worker start in Thread 0x27dc

                              My only concern in the above sample it shows the worker process thread and also aborting of it but in my case there is no such message. And if i put thread->wait() for the output UI freezes. I have searched for relevant examples on thread->wait() but was unable to figure the exact issue.

                              jsulmJ Offline
                              jsulmJ Offline
                              jsulm
                              Lifetime Qt Champion
                              wrote on last edited by
                              #14

                              @Kira You need to check the "abort" flag INSIDE your while loop! Checking it before entering the while loop does not make sense.

                              https://forum.qt.io/topic/113070/qt-code-of-conduct

                              KiraK 1 Reply Last reply
                              0
                              • jsulmJ jsulm

                                @Kira You need to check the "abort" flag INSIDE your while loop! Checking it before entering the while loop does not make sense.

                                KiraK Offline
                                KiraK Offline
                                Kira
                                wrote on last edited by
                                #15
                                This post is deleted!
                                1 Reply Last reply
                                0
                                • KiraK Offline
                                  KiraK Offline
                                  Kira
                                  wrote on last edited by
                                  #16

                                  Solved the issue have messed a bit with the booleans and the loops :p
                                  Once again thanks @J-Hilk @VRonin @jsulm for your response and support

                                  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