【问题标题】:OpenCV Python: How to detect if a window is closed?OpenCV Python:如何检测窗口是否关闭?
【发布时间】:2016-05-02 09:42:15
【问题描述】:

我有以下代码:

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. 运行其余代码

但是在这种情况下,我之前给出了total_frame。我不想那样。

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

  1. 打开一个窗口
  2. 在循环中,在窗口上显示图像
  3. 等待用户关闭该窗口
  4. 当用户关闭该窗口时,退出循环,继续执行其余代码。

但是,我在 OpenCV 中找不到可以检测用户何时关闭窗口的函数。有人可以提出解决方法吗?

【问题讨论】:

  • 也许你可以捕捉到一些异常?例如尝试访问窗口,如果它因 NoWindowExistsException/NullPointerException 而失败,则使用您的代码。
  • @joto umm,对不起,我是 OpenCV 的新手,如何检查异常?使用我当前的代码,如果我关闭窗口,代码就会停止。另外,来自 ShowImage 的手册:“如果在此函数之前未创建窗口,则假定使用 CV_WINDOW_AUTOSIZE 创建窗口”
  • 我对 OpenCV 一点也不熟悉。我只是认为关闭窗口后该实例将保留。也许这就是你要找的?要全局存储一些 cv 引用,以便无论 Window 是否关闭都可以访问它?我只是猜测。
  • @joto umm 我正在对神经元模拟进行建模,因此我想根据用户的需要运行模拟(而不是指定的持续时间或帧数)。因此想要检测用户何时关闭此类窗口。我想或者我可以检测到键盘按下?不完全确定如何做到这一点......
  • 你能在循环过程中关闭窗口吗?

标签: python opencv


【解决方案1】:
import cv2
import numpy as np

# total_frames = 50
cv2.namedWindow("Dragonfly Simulation")
cv2.startWindowThread()
# for i in range(total_frames):
while True:
    # do stuff
    img = np.random.randint(0,255,(200,300)).astype(np.uint8)
    cv2.imshow("Dragonfly Simulation", img)
    key = cv2.waitKey(200)
    print key
    if key in [ord('a'), 1048673]:
        print 'a pressed!'
    elif key in [27, 1048603]: # ESC key to abort, close window
        cv2.destroyAllWindows()
        break

# do the rest of processing after break 
print 'results:'

当然,您可以使用waitKey 检查用户输入,这里有一个基于您的代码的小示例。我将旧的 cv 接口更改为 cv2。我认为 cv 已经过时了。

(编辑)我将 cv2.destroyAllWindows() 移到 while 循环内部,以清楚地表明当用户按下 ESC 键(您可以分配您选择的键)时窗口关闭。我认为 opencv 没有像其他 GUI 工具包(wxPython 等)那样有适当的事件处理程序来捕获窗口关闭事件。因此,您需要定义用户应如何关闭窗口并注意这一点。

【讨论】:

  • @dessskris,这是我想让你建议的事情
【解决方案2】:

除了等待按键之外,我只是在寻找一种方法来检测窗口何时关闭,使用窗口的X 按钮,但我在任何地方都找不到答案(IsWindowVisiblecvGetWindowHandle 在 Python cv2 模块中不可用)。

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

while cv2.getWindowProperty('window-name', 0) >= 0:
    keyCode = cv2.waitKey(50)
    # ...

cv2.getWindowProperty() 在窗口关闭后立即返回-1


解释见cv::WindowPropertyFlags的枚举文档:获取索引为0的flag是全屏属性,但其实用哪个flag都无所谓,一会都变成-1因为窗口关闭了。


注意:这可能仅适用于某些 GUI 后端。值得注意的是,它不适用于 Debian/Ubuntu 软件包中使用的 GTK 后端。要改用 Qt 后端,您必须通过 pip 安装 opencv-python

【讨论】:

  • 是的,您的解决方案有效,但不幸的是写入标准错误“OpenCV 错误:cvGetModeWindow_GTK 中的空指针(NULL 窗口),文件 /build/opencv-SviWsf/opencv-2.4.9.1+dfsg/modules/highgui /src/window_gtk.cpp,第 555 行"
  • @VladyslavSavchenko 在 Python 或 C++ 中?我在 Python 中没有收到任何错误,而且我使用了 OpenCV 3.1 版...您可以尝试将其包装在 try/catch 中并在 catch 语句中退出。
  • 是的,在 Python 中,try..catch 无济于事,因为 opencv 写入 stderr 而不是抛出任何 python 异常(但不关心它,我已经在 wx 上重写了它: ))。感谢您的帮助!
  • 您使用的是哪个操作系统?我无法让它在 Ubuntu 上运行; getWindowProperty 始终返回 0.0,即使窗口已关闭。
  • 这对我不起作用,因为 >= 捕获窗口不可见状态。我用这个:python while cv2.getWindowProperty(name, cv2.WND_PROP_VISIBLE) > 0: keyCode = cv2.waitKey(50) else: print('break')
【解决方案3】:

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

【讨论】:

    【解决方案4】:
            if cv2.getWindowProperty('windowname',1) == -1 :
                break
            cv2.imshow('windowname', image)
    

    【讨论】:

    • 您的答案只是代码,尝试添加对文档的引用或解释它的作用。虽然有时您需要回答核心问题的只是一些代码,但您可以提供的越详细越好。
    【解决方案5】:

    我使用 getWindowProperty('image', 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;
    }
    

    【讨论】:

    • 也可以在 python 中工作:cv2.imshow("image", image) if cv2.getWindowProperty('image',1) &lt; 0: break 其中cv2.getWindowProperty(&lt;windowName&gt;, 1) 指的是自动大小标志。 [docs.opencv.org/3.1.0/d7/dfc/…
    【解决方案6】:

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

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

    【讨论】:

      【解决方案7】:

      我根据这篇文章做了一个简单的函数。它适用于 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()
      

      【讨论】:

        猜你喜欢
        • 2012-03-08
        • 2021-05-31
        • 1970-01-01
        • 1970-01-01
        • 2017-09-14
        • 2014-10-23
        • 1970-01-01
        • 1970-01-01
        • 2021-11-19
        相关资源
        最近更新 更多