OpenCV摄像头打开及预览
0.我想做什么?
想做这样一个功能的原型:用网络摄像头做一个尺寸测量的仪器,好吧,就称它为一键测量仪远古版。
原型开发,目的是验证可行性。所以准备不用工业相机和镜头,而是选择便宜的网络摄像头;开发工具使用OpenCV,当然是python版。
1.打开摄像头并预览
本文完成第一步,打开摄像头并预览。
先介绍OpenCV中两个重要的方法: VideoCapture和waitKey。
1.1 VideoCapture
cv2.VideoCapture是OpenCV中处理视频输入的核心类,负责从摄像头、视频文件或网络流中捕获帧数据。
capture = cv2.VideoCapture(source, apiPreference=None)
参数说明:
- source:
0
:默认摄像头(通常为内置摄像头)1, 2, 3...
:USB外接摄像头(按连接顺序递增)\"video.mp4\"
:视频文件路径(支持MP4/AVI/MOV等)\"rtsp://192.168.1.1:554/stream\"
:RTSP网络视频流\"http://ip:port/video\"
:HTTP视频流
- apiPreference(可选):
指定底层视频捕获API,常用选项:
cv2.CAP_ANY# 自动选择(默认)cv2.CAP_DSHOW# DirectShow(Windows)cv2.CAP_V4L2# Video4Linux2(Linux)cv2.CAP_FFMPEG# FFmpeg解码
示例:cv2.VideoCapture(0, cv2.CAP_DSHOW)
还记得在写播放器那篇文章,传入的是视频文件路径。
常用方法
1. 设备状态检查:isOpened()
if not capture.isOpened():print(\"错误:无法打开视频源\")exit()
- 返回值:布尔值
- 必须调用:在访问帧数据前验证连接状态
2. 帧捕获:read()
ret, frame = capture.read()
- 返回值:
ret
:布尔值,帧是否成功读取frame
:NumPy数组(三维BGR格式)- 特性:
- 阻塞调用:等待下一帧可用
- 自动解码:处理压缩视频流
3. 属性访问:get(propId)
获取视频流的元数据和设备参数:
width = capture.get(cv2.CAP_PROP_FRAME_WIDTH)height = capture.get(cv2.CAP_PROP_FRAME_HEIGHT)fps = capture.get(cv2.CAP_PROP_FPS)
常用属性ID:
cv2.CAP_PROP_FRAME_WIDTH
cv2.CAP_PROP_FRAME_HEIGHT
cv2.CAP_PROP_FPS
cv2.CAP_PROP_POS_MSEC
cv2.CAP_PROP_FRAME_COUNT
cv2.CAP_PROP_AUTOFOCUS
cv2.CAP_PROP_EXPOSURE
4. 参数设置:set(propId, value)
# 设置分辨率capture.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)# 关闭自动对焦capture.set(cv2.CAP_PROP_AUTOFOCUS, 0)# 设置曝光(-1到1之间)capture.set(cv2.CAP_PROP_EXPOSURE, -0.5)
重要注意事项:
- 分辨率设置需设备支持
- 设置后需验证是否成功:
if capture.get(cv2.CAP_PROP_FRAME_WIDTH) != 1280:print(\"不支持该分辨率\")
5. 资源释放:release()
capture.release()
- 必须调用:释放硬件/网络资源
- 未释放后果:
- 摄像头锁定(其他程序无法访问)
- 内存泄漏
- 网络连接残留
1.2 waitKey
waitKey()
是OpenCV HighGUI库中的工具包,它在OpenCV窗口显示期间负责刷新图像帧并监听键盘事件。
retval = cv2.waitKey([delay]) # → 返回整数 (ASCII 键值)
参数delay
delay > 0
waitKey(30)
表示每帧显示30ms)delay = 0
delay < 0
delay=0
(无限等待)返回值
有按键触发,返回值就是按键的ASCII码;没有按键触发,就等待超时吧。
简单的ASCII码有:
2.编写代码
有了上面两个重要的知识点,结合我们的需求,就可以写代码了。
很简单,找到我的USB网络摄像头,用VideoCapture(1)即可。
不断的读取摄像头的帧,read方法即可。
不断的显示出来,用imshow即可。
完整代码很少,如下:
import cv2def camera_video(): capture = cv2.VideoCapture(1) # 0为电脑内置摄像头 if not capture.isOpened(): return while True: ret, frame = capture.read() cv2.imshow(\"video\", frame) c = cv2.waitKey(10) if c == 27: break if c == 13: # 回车,处理图像 cv2.imwrite(\"test.png\", frame)camera_video()cv2.destroyAllWindows()
至此,借着这个机会梳理了VideoCapture和waitKey两个重要接口,坚持、积累,我们下期再见!