std::thread & imshow() - no windows created
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);
drone.enable_video_stream();
vision.ihm_start(&ihm_run);
while (ihm_run)
{
if (ihm.get_key_pressed == 27)
{
ihm_run = false;
}
}
vision.stop_ihm();
}
Now I have a class named Vision_manager with the following vision_manager.h :
class Vision_Manager {
public:
/* ------ CONSTRUCTEUR & DESTRUCTEUR ------ */
Vision_Manager(Drone_Controller& drone);
~Vision_Manager();
/* ------ FONCTIONS MEMBRES UTILISABLES DANS LE MAIN ------ */
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();
private:
/* ------ 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)
{
}
Vision_Manager::~Vision_Manager()
{
cv::destroyAllWindows();
}
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()
{
m_ihm_thread.join();
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";
}
else
{
//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 :).
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
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.
"and I'll create a thread for mat processing" -- yes, imho, that's a much better approach