在这种情况下,我使用OpenCV来检测相机前面的脸部,并对这些脸部进行ML。我的问题是,一旦完成所有处理,然后抓住下一帧,我就会了解过去,而不是现在。意思是,我将读取缓冲区中的内容,而不是摄像头之前的内容。由于我不在乎在处理时哪些面孔出现在镜头前,所以我不在乎镜头前的现在。
我确实尝试将缓冲区大小设置为1
,这确实有很大帮助,但是我仍然会至少读取3次缓冲区。将FPS设置为1,同样不能100%消除这种情况。波纹管就是我所拥有的。
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
将不胜感激。
答案 0 :(得分:0)
我有同样的问题,但在C ++中。我在OpenCV中找不到合适的解决方案,但找到了解决方法。该缓冲器累积一定数量的图像,例如n帧。因此,您无需分析即可读取n帧,然后再次读取帧。最后一帧将是摄像机的实时图像。像这样:
buffer_size = n;
for n+1
{
// read frames to mat variable
}
// Do something on Mat with live image
答案 1 :(得分:0)
是否支持CAP_PROP_BUFFERSIZE
似乎是特定于操作系统和特定于后端的。例如,collation状态为“当前仅受DC1394 [Firewire] v 2.x后端支持,” 2.4 docs称,对于后端V4L,仅在2018年3月9日添加了支持。
禁用缓冲区的最简单的非易碎方法是使用单独的线程。有关详细信息,请参阅我在Piotr Kurowski的回答下的评论。这里的Python代码使用单独的线程来实现无缓冲VideoCapture :(我没有opencv4nodejs环境。)
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
类中,并且通过队列与主线程进行通信。
此code建议在阅读器线程中使用cap.grab()
,但是文档不保证grab()
清除缓冲区,因此这在某些情况下可能有效,但在其他情况下则不可用。 / p>
答案 2 :(得分:0)
我在读取每一帧后将上限设置为“无”,并且我的问题以这种方式解决了:
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