简体   繁体   中英

Strange cv2 behavior with imshow

I'm using Python 3.8.2 on Kubuntu 20.04.

cv2 is the latest available version, as are NumPy and pip:

Requirement already up-to-date: pip in /usr/local/lib/python3.8/dist-packages (20.1.1)
Requirement already up-to-date: opencv-contrib-python in /usr/local/lib/python3.8/dist-packages (4.3.0.36)
Requirement already satisfied, skipping upgrade: numpy>=1.17.3 in /usr/local/lib/python3.8/dist-packages (from opencv-contrib-python) (1.19.1)
Requirement already up-to-date: numpy in /usr/local/lib/python3.8/dist-packages (1.19.1)

Here is my code:

import numpy as np
import cv2

black_image = np.zeros((480, 640, 3))
cv2.imshow("Test", black_image)
cv2.waitKey()

white_image = np.ones((480, 640, 3))
cv2.imshow("Test", white_image)
cv2.waitKey()

This simple test program, when run in IDLE, sometimes displays a small black image (95x25) instead of the 640x480 black image I passed to imshow . Other times, it will display the proper image. In either case, when this window is closed, OpenCV blocks forever instead of displaying the second image and I have to close the process via the IDLE shell window.

When run in the terminal, the results are the same: sometimes a weird small image of size 95x25, and OpenCV blocks before opening the second window resulting in me having to kill the process (Ctrl+C does nothing, and sending SIGTERM doesn't work either).

I have tried:

Passing 0 to cv2.imshow() . Same results.

Passing 1 to cv2.imshow() . This actually displays the white image as intended, but the black image (or its weird 95x25 substitute) is also displayed. As I understand it, cv2.imshow() is supposed to replace the contents of the already opened window if one exists with the same name.

I remember OpenCV working fine with Python 3.7 and below, although I can't test with that as those versions are no longer installable on my version of Ubuntu.

Both results are reproducible on my machine, but no code change is necessary to switch between them. What's going on here, and how do I fix it?

EDIT: Also tried closing windows (by name and through cv2.destroyAllWindows() ) and waiting for specific key presses. The main problem persists: images are not being displayed consistently and OpenCV will sometimes hang forever. Normal programs and other code I've pasted do not work properly.

EDIT 2: Now attached are screenshots of my problem

The first weird window: 第一个奇怪的窗口

IDLE hanging with no OpenCV window open after closing the first one: 关闭第一个窗口后,IDLE 挂起,没有打开 OpenCV 窗口

Konsole (my terminal emulator) also hanging after closing the first window: Konsole(我的终端模拟器)在关闭第一个窗口后也挂起

Ctrl-C not working to end Python in the terminal: Ctrl-C 不会停止进程

I can also provide video proof if needed.

I think you are facing two problems:

  1. the code sometimes displays the black image in a wrong size.
  2. When it does, the run stucks here.

The problem of 2 is that cv2.imshow accepts (by default) key events of closing the window (ie closing the window via x sign will lead to being stuck in the wait step forever).

As a solution for this, you can add an if statement to close the window if a key is pressed and to tell the program explicitly that if the x sign/button is pressed to close the window. Thus, you can write something like the following:

import numpy as np
import cv2

black_image = np.zeros((480, 640, 3))
white_image = np.ones((480, 640, 3))

images = [black_image, white_image]

for image in images:   
    while True:
        cv2.imshow('Frame', image)
        if cv2.waitKey(1) & 0xFF == 27 or cv2.getWindowProperty("Frame", 0) == -1: # "0xFF == 27" for Esc-key in Windows
            break
cv2.destroyAllWindows()

After an updated version of Python (3.8.5 specifically) was released, I updated Python, pip, and PyOpenCV. Everything works as intended now, confirming my suspicions that this was an obscure bug not directly caused by my code.

Updated packages:

Requirement already satisfied: pip in ./.local/lib/python3.8/site-packages (20.3.3)
Requirement already satisfied: opencv-contrib-python in /usr/local/lib/python3.8/dist-packages (4.4.0.46)
Requirement already satisfied: numpy>=1.17.3 in /usr/local/lib/python3.8/dist-packages (from opencv-contrib-python) (1.19.1)

Maybe this can help someone with outdated packages experiencing the same issues in the future.

You can either use cv2.destroyWindow("Test") or cv2.destroyAllWindows() to properly close windows.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM