Dav*_*tti 12 camera buffer opencv node.js opencv4nodejs
我遇到过这种情况,我使用 OpenCV 来检测相机前的人脸并对这些人脸进行一些机器学习。我遇到的问题是,一旦我完成所有处理,然后去抓取下一帧,我就会得到过去,而不是现在。意思是,我将读取缓冲区内的内容,而不是实际在相机前的内容。因为我不在乎处理时哪些人脸出现在相机前面,所以我关心现在在相机前面的是什么。
我确实尝试将缓冲区大小设置为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();
}
Run Code Online (Sandbox Code Playgroud)
是否可以一起删除缓冲区?如果是这样,如何。如果没有,why将不胜感激。
Ulr*_*ern 14
是否CAP_PROP_BUFFERSIZE受支持显得相当操作系统和后端特定。例如,2.4 文档声明它“目前仅受 DC1394 [Firewire] v 2.x 后端支持”,而对于后端 V4L,根据代码,仅在 2018 年 3 月 9 日添加了支持。
禁用缓冲区的最简单的非脆弱方法是使用单独的线程;有关详细信息,请参阅我在 Piotr Kurowski 的回答下的评论。这里使用单独的线程来实现无缓冲 VideoCapture 的 Python 代码:(我没有 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
Run Code Online (Sandbox Code Playgroud)
帧读取器线程封装在自定义VideoCapture类中,与主线程的通信是通过队列进行的。
这个答案建议cap.grab()在阅读器线程中使用,但文档不保证grab()清除缓冲区,因此这可能在某些情况下有效,但在其他情况下无效。
我也有同样的问题,但是是在 C++ 中。我在 OpenCV 中没有找到正确的解决方案,但我找到了解决方法。该缓冲区累积恒定数量的图像,例如 n 帧。所以你可以读取n帧而不进行分析并再次读取帧。最后一帧将是来自相机的实时图像。就像是:
buffer_size = n;
for n+1
{
// read frames to mat variable
}
// Do something on Mat with live image
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8392 次 |
| 最近记录: |