gpt4 book ai didi

c++ - OpenCV - 如果从一个线程调用两次,imshow 会挂起

转载 作者:行者123 更新时间:2023-12-02 16:11:42 24 4
gpt4 key购买 nike

大家。

我正在尝试使用一个单独的线程来显示和处理来自网络摄像头的图像。这些操作不能在主线程中,因为它专用于其他任务。我需要做的是停止并最终重新启动线程。

发生的情况是线程第一次运行,但在第二次运行时 imshow 调用永远卡住。

我用一个偏离另一个 SO 问题 (cv::imshow does not display cv::mat color when on different thread) 的简单示例重现了这个问题

非工作多线程代码

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

using namespace std;
using namespace cv;

class Capture {
private:
bool running;

std::thread thread;
cv::Mat background;
void loop() {

while (running) {
cv::imshow(windowName, background); // at the second time the thread is started this instruction will hang
cv::waitKey(500);
Scalar color(rand()&255, rand()&255, rand()&255);
background.setTo(color);
}
cv::destroyWindow(windowName);
cv::waitKey(1);
}
public:
char windowName[128];
Capture() :
windowName{"test"},
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;
// run the thread one time
cap.run();
std::this_thread::sleep_for(std::chrono::milliseconds(2500));
cap.stop();
// wait
std::this_thread::sleep_for(std::chrono::milliseconds(500));
// run again
cap.run(); //stuck!!!
std::this_thread::sleep_for(std::chrono::milliseconds(2500));
cap.stop();

return 0;
}

工作单线程代码

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

using namespace std;
using namespace cv;

int main()
{
Scalar color(rand()&255, rand()&255, rand()&255);
cv::Mat background(800, 800, CV_8UC3, cv::Scalar{ 255, 0, 255 }) ;
background.setTo(color);
// try the first time to display an image
for (int i=0; i<5; i++)
{
cv::imshow("test", background);
cv::waitKey(500);
color=(rand()&255, rand()&255, rand()&255);
background.setTo(color);
}
// destroy the image
cv::destroyWindow("test");

// repeat the same as before
for (int i=0; i<5; i++)
{
cv::imshow("test", background);
cv::waitKey(500);
color=(rand()&255, rand()&255, rand()&255);
background.setTo(color);
}
cv::destroyWindow("test");
// it worked !
return 0;
}

是否有任何理由导致代码段 #1 不起作用?

谢谢,

马可

编辑

似乎这两个片段都使用存储库中的 opencv3.x 工作。在 Xubuntu 19.04 上从头开始编译的 opencv4.x 失败。

最佳答案

所有 UI 事物都应该留在主线程上! 这就是导致该问题的原因。您不能在另一个线程上使用 UI 内容,例如 waitKey()imshow() 等。

您还试图从另一个线程停止计时器,这也是另一个问题。

以下是提及同一问题的主题:

Post1

Post2

Post3

关于c++ - OpenCV - 如果从一个线程调用两次,imshow 会挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60737852/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com