web-dev-qa-db-ja.com

OpenCV Python:ウィンドウが閉じているかどうかを検出する方法は?

私は次のコードを持っています:

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の関数が見つかりません。誰かが回避策を提案できますか?

14
dessskris

キーが押されるのを待つだけでなく、ウィンドウのXボタンを使用してウィンドウが閉じられたことを検出する方法を探していましたが、どこにも答えが見つかりませんでした(IsWindowVisibleおよびcvGetWindowHandleは、Python _cv2_モジュール)では使用できません。

だから私は遊んで、これはそれがどのように機能するかです:

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

cv2.getWindowProperty()は、ウィンドウが閉じられるとすぐに_-1_を返します。


説明については、ドキュメントの _cv::WindowPropertyFlags_ の列挙を参照してください。インデックス_0_でフラグを取得することはフルスクリーンプロパティですが、実際にはどのフラグを使用するかは問題ではありません。ウィンドウが閉じられると、それらはすべて_-1_になります。

33
Simon Hänisch

バージョン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()
17
David Kohen

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;
}
3
Derzu
        if cv2.getWindowProperty('windowname',1) == -1 :
            break
        cv2.imshow('windowname', image)
2
stephen george
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キー(選択したキーを割り当てることができる)を押したときにウィンドウが閉じることを明確にしました。他のGUIツールキット(wxPythonなど)のように、opencvにウィンドウのクローズイベントをキャッチする適切なイベントハンドラーがないと思います。したがって、ユーザーがウィンドウを閉じる方法と、それを監視する方法を定義する必要があります。

1
otterb