I am trying to use OpenCV in C++ on Ubuntu 22.04. By default, no window was appearing when imshow was called. This post is how I managed to solve my issue by using GTK and investigates a potential bug for Wayland, which was my default backend.
I decided to be a bit more sustainable with my dependencies, so I am trying to work with conan for the first time on Linux (have previously used on Windows). For my conan profile (below), conan didn’t find prebuilds, so it built from source. The conan profile, conanfile.py, and a minimal example project (CMakeLists.txt, main.cpp) are below.
As mentioned above, imshow would simply hang on window creation and never reach waitKey. I neither have extensive experience with building OpenCV or using conan, so fixing this problem took a long time. I am posting what I found here to save someone else the time, should they have a similar problem and if anyone can identify the cause of the behaviour and if it is a bug, where to file it (OpenCV, Conan center, …).
After a lot of trial and error, I permuted building OpenCV with different backends and setting the OPENCV_UI_BACKEND environment flags. OpenCV was build with from source with conan, by setting conan recipe options.
I found these resources helpful:
UI backend flags:
https://docs.opencv.org/4.x/d6/dea/tutorial_env_reference.html#autotoc_md957
OpenCV conan recipe (for “with_gtk”, etc. options list):
Behaviour:
The default appears to be with_qt=False, with_gtk=False and with_wayland=True. Default behaviour is no window shows, no matter what OPENCV_UI_BACKEND is set to out of GTK, GTK2, GTK3
(from cv::getBuildInformation() output):
GUI: Wayland
Wayland Client: YES (ver 1.22.0)
Wayland Cursor: YES (ver 1.22.0)
Xkbcommon: YES (ver 1.6.0)
Setting with_gtk=True and with_wayland=True. Still no window shows, no matter what OPENCV_UI_BACKEND is set to out of GTK, GTK2, GTK3.
GUI: Wayland
Wayland Client: YES (ver 1.22.0)
Wayland Cursor: YES (ver 1.22.0)
Xkbcommon: YES (ver 1.6.0)
GTK+: NO
Setting only with_gtk=True and the others False, now the imshow window shows.
GUI: GTK2
GTK+: YES (ver 2.24.33)
GThread : YES (ver 2.72.4)
GtkGlExt: NO
When I tried to build with Qt, I got a dependency conflict error during the conan build. As I don’t know conan that well, I didn’t want to start downgrading or pinning specific packages. In any case, it seems that Qt was not the default.
As an aside, using GTK, even though the window displayed from the terminal running and debugging with gdb, in VSCode, imshow threw an error in “debug”, even though it did when “launch” was used without the debugger (I lost the error code but it was to do with a system threading .so). I read that this could be due to the isolation of the VSCode as a snap installation, though I am confused why “launch” would run in this case. I removed the snap installation and installed the downloaded VSCode .deb with apt. Now both “debug” and “launch” work with GTK.
conan profile:
[settings]
arch=x86_64
build_type=Debug
compiler=gcc
compiler.cppstd=gnu20
compiler.libcxx=libstdc++11
compiler.version=11
os=Linux
conanfile.py:
from conan import ConanFile
from conan.tools.cmake import CMake, cmake_layout
class MyProject(ConanFile):
settings = "os", "compiler", "build_type", "arch"
generators = "CMakeToolchain", "CMakeDeps"
def requirements(self):
self.requires("opencv/4.9.0")
self.requires("eigen/3.4.0")
def configure(self):
self.options["opencv/*"].with_qt = False
self.options["opencv/*"].with_gtk = True
self.options["opencv/*"].with_wayland = False
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
def layout(self):
cmake_layout(self)
CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
set(PROJECT_NAME MyProject)
project(${PROJECT_NAME})
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
include(CTest)
enable_testing()
add_compile_options(-Wextra -Wpedantic -Wall)
find_package(Eigen3 REQUIRED)
find_package(OpenCV REQUIRED)
add_executable(${PROJECT_NAME} MyProject/main.cpp)
target_link_libraries(${PROJECT_NAME} PRIVATE Eigen3::Eigen ${OpenCV_LIBS})
main.cpp:
#include <opencv2/highgui.hpp>
#include <iostream>
int main()
{
std::cout << cv::getBuildInformation() << std::endl;
cv::Mat3b mat(100, 200, cv::Vec3b(0, 255, 255));
imshow("im", mat);
cv::waitKey();
std::cout << "End." << std::endl;
return 0;
}