cv :: imshow не отображает цвет cv :: mat в другом потоке

Это класс, который я использую для создания окна 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();
// ...

Проблема в том, что окно всегда будет черным (в этом случае оно должно быть фиолетовым). Я явно что-то здесь упускаю ….

2

Решение

Кажется, что вы не можете создать окно в другом потоке. Кроме того, способ вызова функции-члена в другом потоке кажется неправильным.

Посмотрите на этот код. Он отображает изображение, которое меняется каждую секунду в другом потоке, и возвращается через 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;
}
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]