David C.
David C.

Reputation: 1001

Python OpenCV on Raspberry Pi detect window closing

I have a Python application using OpenCV to produce a simple display window. Using the following code fragment (from an interactive Python shell):

>>> import cv2
>>> image = cv2.imread("pic.jpg")
>>> image.shape
(653,551,3)
>>> cv2.namedWindow("foo")
>>> cv2.resizeWindow("foo", 300, 300)
>>> cv2.imshow("foo", image)
>>> cv2.getWindowProperty("foo", cv2.WND_PROP_VISIBLE)
1.0
>>> cv2.waitKey(1000)
-1
>>> cv2.getWindowProperty("foo", cv2.WND_PROP_VISIBLE)
1.0
>>> cv2.waitKey(1000)
-1
>>> cv2.getWindowProperty("foo", cv2.WND_PROP_VISIBLE)
0.0

When I run this from a Linux desktop system (Xubuntu 18.04 LTS, Python 3.6.9, cv2 version 4.5.1), I see a window appear on screen immediately after calling cv2.namedWindow and the VISIBLE property is immediately true, even before I call waitKey. After the waitKey call, I see the window resize and the image is visible.

When I click the window's close box (after the second call to getWindowProperty) and then call waitKey, the window closes and the VISIBLE property is now 0.

This is all good, since I haven't actually destroyed the window yet.

When I try the same thing on a Raspberry Pi (Raspbian/Debian version 10.8, Python 3.7.3, cv2 version 4.5.1) however, the VISIBLE property always returns -1.0, both before the window appears (with the first waitKey call), while it is visible, and after it closes (after the second waitKey call).

If I look at other window properties on the Pi, I find that properties 0, 1 and 2 (FULLSCREEN, AUTOSIZE and ASPECT_RATIO) give me valid values until the window is closed, with all the other properties (including VISIBLE) returning -1 at all times. After the window closes, 0 throws an exception and the other properties return -1.0.

More interesting is that on the Ubuntu/Xfce desktop, properties 0-3 don't change when the window is open or closed, so checking them definitely won't work on that platform.

What is going on here? Why does my desktop environment behave so much differently?

Is it a function of the window manager (Xfce vs. Lxde)? Are there missing packages on the Pi that I could add to change the behavior (I got no messages about cv2 failing to load anything)?

And what's a good solution? Change my code to check for a window-close in a different way? Use a different property (1 or 2) as a workaround and forget the problem? Something else?

Upvotes: 2

Views: 452

Answers (1)

David C.
David C.

Reputation: 1001

I'm quickly coming to the conclusion that this must be a bug in the Raspberry Pi build of OpenCV. Here's a workaround I'm currently using that seems to do what I want on both the Pi and on a Desktop Linux system:

if ((cv2.getWindowProperty("foo", cv2.WND_PROP_VISIBLE) == 0)
    or
    (cv2.getWindowProperty("foo", cv2.WND_PROP_ASPECT_RATIO) < 0)):
   # The window is closed - do something here

In this workaround, I check two properties. On a both platforms, when the window is open, the VISIBLE property is non-zero (-1 on Raspberry Pi or 1 on desktop Linux) and the ASPECT_RATIO property is > 0.

When the window is closed, the VISIBLE property becomes zero on desktop Linux systems and the ASPECT_RATIO becomes -1 on Raspberry Pi.

It's a workaround, not a solution, but it works (at least for the moment).

Upvotes: 1

Related Questions