如何在OpenCV Camera中禁用Buffer? [英] How to disable Buffer in OpenCV Camera?

查看:162
本文介绍了如何在OpenCV Camera中禁用Buffer?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这种情况下,我使用OpenCV来检测相机前面的脸部,并对这些脸部进行ML.我的问题是,一旦完成所有处理,然后抓住下一帧,我就会了解过去,而不是现在.意思是,我将读取缓冲区中的内容,而不是摄像头之前的内容.由于我不在乎在处理时哪些面孔出现在镜头前,因此我在意镜头前的现在.

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, and go to grab the next frame I get the past, not the present. Meaning, I'll read whats inside the buffer, and not what is actually in front of the camera. Since I don't care which faces came in front of the camera while processing, I care what is now in front of the camera.

我确实尝试将缓冲区大小设置为1,这确实有很大帮助,但是我仍然会至少读取3次缓冲区.将FPS设置为1,同样不能100%消除这种情况.波纹管就是我所拥有的.

I did try to set the buffer size to 1, and that did help quite a lot, but I still will get at least 3 buffer reads. Setting the FPS to 1, also dose not help remove this situation 100%. Bellow is the flow that I have.

let cv = require('opencv4nodejs');

let camera = new cv.VideoCapture(camera_port);

camera.set(cv.CAP_PROP_BUFFERSIZE, 1);
camera.set(cv.CAP_PROP_FPS, 2);
camera.set(cv.CAP_PROP_POS_FRAMES , 1);

function loop()
{
    //
    //  <>> Grab one frame from the Camera buffer.
    //
    let rgb_mat = camera.read();

    //  Do to gray scale

    //  Do face detection

    //  Crop the image

    //  Do some ML stuff

    //  Do whats needs to be done after the results are in.

    //
    //  <>> Release data from memory
    //
    rgb_mat.release();

    //
    //  <>> Restart the loop
    //
    loop();
}

我的问题是:

是否可以一起删除缓冲区?如果是这样,怎么做.如果没有,why将不胜感激.

推荐答案

是否支持CAP_PROP_BUFFERSIZE似乎是特定于操作系统和特定于后端的.例如, 2.4个文档表示它是根据

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.

禁用缓冲区的最简单的非易碎方法是使用单独的线程.有关详细信息,请参阅我在Piotr Kurowski的回答下的评论.这里的Python代码使用一个单独的线程来实现无缓冲VideoCapture :(我没有opencv4nodejs环境.)

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

帧读取器线程封装在自定义VideoCapture类中,并且通过队列与主线程进行通信.

The frame reader thread is encapsulated inside the custom VideoCapture class, and communication with the main thread is via a queue.

答案建议在阅读器线程中使用cap.grab(),但是文档不保证grab()会清除缓冲区,因此在某些情况下可能会起作用,而在其他情况下则不会.

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.

这篇关于如何在OpenCV Camera中禁用Buffer?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆