GUI not showing/hangs on imshow with Wayland backend (Ubuntu 22.04)

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

I’m surprised that OpenCV even has a backend to use Wayland. I think that’s probably a new addition and perhaps only intended for specific environments where a DE was never meant to run. I’m also surprised that it seems to take precedence over GTK, when both are enabled for the build.

In your place I’d browse PRs and issues (also closed ones) on opencv’s github that mention wayland.