OSG window blocks refresh of OpenCV window - c++

I have an app that shows (processed) webcam output in an OpenCV window (using imshow) and also, in a different thread, has an OSG window showing some geometry. The problem is that as long as the OSG window is refreshing, the OpenCV window does not update (all the processing in the thread happens, just the call to imshow does nothing). If I drag the OSG window, disabling refreshes, the OpenCV window starts updating normally.
Any ideas why this could happen?
(Windows 8, NVIDIA Quattro K2100, VC++)

You need to call the cv::waitKey() function inside the OpenSceneGraph viewer loop to have your OpenCV windows update. This means that you cannot simply use the OpenSceneGraph function viewer.run(). Instead you have to use the following viewer loop:
while (!viewer.done())
{
cv::waitKey(1);
viewer.frame();
}

Related

QT button becomes unpressable after show() when using OpenCV

I am running QT (5.15.2) on a Raspberry Pi (4B, Raspbian Bullseye 11) and using OpenCV (4.5.1) to do some image processing. I have a main window with 2 buttons in which one starts as greyed out as the first step must be completed before the second. I use the hide() QT function to hide the main window and pop up some gui elements using OpenCV. Once the OpenCV elements are finished and destroyed, I use show() to bring back the main window and ungrey the second button via setEnabled(true). This is where the problem occurs, as but buttons become unpressable on the screen, ie I cannot press the button on the touchscreen I am using.
Through testing I have found that when the loop that controls the OpenCV elements is allowed to end via the time expiring, then the problem does not occur. When the OpenCV elements are manually closed via sliding the "Set" slider from 0 to 1, then the problem occurs. The problem does not occur when using any of the other sliders
The buttons are still active however, as when I plug a keyboard in I can still operate the buttons and the code runs as usual, but I cannot press them using my finger or a mouse. Unfortunately having a keyboard to operate it isn't going to work for my use case.
The code for the loop that controls the OpenCV elements is:
void MainWindow::on_Button1_clicked()
hide();
//Code to load image is here, but is just the basic way of image loading with OpenCV
//Code to create the two OpenCV windows needed inside the loop goes here
time(&iTime);
while(OnOff == 0 && difftime(cTime,iTime) < 5){
createTrackbar(track_val, ControlPanel,&thresh_val,thresh_max_val); //binary gray value
createTrackbar(track_OnOff, ControlPanel,&OnOff,1); //video window on and off
createTrackbar(X_top_left, ControlPanel,&X,638); //bounding box top left X
createTrackbar(Y_top_left, ControlPanel,&Y,478); //bounding box top left Y
createTrackbar(X_size, ControlPanel,&Width,640); //bounding box width
createTrackbar(Y_size, ControlPanel,&Height,480); //bounding box height
createTrackbar(Max_Rad, ControlPanel,&max_rad,max_circ_rad); //Circle Size
imshow(ImageWin, img);
waitKey(1);
time(&cTime);
}
destroyAllWindows();
show();
}
I have uploaded all the code as a minimum reproducible example here.
Thanks for any help.
I was not able to find the cause of the issue however I was able to get around the issue. Using Yunus' advice, I removed the OpenCV gui components.
I used this code to create a method that opened the webcam so I could use OpenCV to process the image in the manner I needed.
So lesson learned, don't mix two different gui generators.

gtk image suddenly do not refresh without any errors or warnings

I develop a tool to capture image from a camera and show the captured image in a window. The GUI window is based on GTK 2.4. At begin, the tool is running correctedly, and the image is captured from camera and showed on the window in real-time. After a while, the image suddenly do not refresh any more on the window, but it's still captured from the camera. There is no errors or warnings. Anyone has ever encountered such a case? Thank you.
Ubuntu 18.04, GTK 2.4
// loop to call the following code to refresh the image on the window
pixbuf_ = Gdk::Pixbuf::create_from_data(
final_img_buf_.data, Gdk::COLORSPACE_RGB, false, 8, final_img_buf_.cols,
final_img_buf_.rows, static_cast<int>(final_img_buf_.step));
gtk_image_.set(pixbuf_);
Edit at 2019-02-27
Thanks for all your replies. I have upgraded GTK to GTK+ 3, but this still appears.
// loop to call the following code to refresh the image on the window
pixbuf_ = Gdk::Pixbuf::create_from_data(
final_img_buf_.data, Gdk::COLORSPACE_RGB, false, 8, final_img_buf_.cols,
final_img_buf_.rows, static_cast<int>(final_img_buf_.step));
// ensure the image is normally updating
//std::this_thread::sleep_for (std::chrono::milliseconds(30));
gtk_image_.set(pixbuf_);
Glib::RefPtr<Gdk::Pixbuf> pixbuf = gtk_image_.get_pixbuf();
std::string filename = std::string("./debug/") + std::to_string(CurTimestampMicrosecond()) + std::string(".jpg");
pixbuf->save(filename, "jpeg");
Afther running a while, the window does not refresh image any more, but the image is still saved correctedly.
Edit at 2019-02-28
// The initialization code
gtk_main_.reset(new Gtk::Main(argc, argv));
ctrl_window_.reset(new CtrlWindow(screen, ctrl_rect)); // inherited from Gtk::Window
thread_ = std::thread([this]() {
Gtk::Main::run(*ctrl_window_);
}
Looks like both g_timeout_add and possibly g_idle_add can be delayed due to the processing of other event sources, so is not optimal in contexts requiring precise timing, like drawing an image to a screen before the frame updates. I've noticed using g_timeout_add in a 2D graphics context completely freezes the application if it can't load a frame at the fps specified.
gtk_widget_add_callback() might be more suited to your needs as it will draw the buffer as quickly as the application can, without hangs, basically doing the messy synchronization for you.

OpenCV putText without a GUI thread, or named window?

I would like to put a UTF8 text using a specific font on my cv::Mat and I don't want to use OpenCV's GUI elements (windows). I compiled OpenCV 3.4.3 against Qt 5.11.1 and it works fine.
I understand that calling cv::addText function crashes duo to lack of GUI thread, in case no window is created by cv::namedWindow or cv::window. So I want to know if there is a way to somehow hide a previously created window, or even start GUI thread without actually having a window?

WIndows Flickering when changing focus in OpenGL

I'm working on a project that requires me to switch between two windows, one using OpenCV and one using OpenGL, both fullscreen.
A GLFW key event opens the OpenCV window fine, but closing the OpenCV window, and attempting to return focus to the OpenGL window results in the window flickering and repeatedly attempting to give focus. This is my code to return focus to the OpenGL window, inside a while loop.
Edit: Ive found out that it only happens when the OpenGL window is fullscreen, which is a requirement of this program. Writing to console shows that the code is being called multiple times
if(!glfwGetWindowAttrib(window, GLFW_FOCUSED))
{
glfwFocusWindow(window);
while(!glfwGetWindowAttrib(window, GLFW_FOCUSED))
{
}
}
I managed to fix my problem by setting the GLFW flag GLFW_AUTO_ICONIFY to false on my openGL window.
The way you posted is not the proper way to set focus.
Use glfwSetWindowCloseCallback to set a close callback.
In that callback is where you set focus to another window.

Menus don't overlay my OpenGL canvas after I open another frame on Mac only

I have an opengl canvas and lightweight menus set to false, and everything works fine. Then I open up a second frame from the first that has some 2D drawing etc. The menus over the openGL canvas in the first frame no longer draw where they overlap the canvas. This only happens on my mac, not on linux or windows. Any ideas?
It turns out that if you use the UIManager to set the look and feel, it must do something to the previous setting that turned off the lightweight menus (required for JOGL).