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. Image display on thread in qt

Image display on thread in qt

Scheduled Pinned Locked Moved Unsolved General and Desktop
5 Posts 3 Posters 605 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.
  • R Offline
    R Offline
    rahult
    wrote on 8 Sept 2020, 15:52 last edited by
    #1

    I am trying to display my image. Here detect_images is a vector of vector contains Mat images, this myfunction is running on a thread triggered with QtConcurrent and trying to display on the thread itself. I am getting a black empty window displayed but not image.

    What wrong i was doing here and can we display image on thread.

    void MainWindow::myfunction(string name, int buf_id)
    {
        cv::putText(detect_images[buf_id][0],"4",cv::Point(40, detect_images[buf_id][0].rows / 2),cv::FONT_HERSHEY_DUPLEX,1.0,CV_RGB(118, 185, 0),2);
        string path = res_path+name;
        cv::imwrite(path, detect_images[buf_id][0]);                                            //writing images into folder
    
        QPixmap pixmap;                                                                                                          //display images
        QImage qimg(detect_images[buf_id][0].data, detect_images[buf_id][0].cols, detect_images[buf_id][0].rows, detect_images[buf_id][0].step, QImage::Format_RGB888);
        pixmap = QPixmap::fromImage(qimg.rgbSwapped());
        ui->label->setPixmap(pixmap);
        ui->label->setScaledContents(true);
        ui->label->show();
        qApp->processEvents();
        QThread::currentThread()->msleep(1000);
    
        detect_images[buf_id].clear();
        free_buff.push(buf_id);
    }
    K 1 Reply Last reply 8 Sept 2020, 16:20
    0
    • R rahult
      8 Sept 2020, 15:52

      I am trying to display my image. Here detect_images is a vector of vector contains Mat images, this myfunction is running on a thread triggered with QtConcurrent and trying to display on the thread itself. I am getting a black empty window displayed but not image.

      What wrong i was doing here and can we display image on thread.

      void MainWindow::myfunction(string name, int buf_id)
      {
          cv::putText(detect_images[buf_id][0],"4",cv::Point(40, detect_images[buf_id][0].rows / 2),cv::FONT_HERSHEY_DUPLEX,1.0,CV_RGB(118, 185, 0),2);
          string path = res_path+name;
          cv::imwrite(path, detect_images[buf_id][0]);                                            //writing images into folder
      
          QPixmap pixmap;                                                                                                          //display images
          QImage qimg(detect_images[buf_id][0].data, detect_images[buf_id][0].cols, detect_images[buf_id][0].rows, detect_images[buf_id][0].step, QImage::Format_RGB888);
          pixmap = QPixmap::fromImage(qimg.rgbSwapped());
          ui->label->setPixmap(pixmap);
          ui->label->setScaledContents(true);
          ui->label->show();
          qApp->processEvents();
          QThread::currentThread()->msleep(1000);
      
          detect_images[buf_id].clear();
          free_buff.push(buf_id);
      }
      K Offline
      K Offline
      KroMignon
      wrote on 8 Sept 2020, 16:20 last edited by Christian Ehrlicher 9 Aug 2020, 16:54
      #2

      @rahult said in Image display on thread in qt:

      What wrong i was doing here and can we display image on thread.

      UI element must be updated in UI thread. This is what you are doing wrong!
      You can do it like this:

      // I suppose ui is a member of MainWindow class
      QTimer::singleShot(0, this, [this, pixmap](){
          ui->label->setPixmap(pixmap);
          ui->label->setScaledContents(true);
          ui->label->show();
      });
      

      It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

      R 2 Replies Last reply 8 Sept 2020, 17:19
      1
      • K KroMignon
        8 Sept 2020, 16:20

        @rahult said in Image display on thread in qt:

        What wrong i was doing here and can we display image on thread.

        UI element must be updated in UI thread. This is what you are doing wrong!
        You can do it like this:

        // I suppose ui is a member of MainWindow class
        QTimer::singleShot(0, this, [this, pixmap](){
            ui->label->setPixmap(pixmap);
            ui->label->setScaledContents(true);
            ui->label->show();
        });
        
        R Offline
        R Offline
        rahult
        wrote on 8 Sept 2020, 17:19 last edited by rahult 9 Aug 2020, 17:28
        #3

        @KroMignon Thank you and yes ui is a member of MainWindow class

        I have added the snippet in my code. This myfunction will be called on a thread for sequence of images.

        void MainWindow::myfunction(string name, int buf_id)
        {
            cv::putText(detect_images[buf_id][0],"4",cv::Point(40, detect_images[buf_id][0].rows / 2),cv::FONT_HERSHEY_DUPLEX,1.0,CV_RGB(118, 185, 0),2);
            string path = res_path+name;
            cv::imwrite(path, detect_images[buf_id][0]);
        //    display_images.push(detect_images[buf_id][0]);
        
            QPixmap pixmap;
            QImage qimg(detect_images[buf_id][0].data, detect_images[buf_id][0].cols, detect_images[buf_id][0].rows, detect_images[buf_id][0].step, QImage::Format_RGB888);
            pixmap = QPixmap::fromImage(qimg.rgbSwapped());
        
            QTimer::singleShot(0, this, [this, pixmap](){
                ui->label->setPixmap(pixmap);
                ui->label->setScaledContents(true);
                ui->label->show();
            });
        
            QThread::currentThread()->msleep(100);
        )
        

        i could see only the last image is displayed

        1 Reply Last reply
        0
        • K KroMignon
          8 Sept 2020, 16:20

          @rahult said in Image display on thread in qt:

          What wrong i was doing here and can we display image on thread.

          UI element must be updated in UI thread. This is what you are doing wrong!
          You can do it like this:

          // I suppose ui is a member of MainWindow class
          QTimer::singleShot(0, this, [this, pixmap](){
              ui->label->setPixmap(pixmap);
              ui->label->setScaledContents(true);
              ui->label->show();
          });
          
          R Offline
          R Offline
          rahult
          wrote on 8 Sept 2020, 17:58 last edited by rahult 9 Aug 2020, 17:59
          #4

          @KroMignon said in Image display on thread in qt:

          UI element must be updated in UI thread. This is what you are doing wrong!

          Out of curiosity i wanted to know...... as you said UI element must be updated in UI thread, i am maintaining a common buffer where i push the resultant images into it and wanted to display it on main thread. Below is how i followed, even though i get the same black empty window issue.
          Here i am calling function1 from my main() where my UI is declared, display_images is a queue globally declared.

          void MainWindow::display_func()
          {
              qDebug() << display_images.size();
              while(display_images.size())   
              {
                  Mat img = display_images.front();
                  QPixmap pixmap;
                  QImage qimg(img.data, img.cols, img.rows, img.step, QImage::Format_RGB888);
                  pixmap = QPixmap::fromImage(qimg.rgbSwapped());
                  ui->label->setPixmap(pixmap);
                  ui->label->setScaledContents(true);
                  ui->label->show();
                  qApp->processEvents();
                  QThread::currentThread()->msleep(100);
                  display_images.pop();
              }
          }
          
          void MainWindow::function1(int buf_id)
          {
              DIR *dir;
              struct dirent *ent;
              cv::Mat img;
              string img_path;
              dir = opendir(img_paths.c_str());
              while(1)
              {
                  if(pro_buf.size() <= max_in_images)
                  {
                      if((ent = readdir(dir)) == NULL)
                      {
                          closedir(dir);
                          terminate_th = 1;
                          break;
                      }
                      if(ent->d_name[0] == '.')
                      {
                          continue;
                      }
                      img_path = img_paths + ent->d_name;
                      img = cv::imread(img_path.c_str(), 1);
          
                      pro_buf.push(img);
                  }
                  display_func();
              }
              return;
          }
          
          void MainWindow::myfunction(string name, int buf_id)
          {
              cv::putText(detect_images[buf_id][0],"4",cv::Point(40, detect_images[buf_id][0].rows / 2),cv::FONT_HERSHEY_DUPLEX,1.0,CV_RGB(118, 185, 0),2);
              string path = res_path+name;
              cv::imwrite(path, detect_images[buf_id][0]);
              display_images.push(detect_images[buf_id][0]);
              detect_images[buf_id].clear();
              free_buff.push(buf_id);
          }
          
          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on 8 Sept 2020, 18:08 last edited by
            #5

            Hi,

            How exactly are you using threads in your application.

            From the code you are showing you seem to call UI related function within MainWindow trying to force the event loop to run and then blocking it.

            If you want to show your images one after the other, you should use a QTimer with a slot displaying the next image and stop the QTimer once your done. You can also use a single shot version within your slot to call it again and not do that after your buffer is empty.

            As for the black image, beside the threading issues you may have, are you sure that your images are not black before converting them to QPixmap ?

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

            1 Reply Last reply
            3

            1/5

            8 Sept 2020, 15:52

            • Login

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