3、读取本地摄像头:cv2.VideoCapture的使用、帧率设置、分辨率调整与属性获取
好,咱们进入实战环节。
摄像头数据流接入,说白了就是让电脑认识摄像头。OpenCV 里最核心的工具就是 cv2.VideoCapture。我刚开始接触这个接口时,觉得它就是个简单的摄像头开关。后来踩的坑多了,才发现里面门道不少。
3.1 打开摄像头:cv2.VideoCapture 的基本用法
先看最基础的代码。打开摄像头只需要一行:
import cv2
# 打开默认摄像头(通常是笔记本前置摄像头)
cap = cv2.VideoCapture(0)
# 检查是否成功打开
if not cap.isOpened():
print("摄像头打开失败,请检查连接")
exit()
# 读取一帧
ret, frame = cap.read()
# 释放资源
cap.release()
这里 0 代表设备索引。如果你插了多个摄像头,可以试试 1、2…… 我遇到过一种情况:笔记本自带摄像头是 0,外接 USB 摄像头有时是 1,有时是 2。嗯,这跟驱动加载顺序有关。
3.2 帧率设置:别被数字骗了
很多人以为设置帧率就是调个参数那么简单。其实不然。
# 尝试设置帧率为 30fps
cap.set(cv2.CAP_PROP_FPS, 30)
# 获取实际帧率
fps = cap.get(cv2.CAP_PROP_FPS)
print(f"实际帧率: {fps}")
你猜怎么着?我曾在项目中设置 60fps,结果实际跑出来只有 15fps。为什么?因为摄像头硬件能力有限,或者 USB 带宽不够。说白了,set() 只是给摄像头发个请求,它不一定听你的。
get() 读回来确认。如果实际帧率远低于设定值,别硬调,考虑降低分辨率或换硬件。
还有一个坑:有些摄像头不支持动态调整帧率。我曾经调试一个工业相机,怎么调帧率都不变,后来发现它只支持 30fps 和 60fps 两档。你想想看,中间值根本没用。
3.3 分辨率调整:别贪心
分辨率设置和帧率类似,也是先 set 再 get 确认。
# 设置分辨率为 1280x720
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
# 获取实际分辨率
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
print(f"实际分辨率: {width}x{height}")
我个人习惯是:先设一个目标分辨率,然后读回来看看实际是多少。如果差太多,就降一档。比如你想用 1920x1080,但摄像头只支持 1280x720,那就别硬撑。
3.4 属性获取:知己知彼
除了帧率和分辨率,还有很多属性可以查。我列几个常用的:
| 属性常量 | 含义 | 常见值 |
|---|---|---|
| CAP_PROP_FRAME_WIDTH | 画面宽度 | 640, 1280, 1920 |
| CAP_PROP_FRAME_HEIGHT | 画面高度 | 480, 720, 1080 |
| CAP_PROP_FPS | 帧率 | 15, 30, 60 |
| CAP_PROP_BRIGHTNESS | 亮度 | 0~255 |
| CAP_PROP_CONTRAST | 对比度 | 0~255 |
| CAP_PROP_SATURATION | 饱和度 | 0~255 |
| CAP_PROP_HUE | 色调 | 0~255 |
| CAP_PROP_GAIN | 增益 | 0~255 |
| CAP_PROP_EXPOSURE | 曝光时间 | 视摄像头而定 |
获取这些属性的代码很简单:
# 一次性获取多个属性
props = {
"宽度": cv2.CAP_PROP_FRAME_WIDTH,
"高度": cv2.CAP_PROP_FRAME_HEIGHT,
"帧率": cv2.CAP_PROP_FPS,
"亮度": cv2.CAP_PROP_BRIGHTNESS,
"对比度": cv2.CAP_PROP_CONTRAST,
}
for name, prop_id in props.items():
value = cap.get(prop_id)
print(f"{name}: {value}")
你可能会发现,有些属性返回 0 或者 -1。别慌,这通常意味着摄像头不支持该属性。我遇到过一款廉价 USB 摄像头,亮度、对比度全都不支持,只能调分辨率。嗯,一分钱一分货。
3.5 完整示例:一个实用的摄像头检测脚本
最后,我分享一个自己常用的脚本。它帮你快速了解一个摄像头的底细:
import cv2
def inspect_camera(index=0):
cap = cv2.VideoCapture(index)
if not cap.isOpened():
print(f"摄像头 {index} 无法打开")
return
print(f"=== 摄像头 {index} 信息 ===")
# 尝试设置常用分辨率
for w, h in [(640, 480), (1280, 720), (1920, 1080)]:
cap.set(cv2.CAP_PROP_FRAME_WIDTH, w)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, h)
actual_w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
actual_h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
print(f"设置 {w}x{h} -> 实际 {actual_w}x{actual_h}")
# 获取当前帧率
fps = cap.get(cv2.CAP_PROP_FPS)
print(f"当前帧率: {fps}")
cap.release()
# 检查 0 号和 1 号摄像头
inspect_camera(0)
inspect_camera(1)
这个脚本会遍历几个常见分辨率,告诉你摄像头到底支持什么。我每次拿到新摄像头,第一件事就是跑这个脚本。你想想看,连硬件能力都不清楚,后面怎么调参?
好了,关于 cv2.VideoCapture 的基本操作就这些。记住三个要点:打开要检查、设置要确认、属性要了解。下一节咱们聊聊如何从摄像头持续读取视频流,以及如何处理实时数据。