我想减少摄像头每秒获取的帧数,这是我使用的代码
#!/usr/bin/env python
import cv2
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FPS, 10)
fps = int(cap.get(5))
print("fps:", fps)
while(cap.isOpened()):
ret,frame = cap.read()
if not ret:
break
cv2.imshow('frame', frame)
k = cv2.waitKey(1)
if k == 27:
break
但它不起作用,我仍然有30 fps默认而不是10设置的cap.set(cv2.CAP_PROP_FPS, 10)
.我想降低帧率,因为我有一个手探测器,这需要相当多的时间来处理每一帧,我不能在缓冲区中存储帧,因为它会检测到在以前的位置的手。我可以使用计时器或其他东西来运行探测器,但我认为改变fps是一种更简单的方法,但它不起作用,我不知道为什么。
我在Windows 8.1中使用OpenCV 3.4.2和Python 3.6.3
6条答案
按热度按时间dced5bon1#
设置帧速率并不总是像您期望的那样工作。它取决于两件事:
1.你的相机能输出什么。
1.您使用的当前捕获后端是否支持更改帧速率。
所以点(1).您的相机将有一个格式列表,它能够提供给捕捉设备(例如您的计算机)。这可能是1920x1080@30 fps或1920x1080@60 fps,并且它还指定了像素格式。绝大多数消费相机不允许您以任何粒度更改其帧速率。大多数捕获库将拒绝更改为相机没有广告的捕获格式。
即使是机器视觉摄像机,它允许您进行更多的控制,通常也只提供一种帧速率选择(例如1,2,5,10,15,25,30等)。如果您想要在硬件级别不支持的帧速率,通常唯一的方法是使用硬件触发。
第(2)点。当你使用
cv.VideoCapture
时,你实际上是在调用一个特定于平台的库,比如DirectShow或V4 L2。我们称之为后端。你可以通过使用以下命令来指定正在使用的后端:cv2.VideoCapture(0 + cv2.CAP_DSHOW)
定义了很多
CAP_X
,但只有一部分适用于您的平台。(例如CAP_V4L2
仅适用于Linux)。在Windows上,强制系统使用DirectShow是一个相当不错的选择。然而如上所述,如果你的相机只报告它可以输出30 fps和60 fps,请求10 fps将毫无意义。更糟糕的是,很多设置只是在OpenCV中报告True
,而实际上它们并没有实现。你已经看到,大多数时候阅读参数会给予你合理的结果,但是如果参数没有实现(例如曝光是一个常见的参数),那么你可能会得到废话。你最好等待一段时间,然后阅读最后一张图像。
使用此策略时要小心。不要这样做:
您需要确保不断清除相机的帧缓冲区,否则您将开始看到视频中的滞后。类似于以下内容的内容应该可以工作:
对于像手探测器这样的应用程序,最好的方法是让一个线程捕获图像,而探测器在另一个线程中运行(该线程也控制GUI)。您的探测器提取最后捕获的图像,运行并显示结果(您可能需要在阅读/写入图像缓冲区时锁定对图像缓冲区的访问)。这样,您的瓶颈是探测器,而不是相机的性能。
juzqafwq2#
我无法为我的相机设置FPS,所以我设法根据时间限制FPS,以便只有每秒1帧才能进入我的代码的其余部分。这不是精确的,但我不需要精确的,只是一个限制器而不是30fps。HTH
cwdobuhd3#
正如Josh所说,在openCV上更改相机的fps在很大程度上取决于您的相机是否支持您试图设置的配置。
我设法在Ubuntu 18.04 LTS中更改了openCV的相机fps:
1.使用“sudo apt-get install v4 l-utils”安装v4 l2
1.运行命令“v4 l2-ctl --list-formats-ext”以显示支持的视频格式,包括帧大小和间隔。Results from running v4l2-ctl --list-formats-ext
1.在我的python脚本中:
2o7dmzc54#
属性 CV_CAP_PROP_FPS 仅适用于视频。如果您使用以下命令:
它返回零。如果你想减少每秒的帧数,那么你可以增加waitkey()的一个参数。例如:
svmlkihl5#
这是我开发的一个类,用于对视频或实时流进行子采样。
使用方法:
wfauudbj6#
这会解决你的问题