0 · 导读:一个心智模型贯穿全局
把三件事先统一起来:
- 摄像头:一个永不停止、按固定帧率往外吐帧的设备。
- 视频文件:一个预先录好、按固定帧率往外吐帧的文件。
- OpenCV 的处理方式:两者都被抽象成
cv2.VideoCapture,区别只在于你传入的是「设备索引0」还是「文件路径"clip.mp4"」。
于是整条流水线只有一句话:
打开一个 VideoCapture → 循环 read() 拿到一帧 frame(numpy 数组) → 处理这一帧 → 显示/保存 → 循环,直到没有下一帧
全文两条贯穿主线(和图像处理一样,80% 的坑都在这里):
frame就是一张uint8的 NumPy 数组((H, W, 3)的 BGR),你之前学的所有图像处理函数(cvtColor/resize/rectangle/split)对摄像头帧完全适用。- 坐标
(x, y)与数组[y, x]错位、BGR vs RGB —— 摄像头帧一样踩。
1 · 环境准备
1.1 安装
OpenCV 的 Python 包分两个:
| 包名 | 用途 | 体积 |
|---|---|---|
opencv-python |
主模块 cv2,含核心 + 视频 IO + 图像算法 |
小 |
opencv-contrib-python |
在上面的基础上加了 contrib 扩展(SIFT、跟踪、AR 等) |
稍大 |
入门只用主模块即可:
pip install opencv-python
服务器 / 无显示环境(Docker、CI、树莓派无桌面)装
opencv-python-headless,否则import cv2会因找不到 GUI 后端报错。headless 版只是去掉了imshow/namedWindow这类依赖显示后端的函数,视频VideoCapture/VideoWriter不受影响。
1.2 验证安装
import cv2
print(cv2.__version__) # 例如 4.9.0
cap = cv2.VideoCapture(0) # 尝试打开默认摄像头
print(cap.isOpened()) # True 表示成功
cap.release()
1.3 版本与后端
cv2.getBuildInformation() 能看出当前编译进了哪些视频后端(V4L2 / DSHOW / GSTREAMER / FFMPEG)。后面排错经常要看它。
info = cv2.getBuildInformation()
print("FFMPEG" in info, "GSTREAMER" in info, "V4L2" in info)
2 · 图像基础回顾(因为摄像头帧就是图)
在进入视频前,先把「单张图」的几个 API 钉死,摄像头每帧用的就是它们。
import cv2
img = cv2.imread("cat.jpg") # 返回 BGR 的 (H,W,3) uint8 数组
cv2.imshow("window", img) # 在名为 window 的窗口显示
key = cv2.waitKey(0) # 等待按键;0=无限等待,>0=毫秒
cv2.destroyAllWindows() # 关闭所有窗口
三个必须记住的点:
cv2.imread返回 BGR(蓝绿红),不是 RGB。想用matplotlib显示要cv2.cvtColor(img, cv2.COLOR_BGR2RGB)。cv2.imshow之后必须跟一个cv2.waitKey,否则窗口会瞬间闪退(它负责把图像推到屏幕并刷新事件队列)。cv2.waitKey(1)在视频循环里的「1」是等待 1 毫秒并顺带处理 GUI 事件;不是「每秒 1 帧」。真正控制帧率的是摄像头自己的帧率。
3 · 摄像头捕获:VideoCapture
3.1 打开与读取
import cv2
cap = cv2.VideoCapture(0) # 0 = 默认摄像头(笔记本内置摄像头)
if not cap.isOpened():
raise IOError("打不开摄像头,检查设备索引/权限/是否被占用")
while True:
ret, frame = cap.read() # ret: 是否成功取到帧;frame: (H,W,3) BGR 数组
if not ret:
break
cv2.imshow("live", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
956



被折叠的 条评论
为什么被折叠?



