Ask Your Question

std::thread & imshow() - no windows created

asked 2016-02-24 10:27:48 -0500

Maltergate gravatar image

Hi dears,

First of all, thanks for your time :).

I'm trying to create thread (yes I know, multi-thread is bad however I'd like to experiment) in which I would display an image.

I have read OpenCV doesn't handle very much the threading and for some people, the window creation has to be done in main thread. So that's what I did.

int main(int argc, const char * argv[]) {

    bool success(true), ihm_run(true);

    Drone_Controller drone;
    Vision_Manager vision(drone);

    success = drone.connect();
    if (!success)
        return EXIT_FAILURE;

    cv::namedWindow("Display & Command", CV_WINDOW_AUTOSIZE);


    while (ihm_run)
        if (ihm.get_key_pressed == 27)
            ihm_run = false;

Now I have a class named Vision_manager with the following vision_manager.h :

class Vision_Manager {


/* ------ CONSTRUCTEUR & DESTRUCTEUR ------ */
Vision_Manager(Drone_Controller& drone);

void video_controls(); //Affiche la vidéo et récupère les entrées clavier
char get_key_pressed();
void ihm_start(bool *m_IHMRun);
void ihm_stop();


/* ------ ATTRIBUTS ------ */
Drone_Controller& m_drone;
cv::Mat m_picture_rgb;
char m_key_pressed;

bool *m_IHMRun;

//Déclaration du thread utilisé pour l'ihm
std::thread m_ihm_thread;

and vision_manager.c :

#include "vision_manager.hpp"

Vision_Manager::Vision_Manager(Drone_Controller& drone) : m_drone(drone)



void Vision_Manager::ihm_start(bool *IHMRun)
    m_ihm_thread = std::thread(&Vision_Manager::video_controls, this);
    //&Vision_Manager::video_controls, this, N

    m_IHMRun = IHMRun;

void Vision_Manager::ihm_stop()

    std::cout << "Jointure effectuée" << std::endl;

void Vision_Manager::video_controls()
    int picture_nb;

    //Créationde la fenêtre
    //cv::namedWindow("Affichage & Commandes", CV_WINDOW_AUTOSIZE);

    picture_nb = m_drone.get_picture_nb();

    while (*m_IHMRun == true)
        // Si l'initialitasion du stream n'a pas plantée et que l'image qu'on récupère est différente de celle d'avant
        if (m_drone.get_picture_nb() != picture_nb)
            // On récupère l'image
            m_picture_rgb = m_drone.get_picture();
            picture_nb = m_drone.get_picture_nb();

            // Test si l'image a bien été récupérée
            if (m_picture_rgb.empty())
                //Si elle est vide ça ne sert à rien (typiquement en début de programme)
                std::cout << "Image vide \n";
                //Affichage de l'image avec le niveau de batterie
                cv::imshow("Affichage & Commandes", m_picture_rgb);
                std::cout << "ImShow OpenCV" << std::endl;

        m_key_pressed = cv::waitKey(50);

    cv::destroyWindow("Affichage & Commandes");

char Vision_Manager::get_key_pressed()
    return m_key_pressed;

Everything is compiling and the thread is created as I see the prompts. However I do not have any window.

Does anyone know ?

Thanks again for your help :).

edit retag flag offensive close merge delete



naive threading - fastest way to hell.

probably none of the highgui calls should go into your thread, keep them in the main thread, you're messing with the os here

berak gravatar imageberak ( 2016-02-24 11:04:20 -0500 )edit

Hi @berak,

Thanks for your awnser. I'll redesign my program in order to avoid multi-threading then. The HighGUI will be used in main thread and I'll create a thread for mat processing (finding the edges, calculating new trajectory, etc...)

However if you have further information why this (highgui in another thread) cannot work, i'd be happy to read it. In fact I really don't understand why, what's the difference between two threads, why it would work in the first one and not in the second.

Maltergate gravatar imageMaltergate ( 2016-02-25 02:29:08 -0500 )edit

"and I'll create a thread for mat processing" -- yes, imho, that's a much better approach

berak gravatar imageberak ( 2016-02-25 02:38:43 -0500 )edit

1 answer

Sort by » oldest newest most voted

answered 2020-03-05 10:28:55 -0500

You need to create a thread loop, initialise the windows in the thread (best just before the loop starts) and update your windows from within the loop.

Here is an example, this thread loop is run from a detached thread (use mutex's to lock data passed into the loop and unlock accordingly)

void ImageViewer::processImageQueue()
// Initialise
cv::Mat floatImage(1230, 1204, CV_32FC3);
cv::Mat temp;
cv::Mat image;

sliderSelection = 0;

cv::namedWindow(m_windowName, cv::WINDOW_AUTOSIZE);
cv::createTrackbar("Exposure Time", m_windowName, &sliderSelection, maxSelection, onTrackbar);

ourself = this;
onTrackbar(sliderSelection, 0);

// Main thread loop
while (true)
    int imagesQueued = 0;
        std::lock_guard<std::mutex> guard(m_imageQueueMutex);
        imagesQueued = m_imageQueue.size();

    if (imagesQueued < 1)

        std::lock_guard<std::mutex> guard(m_imageQueueMutex);
        image = m_imageQueue[0];

    image.convertTo(temp, CV_32FC1);

    double min, max;
    cv::minMaxLoc(temp, &min, &max);

    temp = (temp - min) / (max - min);

    cv::cvtColor(temp, floatImage, CV_GRAY2BGR);

    cv::putText(floatImage, std::to_string(framesPerSecond()) + " fps", cv::Point(32, 32), 0, 1.0, cv::Scalar(0.0, 0.0, 1.0));
    cv::putText(floatImage, std::to_string(imagesQueued - 1) + " queued image(s)", cv::Point(32, 64), 0, 1.0, cv::Scalar(1.0, 0.0, 0.0));

    cv::imshow(m_windowName, floatImage);
edit flag offensive delete link more

Question Tools

1 follower


Asked: 2016-02-24 10:26:52 -0500

Seen: 7,019 times

Last updated: Feb 24 '16