I have this situation where I use OpenCV to detect faces in front of the camera and do some ML on those faces. The issue that I have is that once I do all the processing, an
I set cap value after reading each frame to None and my problem solved in this way:
import cv2
from PyQt5.QtCore import QThread
if __name__ == '__main__':
while True:
cap = cv2.VideoCapture(0)
ret, frame = cap.read()
cv2.imshow('A', frame)
cv2.waitKey(0)
print('sleep!')
QThread.sleep(5)
print('wake up!')
cap = None
Whether CAP_PROP_BUFFERSIZE
is supported appears quite operating system and backend-specific. E.g., the 2.4 docs state it is "only supported by DC1394 [Firewire] v 2.x backend currently," and for backend V4L, according to the code, support was added only on 9 Mar 2018.
The easiest non-brittle way to disable the buffer is using a separate thread; for details, see my comments under Piotr Kurowski's answer. Here Python code that uses a separate thread to implement a bufferless VideoCapture: (I did not have a opencv4nodejs environment.)
import cv2, Queue, threading, time
# bufferless VideoCapture
class VideoCapture:
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 = VideoCapture(0)
while True:
frame = cap.read()
time.sleep(.5) # simulate long processing
cv2.imshow("frame", frame)
if chr(cv2.waitKey(1)&255) == 'q':
break
The frame reader thread is encapsulated inside the custom VideoCapture
class, and communication with the main thread is via a queue.
This answer suggests using cap.grab()
in a reader thread, but the docs do not guarantee that grab()
clears the buffer, so this may work in some cases but not in others.
I have the same problem but in C++. I didn't find proper solution in OpenCV but I found a workaround. This buffer accumulates a constant number of images, say n frames. So You can read n frames without analysis and read frame once more. That last frame will be live image from camera. Something like:
buffer_size = n;
for n+1
{
// read frames to mat variable
}
// Do something on Mat with live image