imshow产生奇怪的cv2行为

时间:2020-07-26 19:26:17

标签: python python-3.x numpy opencv

我正在Kubuntu 20.04上使用Python 3.8.2。

cv2是最新的可用版本,NumPy和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)

这是我的代码:

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()

这个简单的测试程序在IDLE中运行时,有时会显示一个小的黑色图像(95x25),而不是我传递给imshow的640x480黑色图像。其他时间,它将显示正确的图像。无论哪种情况,当关闭此窗口时,OpenCV都会永远阻塞而不显示第二个图像,而我必须通过IDLE shell窗口关闭该过程。

在终端中运行时,结果是相同的:有时,一个大小为95x25的奇怪的小图像,在打开第二个窗口之前会被OpenCV阻塞,导致我不得不终止进程(Ctrl + C不执行任何操作,并发送{ {1}}也不起作用。

我尝试过:

将0传递给SIGTERM。结果相同。

将1传递到cv2.imshow()。实际上,这将按预期显示白色图像,但是也会显示黑色图像(或其怪异的95x25替代品)。据我了解,cv2.imshow()应该替换已经打开的窗口的内容(如果存在一个具有相同名称的窗口)。

我记得OpenCV可以在Python 3.7及以下版本上正常工作,尽管我无法对其进行测试,因为这些版本不再可以在我的Ubuntu版本上安装。

这两个结果在我的机器上都是可重现的,但是无需更改代码即可在它们之间进行切换。这是怎么回事,我该如何解决?

编辑:还尝试关闭窗口(按名称和通过cv2.imshow())并等待特定的按键。主要问题仍然存在:图像无法始终显示,并且OpenCV有时会永远挂起。 我粘贴的普通程序和其他代码无法正常工作。

编辑2:现在附上我的问题的屏幕截图

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

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

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

Ctrl-C无法在终端中终止Python: Ctrl-C doesn't stop the process

如果需要,我还可以提供视频证明。

3 个答案:

答案 0 :(得分:0)

我认为您面临两个问题:

  1. 代码有时会以错误的尺寸显示黑色图像。
  2. 运行时,运行卡在此处。

2的问题是cv2.imshow(默认情况下)接受关闭窗口的键事件(即,通过x符号关闭窗口将导致永远停留在等待步骤中)。

作为解决方案,可以添加if语句以在按下键时关闭窗口,并明确告知程序是否按下x符号/按钮以关闭窗口。因此,您可以编写如下内容:

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()

答案 1 :(得分:0)

发布了Python的更新版本(特别是3.8.5)之后,我更新了Python,pip和PyOpenCV。现在一切都按预期工作,证实了我的怀疑,这是一个晦涩的bug,并非直接由我的代码引起。

更新的软件包:

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)

也许这可以帮助那些过时的软件包的人将来遇到同样的问题。

答案 2 :(得分:-1)

您可以使用cv2.destroyWindow("Test")cv2.destroyAllWindows()来正确关闭窗口。

相关问题