Allows to always get most recent frame, in case video capture loop has some (computation) delay inside
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Based on: https://stackoverflow.com/questions/43665208/how-to-get-the-latest-frame-from-capture-device-camera-in-opencv/54755738#54755738 | |
# | |
# Added: | |
# - configurable delay handling | |
# - renamed class | |
# - per frame timestamp output | |
# | |
import cv2, threading, time, queue | |
from sys import argv | |
wait = 0 if len(argv) == 1 else float(argv[1]) | |
class BufferlessVideoCapture: | |
def __init__(self, name): | |
self.cap = cv2.VideoCapture(name) | |
self.q = queue.Queue() | |
t = threading.Thread(target=self._reader) | |
t.daemon = True | |
t.start() | |
# read frames as soon as they are available, keeping only most recent one | |
def _reader(self): | |
while True: | |
ret, frame = self.cap.read() | |
if not ret: | |
break | |
if not self.q.empty(): | |
try: | |
self.q.get_nowait() # discard previous (unprocessed) frame | |
except queue.Empty: | |
pass | |
self.q.put(frame) | |
def read(self): | |
return self.q.get() | |
cap = BufferlessVideoCapture(0) | |
while True: | |
time.sleep(wait) | |
print("after wait, before cap.read()", time.time()) | |
frame = cap.read() | |
cv2.imshow("frame", frame) | |
if chr(cv2.waitKey(1)&255) == 'q': | |
break |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Call with "python BufferlessVideoCapture.py 2" for 2 second delay between loop executions.
Whenever a timestamp message is written, do after a seond a change (eg. of hand) in view.
When next timestamp gets printed, newly displayed frame will show changed scene.