CV01-OpenCV窗口手动关闭后堵塞程序运行的问题
OpenCV窗口手动关闭后堵塞程序运行的问题
问题描述
系统环境:Ubuntu 18.04
OpenCV版本:4.1.0
Python版本:3.7.3
当我们通过OpenCV的imshow()
方法显示图像后,我们会使用waitKey()
方法保持窗口存在来展示图像。
此时我们能够获取用户的按键来关闭窗口,该方法的实现为:
import cv2 as cv
img = cv.imread(img_dir)
cv.imshow('img',img)
if cv.waitKey(0) == 27: # wait for ESC
cv.destroyWindow('img')
此时程序会堵塞并且一直等待用户在图片窗口按下ESC
键。
而当我们通过图像窗口的关闭按钮关闭图像后,程序依然被堵塞,而此时我们所期望的是程序能够继续运行下去,因此我们需要检测图像窗口是否被关闭。
解决方法
我们不再使用waitKey(0)
来显示图像,转而通过循环来保持图像的展示,同时检测:
- 用户是否按下指定按键
- 窗口是否被关闭
我们通过获取窗口的WND_PROP_VISIBLE
属性来判断窗口是否存在,使用到的方法为:cv.getWindowProperty(win_name,prop_id)
,该方法能够获取到的窗口属性都有:
//! Flags for cv::setWindowProperty cv::getWindowProperty
enum WindowPropertyFlags {
WND_PROP_FULLSCREEN = 0, //!< 全屏(can be WINDOW_NORMAL or WINDOW_FULLSCREEN).
WND_PROP_AUTOSIZE = 1, //!<自动大小(can be WINDOW_NORMAL or WINDOW_AUTOSIZE).
WND_PROP_ASPECT_RATIO = 2, //!< 保持纵横比(can be set to WINDOW_FREERATIO or WINDOW_KEEPRATIO).
WND_PROP_OPENGL = 3, //!< opengl窗口.
WND_PROP_VISIBLE = 4 //!< 检测窗口是否存在并且是否可见
};
综合起来的实现为:
import cv2 as cv
img = cv.imread(img_dir)
cv.imshow('img',img)
while cv.waitKey(100) != 27:# loop if not get ESC
if cv.getWindowProperty('img',cv.WND_PROP_VISIBLE) <= 0:
break
cv.destroyWindow('img')
此举能够在手动关闭窗口后保持程序的正常运行不堵塞。
封装
我将该功能封装成为了一个方法showImage()
,代码如下:
def showImage(img, title='image', t=1000, esc=False):
cv.imshow(title, img)
if esc:
while cv.waitKey(100) != 27:
if cv.getWindowProperty(title,cv.WND_PROP_VISIBLE)<=0:
break
else:
cv.waitKey(t)
cv.destroyWindow(title)
该方法实现的功能为,当esc
属性为False
的时候,窗口显示t
ms自动关闭;而当esc
为True
的时候,我们会检测窗口是否存在和是否按下ESC
键,若手动关闭了窗口或按下ESC
键关闭窗口,程序将继续运行。