Reputation: 575
I have the following code:
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
So what does it do:
However in this case I have the total_frame
given before. I don't want that.
Instead, I want a code that does the following:
However, I cannot find a function in OpenCV that can detect when user closes a window. Can anyone suggest a workaround please?
Upvotes: 37
Views: 54694
Reputation: 836
@David Kohen's answer is working great for me. But if you have many images to show its better to convert it to a function
def waitUntilX(window):
while True:
k = cv2.waitKey(100) # change the value from the original 0 (wait forever) to something appropriate
if k == 27:
print('ESC')
cv2.destroyAllWindows()
break
if cv2.getWindowProperty(window,cv2.WND_PROP_VISIBLE) < 1:
break
cv2.destroyAllWindows()
Usage
invertedmask = cv2.bitwise_not(mask)
cv2.imshow('inverted mask', invertedmask)
waitUntilX('inverted mask')
Upvotes: 0
Reputation: 961
https://www.programcreek.com/python/example/110676/cv2.WND_PROP_VISIBLE
For my scenario, it had to be the following. I had to call k = cv2.waitKey(1) & 0xFF
before checking status of the window for it to work
def show_webcam(mirror=False):
cam = cv2.VideoCapture(0)
# cv2.startWindowThread()
window_name="A_star webcam"
while True:
ret_val, img = cam.read()
if mirror:
img = cv2.flip(img, 1)
cv2.imshow(window_name, img)
k = cv2.waitKey(1) & 0xFF
if not (cv2.getWindowProperty(window_name,cv2.WND_PROP_VISIBLE)):
break
if cv2.waitKey(1) == 27:
break # esc to quit
cv2.destroyAllWindows()
The libraries installed are
autopep8==1.6.0
numpy==1.22.1
opencv-python==4.5.5.62
pycodestyle==2.8.0
toml==0.10.2
Upvotes: 0
Reputation: 4968
I was just looking for a way to detect when the window has been closed using the X
button of the window in addition to waiting for a key press, but I couldn't find an answer anywhere (IsWindowVisible
and cvGetWindowHandle
are not available in the Python cv2
module).
So I played around and this is how it works:
while cv2.getWindowProperty('window-name', 0) >= 0:
keyCode = cv2.waitKey(50)
# ...
cv2.getWindowProperty()
returns -1
as soon as the window is closed.
For explanation, see the documentation for the enumeration of cv::WindowPropertyFlags
: getting the flag with index 0
is the fullscreen property, but actually it doesn't matter which flag to use, they all become -1
as soon as the window is closed.
Note: This might only work for certain GUI backends. Notably, it will not work with the GTK backend used in Debian/Ubuntu packages. To use the Qt backend instead, you have to install opencv-python
via pip.
Upvotes: 54
Reputation: 699
I made a simple function based on this post. It works in 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
It can be used instead of cv2.waitKey(0) like following example.
# Usage
cv2.imshow(title, img_resized)
# cv2.waitKey(0)
wait_with_check_closing(title)
cv2.destroyAllWindows()
Upvotes: 1
Reputation: 714
I used the following code t check if a key is pressed or the window is closed at the same time.
while cv2.getWindowProperty(camera.get_name(), cv2.WND_PROP_VISIBLE) > 0:
if cv2.waitKey(100) > 0:
break
cv2.destroyAllWindows()
Upvotes: 4
Reputation: 7146
I tested on C++ using the getWindowProperty('image', WND_PROP_VISIBLE), but it does not work. So I used the WND_PROP_AUTOSIZE and it works.
I did like this:
cv::namedWindow("myTitle", WINDOW_AUTOSIZE);
while(1)
{
cv::imshow("myTitle", myImage);
if (cv::getWindowProperty("myTitle", WND_PROP_AUTOSIZE) == -1)
break;
}
Upvotes: 7
Reputation: 49
if cv2.getWindowProperty('windowname',1) == -1 :
break
cv2.imshow('windowname', image)
Upvotes: 4
Reputation: 471
As of version 2.2 there is a simple solution (this is modified from the loop in 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()
Upvotes: 37
Reputation: 2710
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:'
Sure, you can check user inputs using waitKey
and here is a small example based on your code. I changed old cv interface to cv2. I think cv is obsolete.
(Edit) I moved cv2.destroyAllWindows() to inside the while loop to make it clear that the window closes when the user pressed ESC key (which you can assign a key of your choice). I do not think opencv has a proper event handler to catch the window close event like in other GUI toolkit (wxPython etc). So you will need to define how your users should close the window and watch out for that.
Upvotes: 2