How to disable Buffer in OpenCV Camera?

前端 未结 3 1388
情话喂你
情话喂你 2021-01-04 19:07

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

相关标签:
3条回答
  • 2021-01-04 19:32

    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
    
    0 讨论(0)
  • 2021-01-04 19:34

    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.

    0 讨论(0)
  • 2021-01-04 19:34

    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
    
    0 讨论(0)
提交回复
热议问题