2016-02-03 4 views
2

Это класс, который я использую для создания окна HighGui с некоторым контентом на другой поток.cv :: imshow не отображает cv :: mat color, когда на другой поток

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(); 
// ... 

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

+0

попытка создать окна ип основной поток с резюме :: namedWindow – Micka

+0

окно создается в основном потоке: конструктор Capture, называется в моей основной (это где создается окно), а затем, Capture :: run запускает новый поток. –

+0

В чем разница между CAPTURE_WINDOW_NAME и "sth"? – Micka

ответ

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; 
} 
+0

любая конкретная причина, почему cv :: namedWindow исчез из Ctor? Я считаю, что это просто опечатка? –

+0

Нет, это не опечатка. Это не работает, если вы используете окно, созданное в другом потоке. – Miki

+0

так, где я должен положить его? внутри цикла()? Кстати, код в моем следующем ответе (где cv :: nameWindow находится в Ctor) действительно работает: –