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. Displaying live camera feed
Forum Updated to NodeBB v4.3 + New Features

Displaying live camera feed

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 4 Posters 566 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.
  • S Offline
    S Offline
    shreya_agrawal
    wrote on last edited by shreya_agrawal
    #1

    I am doing camera calibration through qt. I have several windows for it, such as exposure, blur, distortion and so on. I want to show the live camera feed in the labels present in each of the windows.
    For testing purpose, I have created a glob and stored several demo images in a vector. Then, I am running a while loop and emitting a signal with the current image, inside a thread. The other thread is used to initialize the UI. Then, the signal is connected to the slots of the individual window to set the images in their label. But this approach crashes the application for windows which perform costly operations on the image. Is there any other approach to address this issue?

    std::string folder = "/path/of/images/*.jpg";
        cv::glob(folder,images);
    
    void MainWindow::liveIMG::setReference(MainWindow *m) {
        this->m = m;
    }
    
    void MainWindow::liveIMG::run() {
        size_t i = 0;
        while (true)
        {
           if(i == m->images.size()) i = 0;
           m->img = cv::imread(m->images[i]);
           i++;
           QImage image(m->img.data, m->img.cols, m->img.rows, m->img.step, QImage::Format_RGB888);
           emit updateImage(image);
        }
    }
    
    jsulmJ Christian EhrlicherC JonBJ 3 Replies Last reply
    0
    • S shreya_agrawal

      I am doing camera calibration through qt. I have several windows for it, such as exposure, blur, distortion and so on. I want to show the live camera feed in the labels present in each of the windows.
      For testing purpose, I have created a glob and stored several demo images in a vector. Then, I am running a while loop and emitting a signal with the current image, inside a thread. The other thread is used to initialize the UI. Then, the signal is connected to the slots of the individual window to set the images in their label. But this approach crashes the application for windows which perform costly operations on the image. Is there any other approach to address this issue?

      std::string folder = "/path/of/images/*.jpg";
          cv::glob(folder,images);
      
      void MainWindow::liveIMG::setReference(MainWindow *m) {
          this->m = m;
      }
      
      void MainWindow::liveIMG::run() {
          size_t i = 0;
          while (true)
          {
             if(i == m->images.size()) i = 0;
             m->img = cv::imread(m->images[i]);
             i++;
             QImage image(m->img.data, m->img.cols, m->img.rows, m->img.step, QImage::Format_RGB888);
             emit updateImage(image);
          }
      }
      
      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @shreya_agrawal said in Displaying live camera feed:

      void MainWindow::liveIMG::run() {
      size_t i = 0;
      while (true)

      So, this is running in another thread (not the GUI thread)? And you also do not have any pause in this loop, so probably flooding the event queue with too many signals.

      "But this approach crashes the application" - as always in such a situation run in debugger and post stack trace after crash to see where it is crashing.

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

      S 1 Reply Last reply
      2
      • S shreya_agrawal

        I am doing camera calibration through qt. I have several windows for it, such as exposure, blur, distortion and so on. I want to show the live camera feed in the labels present in each of the windows.
        For testing purpose, I have created a glob and stored several demo images in a vector. Then, I am running a while loop and emitting a signal with the current image, inside a thread. The other thread is used to initialize the UI. Then, the signal is connected to the slots of the individual window to set the images in their label. But this approach crashes the application for windows which perform costly operations on the image. Is there any other approach to address this issue?

        std::string folder = "/path/of/images/*.jpg";
            cv::glob(folder,images);
        
        void MainWindow::liveIMG::setReference(MainWindow *m) {
            this->m = m;
        }
        
        void MainWindow::liveIMG::run() {
            size_t i = 0;
            while (true)
            {
               if(i == m->images.size()) i = 0;
               m->img = cv::imread(m->images[i]);
               i++;
               QImage image(m->img.data, m->img.cols, m->img.rows, m->img.step, QImage::Format_RGB888);
               emit updateImage(image);
            }
        }
        
        Christian EhrlicherC Offline
        Christian EhrlicherC Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #3

        @shreya_agrawal Apart from @jsulm comments please read the docs about the QImage ctor you're using and fix your code accordingly.

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        1 Reply Last reply
        3
        • S shreya_agrawal

          I am doing camera calibration through qt. I have several windows for it, such as exposure, blur, distortion and so on. I want to show the live camera feed in the labels present in each of the windows.
          For testing purpose, I have created a glob and stored several demo images in a vector. Then, I am running a while loop and emitting a signal with the current image, inside a thread. The other thread is used to initialize the UI. Then, the signal is connected to the slots of the individual window to set the images in their label. But this approach crashes the application for windows which perform costly operations on the image. Is there any other approach to address this issue?

          std::string folder = "/path/of/images/*.jpg";
              cv::glob(folder,images);
          
          void MainWindow::liveIMG::setReference(MainWindow *m) {
              this->m = m;
          }
          
          void MainWindow::liveIMG::run() {
              size_t i = 0;
              while (true)
              {
                 if(i == m->images.size()) i = 0;
                 m->img = cv::imread(m->images[i]);
                 i++;
                 QImage image(m->img.data, m->img.cols, m->img.rows, m->img.step, QImage::Format_RGB888);
                 emit updateImage(image);
              }
          }
          
          JonBJ Online
          JonBJ Online
          JonB
          wrote on last edited by JonB
          #4

          @shreya_agrawal
          As @Christian-Ehrlicher has said, a very common error we see with that constructor of QImage. Understand that your situation is compounded by this being in a thread: that means the emit() does not block calling any slots which may access the signal's image data, it proceeds immediately, making it certain it will go wrong; if it were a non-thread direct connection you might get away with it.

          1 Reply Last reply
          2
          • jsulmJ jsulm

            @shreya_agrawal said in Displaying live camera feed:

            void MainWindow::liveIMG::run() {
            size_t i = 0;
            while (true)

            So, this is running in another thread (not the GUI thread)? And you also do not have any pause in this loop, so probably flooding the event queue with too many signals.

            "But this approach crashes the application" - as always in such a situation run in debugger and post stack trace after crash to see where it is crashing.

            S Offline
            S Offline
            shreya_agrawal
            wrote on last edited by
            #5

            @jsulm
            Thank you for your reply!
            The issue was in fact flooding the event queue with too many signals. Now, I am using a boolean condition to start and stop the loop whenever necessary.

            JonBJ 1 Reply Last reply
            0
            • S shreya_agrawal has marked this topic as solved on
            • S shreya_agrawal

              @jsulm
              Thank you for your reply!
              The issue was in fact flooding the event queue with too many signals. Now, I am using a boolean condition to start and stop the loop whenever necessary.

              JonBJ Online
              JonBJ Online
              JonB
              wrote on last edited by
              #6

              @shreya_agrawal
              If you say so. However, be aware if you have code:

                     m->img = cv::imread(m->images[i]);
                     i++;
                     QImage image(m->img.data, m->img.cols, m->img.rows, m->img.step, QImage::Format_RGB888);
                     emit updateImage(image);
              
              

              If you hit the m->img = ... line a second time while the image passed in emit updateImage(image) has not yet been fully processed by whatever slot (in another thread in your case, and you are not using e.g. connected with BlockingQueuedConnection) it will/should go wrong. Maybe your new "boolean condition to start and stop the loop whenever necessary" prevents this happening, I don't know.

              S 1 Reply Last reply
              2
              • JonBJ JonB

                @shreya_agrawal
                If you say so. However, be aware if you have code:

                       m->img = cv::imread(m->images[i]);
                       i++;
                       QImage image(m->img.data, m->img.cols, m->img.rows, m->img.step, QImage::Format_RGB888);
                       emit updateImage(image);
                
                

                If you hit the m->img = ... line a second time while the image passed in emit updateImage(image) has not yet been fully processed by whatever slot (in another thread in your case, and you are not using e.g. connected with BlockingQueuedConnection) it will/should go wrong. Maybe your new "boolean condition to start and stop the loop whenever necessary" prevents this happening, I don't know.

                S Offline
                S Offline
                shreya_agrawal
                wrote on last edited by
                #7

                @JonB
                Ah! Thanks for the heads up, will look into it further.

                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