OpenCV Python:如何检测窗口是否关闭?

时间:2016-01-25 22:17:12

标签: python opencv

我有以下代码:

total_frames = 50
cv2.cv.NamedWindow("Dragonfly Simulation")
cv2.cv.StartWindowThread()
for i in range(total_frames):
    # do stuff
    img_name = # something
    img = cv2.cv.LoadImage(img_name)
    cv2.cv.ShowImage("Dragonfly Simulation", img)
    cv2.cv.WaitKey(2)
cv2.cv.DestroyWindow("Dragonfly Simulation")
cv2.cv.WaitKey(1)
# rest of code

那它做了什么:

  1. 打开一个窗口
  2. 在循环中,在窗口上显示图像
  3. 完成后,关闭窗口
  4. 运行其余代码
  5. 但是在这种情况下,我之前给出了total_frame。我不想要那个。

    相反,我想要一个执行以下操作的代码:

    1. 打开一个窗口
    2. 在循环中,在窗口上显示图像
    3. 等待用户关闭该窗口
    4. 当用户关闭该窗口时,退出循环,继续执行其余代码。
    5. 但是,我在OpenCV中找不到可以检测用户何时关闭窗口的函数。有人可以建议一个解决方法吗?

7 个答案:

答案 0 :(得分:27)

我正在寻找一种方法来检测窗口何时关闭,除了等待按键按下窗口的X按钮,但我无法在任何地方找到答案({{ 1}}和IsWindowVisible在Python cvGetWindowHandle模块中不可用。)

所以我玩了,这就是它的工作原理:

cv2
窗口关闭后,

while cv2.getWindowProperty('window-name', 0) >= 0: keyCode = cv2.waitKey(50) # ... 会立即返回cv2.getWindowProperty()

有关解释,请参阅cv::WindowPropertyFlags枚举的文档:获取索引为-1的标志是全屏属性,但实际上使用哪个标志并不重要,它们都变为{窗口关闭后立即{1}}。

答案 1 :(得分:12)

从版本2.2开始,有一个简单的解决方案(这是从hist.py中的循环中修改的):

    cv2.imshow('image',im)
    while True:
        k = cv2.waitKey(100) # change the value from the original 0 (wait forever) to something appropriate
...
        elif k == 27:
            print('ESC')
            cv2.destroyAllWindows()
            break        
        if cv2.getWindowProperty('image',cv2.WND_PROP_VISIBLE) < 1:        
            break        
    cv2.destroyAllWindows()

答案 2 :(得分:2)

        if cv2.getWindowProperty('windowname',1) == -1 :
            break
        cv2.imshow('windowname', image)

答案 3 :(得分:2)

我使用getWindowProperty(&#39; image&#39;,WND_PROP_VISIBLE)在C ++上测试过,但它不起作用。所以我使用了WND_PROP_AUTOSIZE并且它可以工作。

我确实喜欢这个:

cv::namedWindow("myTitle", WINDOW_AUTOSIZE);

while(1)
{
    cv::imshow("myTitle", myImage);


    if (cv::getWindowProperty("myTitle", WND_PROP_AUTOSIZE) == -1)
        break;
}

答案 4 :(得分:1)

waitKey

当然,您可以使用setScale检查用户输入,这是一个基于您的代码的小例子。我将旧的cv界面改为cv2。我认为cv已经过时了。

(编辑)我将cv2.destroyAllWindows()移动到while循环内部,以便在用户按下ESC键(可以指定您选择的键)时清除该窗口。我不认为opencv有一个适当的事件处理程序来捕获窗口关闭事件,就像在其他GUI工具包(wxPython等)中一样。因此,您需要定义用户应关闭窗口的方式并注意这一点。

答案 5 :(得分:0)

我使用以下代码t检查是否按下了一个键或同时关闭了窗口。

    while cv2.getWindowProperty(camera.get_name(), cv2.WND_PROP_VISIBLE) > 0:
        if cv2.waitKey(100) > 0:
            break

    cv2.destroyAllWindows()

答案 6 :(得分:0)

我根据这篇文章做了一个简单的函数。它适用于 opencv 4.5.2

def wait_with_check_closing(win_name):
    """ 
        https://stackoverflow.com/questions/35003476/"
        "opencv-python-how-to-detect-if-a-window-is-closed/37881722
    """
    while True:
        keyCode = cv2.waitKey(50)
        if keyCode != -1:
            break
        win_prop = cv2.getWindowProperty(win_name, cv2.WND_PROP_VISIBLE)
        if win_prop <= 0:
            break


它可以代替 cv2.waitKey(0) 使用,如下例所示。

# Usage
cv2.imshow(title, img_resized)
# cv2.waitKey(0)
wait_with_check_closing(title)
cv2.destroyAllWindows()