OpenCV从实时摄像头流获取帧率及帧时间戳问题求助
问题解决思路与方案
你遇到的是OpenCV不同视频后端的属性支持差异问题:
- 用
cv2.CAP_DSHOW时,该后端对实时摄像头的CAP_PROP_POS_MSEC、CAP_PROP_FPS属性支持不完善,所以返回异常值;而CAP_PROP_FRAME_COUNT返回-1是正常的——实时摄像头是持续流,没有固定总帧数。 - 去掉
CAP_DSHOW后用默认后端,虽然能读取属性,但默认后端(比如旧的VFW)可能不支持自定义分辨率设置。
解决方法
方法1:手动统计帧率与计算时间戳(最可靠)
实时摄像头的标称帧率和实际帧率可能有差异,手动统计反而更准确。修改你的代码如下:
import os import time import cv2 import numpy as np # 使用DSHOW后端确保分辨率设置生效 vc = cv2.VideoCapture(0, cv2.CAP_DSHOW) # 确认分辨率设置是否成功 w_set_ok = vc.set(cv2.CAP_PROP_FRAME_WIDTH, 1280) h_set_ok = vc.set(cv2.CAP_PROP_FRAME_HEIGHT, 720) print(f"分辨率设置结果:宽度{'成功' if w_set_ok else '失败'},高度{'成功' if h_set_ok else '失败'}") # 初始化统计变量 total_frames = 0 start_time = time.time() last_frame_time = time.time() delta = 0 while True: ret, img = vc.read() if not ret: break current_time = time.time() # 计算当前帧的时间戳(程序启动后毫秒数) frame_timestamp = (current_time - start_time) * 1000 # 统计平均帧率 total_frames += 1 elapsed = current_time - start_time avg_fps = total_frames / elapsed if elapsed > 0 else 0 # 计算瞬时帧率 instant_fps = 1 / (current_time - last_frame_time) if (current_time - last_frame_time) > 0 else 0 last_frame_time = current_time print(f"帧时间戳:{frame_timestamp:.2f}ms,平均帧率:{avg_fps:.2f}fps") # 原有的3秒触发逻辑 delta += current_time - last_frame_time if delta > 3: # 执行图像操作 print("执行定时操作") delta = 0 if cv2.waitKey(20) == 27: break vc.release() cv2.destroyAllWindows()
方法2:尝试使用Windows Media Foundation后端
Windows系统下推荐用cv2.CAP_MSMF后端,它对分辨率设置和属性读取的支持更均衡:
vc = cv2.VideoCapture(0, cv2.CAP_MSMF) # 设置分辨率 vc.set(cv2.CAP_PROP_FRAME_WIDTH, 1280) vc.set(cv2.CAP_PROP_FRAME_HEIGHT, 720) # 尝试读取属性 fps = vc.get(cv2.CAP_PROP_FPS) print(f"读取到的帧率:{fps}") # 后续循环逻辑不变
注意:无论用哪种后端,CAP_PROP_FRAME_COUNT返回-1都是正常现象,因为实时摄像头没有固定的总帧数。
内容的提问来源于stack exchange,提问作者Francesco Borg
相关产品推荐
相关产品推荐

