【问题标题】:Strange cv2 behavior with imshowimshow 的奇怪 cv2 行为
【发布时间】:2020-11-16 03:46:43
【问题描述】:

我在 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 什么都不做,并发送 @ 987654332@ 也不起作用)。

我试过了:

将 0 传递给 cv2.imshow()。结果相同。

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

我记得 OpenCV 在 Python 3.7 及更低版本上运行良好,但我无法对其进行测试,因为这些版本不再可安装在我的 Ubuntu 版本上。

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

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

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

第一个奇怪的窗口:

关闭第一个窗口后,IDLE 挂起,没有打开 OpenCV 窗口:

Konsole(我的终端模拟器)在关闭第一个窗口后也挂起:

Ctrl-C 无法在终端中结束 Python:

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

【问题讨论】:

  • 使用cv2的时候,别忘了在最后写:cv2.destroyAllWindows()。
  • 感谢您的提示,尽管在 Python 3.8 之前我似乎不必使用它。
  • 通过按键(q 或 esc)关闭窗口/imshow 时,您不会遇到问题,对吧?
  • 程序执行永远不会到达那里。 cv2 在 waitKey 期间阻塞某处。
  • 我在答案中提供的解决方案怎么样?

标签: python python-3.x numpy opencv


【解决方案1】:

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

【讨论】:

  • 关闭窗口不是我的问题,尽管下次我让它工作时我会记得这样做。根据文档,OpenCV 的行为不正常。它在不打开窗口的情况下无限期阻塞,并且有时会显示错误的图像。
【解决方案2】:

我认为你面临两个问题:

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

【讨论】:

    【解决方案3】:

    在 Python 的更新版本(特别是 3.8.5)发布后,我更新了 Python、pip 和 PyOpenCV。现在一切都按预期工作,证实了我的怀疑,即这是一个不直接由我的代码引起的模糊错误。

    更新包:

    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)
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 2012-04-12
      • 2017-12-04
      • 2020-01-22
      • 1970-01-01
      • 2022-01-01
      相关资源
      最近更新 更多