user1245262
user1245262

Reputation: 7505

How should I properly use cv2.waitKey when wanting to start/pause a video?

I've written a small script that allows be to run/pause a video stream using OpenCV. I don't understand why I needed to use the cv2.waitkey() in the manner I did. The structure of my code is as follows:

def marker(event, x, y, flags, param):
    # Method called by mouse click
    global run

    if event == cv2.EVENT_LBUTTONDOWN:
        run = not run


...

window_name = 'Editor Window'
cv2.namedWindow(window_name)
cv2.setMouseCallback(window_name, marker)
fvs = cv2.VideoCapture(args["video"])
(grabbed, frame) = fvs.read()

while grabbed:

    # grab the frame from the threaded video file stream, resize
    # it, and convert it to grayscale (while still retaining 3
    # channels)
    if run:
        # Code to display video fames ...

        cv2.waitKey(1) & 0xFF # Use A
        (grabbed, frame) = fvs.read()
    else:
        cv2.waitKey(1) & 0xFF # Use B

The code is very sensitive to the use of cv2.waitKey:

  1. If I don't have "Use A", the window freezes, without ever showing the video. I would've expected it to run and then close very quickly. Why is this not the case?

  2. If "Use B" is absent, execution freezes after the first mouse click. Does openCV somehow need to be waiting for a keyboard entry in order to see a mouse click? If so, why?

  3. If "Use B" has a delay of 0 (i.e. wait indefinitely), then it only seems to see mouse click events intermittently, though sometimes I'm also periodically pressing on the space bar as I click. Why is this? Am I somehow getting 'lucky' if I give a mouse-click soon enough before (or after?) a key press? If not, why the intermittent response?

Ultimately, I don't really understand the workings of cv2.waitKey(). I would've thought it waits for the given time delay for a keyboard event and then moves on. The interaction with a mouse click even confuses me.

Upvotes: 3

Views: 3615

Answers (2)

tsveti_iko
tsveti_iko

Reputation: 7972

According to the OpenCV Documentation:

The function waitKey waits for a key event infinitely (when delay <= 0 ) or for delay milliseconds, when it is positive. Since the OS has a minimum time between switching threads, the function will not wait exactly delay ms, it will wait at least delay ms, depending on what else is running on your computer at that time. It returns the code of the pressed key or -1 if no key was pressed before the specified time had elapsed.

So you can pause by pressing the "p" button of the keyboard using the OpenCV cv2.waitKey(delay) function like this:

import cv2

cap = cv2.VideoCapture('your_video.mov')

while(True):
    _, frame = cap.read()

    cv2.imshow("Frame", frame)

    key = cv2.waitKey(1)
    if key == ord("p"):
        cv2.waitKey(0)

Upvotes: 2

deets
deets

Reputation: 6395

waitKey drives the event-loop. Which is essential for things like keyboard or mouse events. Thus you always need to drive it if you expect interactive reactions.

Also, you can pull the waitKey in front of the if, and just issue it once.

Upvotes: 1

Related Questions