Hello!
In my project I need to control the movement of the drone with the WASD keys. If I press them once, everything looks fine: the command is sent to the drone and it moves correctly, the video stream goes well. But if I hold down any button on the keyboard, the drone will move correctly, but the video will stop until I release the button.
So, I tried this without the drone, just with VideoCapture and my webcam, and I had the same results, but instead of the video stream stopping completely, I had a huge FPS drop.
I then tried using another library to capture keyboard events (module “keyboard”) and got similar results.
My question is, why is this happening and what can I do to solve this problem, because sometimes I need to hold down the key?
post a minimal reproducible example please.
import cv2
from keyboard import is_pressed as key
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
cv2.imshow("frame", frame)
key = cv2.waitKey(1)
if key == ord('q'):
break
cv2.destroyAllWindows()
cap.release()
ah yes, I can reproduce the issue on win32.
what OS/GUI toolkit do you run this on?
my best guess is that the event processing sees the keyboard event and stops there, before handling any drawing events, which may come before or after a keyboard event.
cheap workaround: run waitKey(), but repeat if there was a key code returned (stop if there wasn’t).
import cv2
cap = cv2.VideoCapture(0)
assert cap.isOpened()
while True:
ret, frame = cap.read()
if not ret: break
cv2.imshow("frame", frame)
do_stop = False
while True:
key = cv2.waitKey(1)
if key == -1: # no keycode reported
break # inner loop
if key == ord('q'):
do_stop = True # break outer loop
# don't break inner loop yet, we'll do that in the next iteration when no keycode is reported
if do_stop:
break
cv2.destroyAllWindows()
cap.release()
it might be possible, for some GUI toolkits, to fix this inside of waitKey().
Thank you very much!
what OS/GUI toolkit do you run this on?
This program runs on my notebook with OS Win10
good to know. I was curious to see if this happened on non-Windows as well.
I’ve investigated the code in window_w32.cpp
some more. it’s possible to process non-key events first but it’s messy in some instances. Windows API knows PeekMessage and GetMessage. PeekMessage can exclude input events or it could be used to process just until a key event is found. PeekMessage is used in some situations, but GetMessage in others. GetMessage can’t exclude input events, it can only select ranges to include, which isn’t good enough. implementing a fix/improvement for the situation in there would require careful planning and documentation of the code.