Reputation: 43
Consider the below script:
class VideoCaptureThreading:
def __init__(self, src=0, width=640, height=480):
self.src = src
self.cap = cv2.VideoCapture(self.src)
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
self.grabbed, self.frame = self.cap.read()
self.started = False
self.read_lock = threading.Lock()
def set(self, var1, var2):
self.cap.set(var1, var2)
def start(self):
if self.started:
print('[!] Threaded video capturing has already been started.')
return None
self.started = True
self.thread = threading.Thread(target=self.update, args=())
self.thread.start()
return self
def update(self):
while self.started:
grabbed, frame = self.cap.read()
with self.read_lock:
self.grabbed = grabbed
self.frame = frame
def read(self):
with self.read_lock:
if isinstance(self.frame,np.ndarray):
frame = self.frame.copy()
grabbed = self.grabbed
else:
frame=None
grabbed=False
return grabbed, frame
def stop(self):
self.started = False
self.thread.join()
def get(self, prop):
with self.read_lock:
prop = self.cap.get(prop)
return prop
def __exit__(self, exec_type, exc_value, traceback):
self.cap.release()
Suppose in the above script, I want to reduce latency in reading the frames from a videocapture object so here multithreading is used to read and update the frames from buffer in read() method
a copy of the frame is created using copy()
which I feel might be causing lag but again I am making a guess, any helpful explanations are welcomed.
Upvotes: 0
Views: 126
Reputation: 2495
This approach makes sure the frame is the latest one in the stream in case the stream publishes faster than reading from the buffer. If there is an observable latency, it is most probably because of heavy publisher encoder options or unsuited listener configuration (e.g. realtime flag not set). Copy has a cost but it does not exceed few milliseconds.
Upvotes: 1