Home > Mobile >  using multiple waitKey() in an if-elif test, second key test always fails, even when that key is pre
using multiple waitKey() in an if-elif test, second key test always fails, even when that key is pre

Time:01-19

I made a simple code to take snapshots from my webcam when prompted by pressing 's', and quit if I pressed 'q'. Code runs fine but the elif statement for the quitting part alone is ignored.

import cv2

cap = cv2.VideoCapture(0)
counter = 0

while(True):
    ret, frame = cap.read()
    cv2.imshow('Webcam', frame)
    if  (cv2.waitKey(1) & 0xFF) == ord('s'):
        print("s working")
        counter = counter   1
        cv2.imwrite("Snapshot_"   str(counter)   ".png", frame)
    elif (cv2.waitKey(1) & 0xFF) == ord('q'):
        print("q working")
        break
cap.release()
cv2.destroyAllWindows()

I also tried swapping their order, the if statement being the 'q' condition and the elif being 's', the second statement is always the one skipped. Update: it only works if I hold q for a while Why isn't it working normally?

CodePudding user response:

As I learned from the comments, the problem was caused by the waitKey delay. So to fix it I put the pressed button in a variable and compared the condition statements to that variable instead.

import cv2

cap = cv2.VideoCapture(0)
counter = 0

while(True):
    ret, frame = cap.read()
    cv2.imshow('Webcam', frame)
    k = cv2.waitKey(1) & 0xFF
    if  k == ord('s'):
        print("s working")
        counter = counter   1
        cv2.imwrite("Screenshot_"   str(counter)   ".png", frame)
    elif k == ord('q'):
        print("q working")
        break
cap.release()
cv2.destroyAllWindows()

CodePudding user response:

The issue is not caused by any delays, nor by any blocking.

After cap.read() returns a new frame, there may be key events waiting because you pressed some keys.

Each waitKey() consumes one key press event and returns it, if there was a key event.

If you pressed a key, the first waitKey() receives that event, and if it was the wrong key, the if doesn't run its consequent code.

Then, the second waitKey() has no key event to handle, so it returns -1.

If you held the key down, you might have had a chance to create enough key press events to get one of them into the second waitKey().

The proper solution is to call waitKey() once per loop, and store its returned value in a variable.

Then you test that variable against as many key codes as you like.

while True:
    ...
    keycode = cv.waitKey()
    if keycode == ord('s'):
        ...
    elif keycode == ord('q'):
        ...

That &0xFF stuff is superfluous and outdated since 2016. waitKey() does that already. It is superfluous.

  • Related