【问题标题】:cv::imshow does not display cv::mat color when on different threadcv::imshow 在不同线程上时不显示 cv::mat 颜色
【发布时间】:2016-02-03 23:34:54
【问题描述】:

这是我用来在不同线程上生成带有一些内容的 HighGui 窗口的类。

class Capture {
private:
  bool running;
  std::thread thread;
  cv::Mat background;
  void loop() {
    while (running) {
      cv::imshow("sth",background);
      cv::waitKey(settings::capture_wait_time);
    }
  }
  public:
   Capture()  :
     running {false},
     thread {},
     background { 800, 800,  CV_8UC3, cv::Scalar{255,0,255}} {
       cv::namedWindow("sth");  
   }
   inline ~Capture() {
     if (running) stop(); // stop and join the thread
     cv::destroyWindow("sth");
   }
   void run() {
     if (!running) {
       running = true;
       thread = std::thread{[this]{loop();}};
     }
   }
   inline void join() { if (thread.joinable()) thread.join(); };
   inline void stop() {
     running = false;
     if (thread.joinable()) thread.join();
   }
};

// main
Capture cap;
cap.run();
// ... 

问题是窗口最终总是黑色的(在这种情况下它应该是紫色的)。我显然在这里遗漏了一些东西....

【问题讨论】:

  • 尝试使用 cv::namedWindow 在主线程中创建窗口
  • 窗口在主线程中创建:在我的主线程中调用 Capture 的构造函数(这是创建窗口的位置),然后 Capture::run 生成一个新线程。
  • CAPTURE_WINDOW_NAME 和“sth”有什么区别?
  • 无,抱歉我已经编辑了原文
  • 你能在 imshow 之前 adf 一个 cout,在 imshow 之后一个 cout,在 waitKey 之后一个 cout 来检查它是冻结在那里还是不显示?

标签: c++ multithreading opencv highgui


【解决方案1】:

您似乎无法在另一个线程中创建窗口。此外,您在另一个线程上调用成员函数的方式似乎是错误的。

看看这段代码。它在不同的线程中显示每秒变化的图像,并在 5 秒后返回。

#include <opencv2/opencv.hpp>
#include <thread>

using namespace std;
using namespace cv;

class Capture {
private:
    bool running;
    std::thread thread;
    cv::Mat background;
    void loop() {

        while (running) {
            cv::imshow("sth", background);
            cv::waitKey(1000);

            Scalar color(rand()&255, rand()&255, rand()&255);
            background.setTo(color);
        }
    }
public:
    Capture() :
        running{ false },
        thread{},
        background{ 800, 800, CV_8UC3, cv::Scalar{ 255, 0, 255 } } {
    }
    inline ~Capture() {
        if (running) stop(); // stop and join the thread
    }
    void run() {
        if (!running) {
            running = true;
            thread = std::thread{ &Capture::loop, this };
        }
    }
    inline void join() { if (thread.joinable()) thread.join(); };
    inline void stop() {
        running = false;
        if (thread.joinable()) {
            thread.join();
        }
    }
};

int main()
{
    Capture cap;
    cap.run();

    std::this_thread::sleep_for(std::chrono::milliseconds(5000));

    cap.stop();

    return 0;
}

【讨论】:

  • cv::namedWindow 从 Ctor 中消失的任何特殊原因?我想这只是一个错字吧?
  • 不,这不是错字。如果您使用在不同线程中创建的窗口,它将不起作用。
  • 那么我应该把它放在哪里呢?在循环()内?顺便说一句,我下一个答案中的代码(其中 cv::nameWindow 在 Ctor 中)确实有效:
  • 我的代码不是一成不变的,你可以根据需要更改。它解决了原来的不显示紫色窗口的问题。就是这样。
  • 只是报告当 cv::namedWindow 添加到循环中时,它确实有效。我会将它添加到您的代码中,以便它编译。
猜你喜欢
  • 2021-04-18
  • 2013-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-16
  • 2014-06-21
  • 1970-01-01
  • 2023-03-17
相关资源
最近更新 更多