大家。
我试图有一个单独的线程来显示和处理来自网络摄像头的图像。
这些操作不能在主线程中,因为它专用于其他任务。
我需要做的是停止并最终重新启动线程。
发生的情况是,线程第一次运行,但在第二次运行时,imshow 调用永远冻结。
我用一个偏离另一个SO问题的简单例子重现了这个问题(在不同线程上时,cv::imshow 不显示 cv::mat 颜色 https://stackoverflow.com/questions/35189841/cvimshow-does-not-display-cvmat-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 不应该工作有什么原因吗?
Thanks,
Marco
edit
看来这两个片段都使用存储库中的 opencv3.x 来工作。
在 Xubuntu 19.04 上从头编译 opencv4.x 失败。