目录
前言
5.2 视频基础理论
5.2.1 什么是帧
5.2.2 OpenCV 处理视频的逻辑
5.2.3 视频读取
5.3业务流程
5.3.1 完整实战代码
5.3.1 完整实战代码
5.3.2 帧图像处理演示
5.4 调用摄像头
5.4.1 理论说明
5.4.2 完整实战代码
5.5注意
5.6 本章小结
前言
承接第 4 章图像几何变换。前面操作的都是静态图片,本章学习 OpenCV 处理视频,掌握本地视频读取、摄像头调用,所有代码可直接运行。
5.1 本章学习目标
- 理解视频底层原理,认识帧的概念
- 掌握使用VideoCapture读取本地视频文件
- 学会调用电脑摄像头采集画面
- 读懂ret、frame返回值,实现按键退出
- 养成规范释放视频资源的习惯
5.2 视频基础理论
5.2.1 什么是帧
视频本质上不是一张完整大图,是由很多张静态图像连续播放形成。其中每一张图像就叫做一帧(frame)。
依靠人眼的视觉暂留特性,短时间内连续切换大量图片,人就感知到连续动态画面。
帧率 FPS:每秒播放多少帧图片,FPS 越高视频画面越流畅。 |
5.2.2 OpenCV 处理视频的逻辑
OpenCV 处理视频,本质就是循环不断读取每一帧图像。
拿到每一帧frame之后,它就等价于imread读取的普通图片,之前学习的灰度转换、缩放、色彩变换全部都可以直接作用在帧上。
5.2.3 视频读取
OpenCV 提供cv2.VideoCapture()专用接口实现视频读取,是处理视频流的核心方法。
video_capture = cv2.VideoCapture(r"视频路径"):创建视频捕获对象,绑定指定视频文件,用于加载、读取视频全部帧数据。
ret, frame = video_capture.read():逐帧读取视频画面,每次调用仅读取一帧,重复调用可依次读取后续画面。返回两个核心参数:ret为布尔值,标记是否读取到有效帧(判断是否到达视频末尾);frame为当前读取的图像帧数组,和静态图片数据格式完全一致。
通过while循环持续读取帧画面,配合cv2.waitKey(ms)控制单帧画面展示时长,以此调节视频播放速度。播放窗口需保持同名,确保画面实时覆盖刷新,实现流畅的视频播放效果。
5.3业务流程
- 创建VideoCapture对象,传入视频路径
- 判断视频是否正常打开
- while循环,不停调用read()读取帧
- 判断ret,读到末尾退出循环
- imshow展示当前帧
- 监听 ESC 按键实现手动退出,用waitKey()检测键盘ASSII机制,退出视频播放
- 释放资源(video_capture.release())不然会堆积在计算机中,关闭窗口
5.3.1 完整实战代码
5.3.1 完整实战代码
import cv2 # 传入视频文件路径,创建视频读取对象 video_capture = cv2.VideoCapture(r'D:\pythoncode2\bigdata_ai40\data\wa.mp4') # 判断视频是否成功打开:路径错误、文件损坏都会打开失败 if not video_capture.isOpened(): print("无法打开视频") exit() # 循环读取视频画面 while True: # 读取一帧画面 ret, frame = video_capture.read() # ret为False代表读到视频末尾,结束循环 if not ret: break cv2.imshow('video', frame) # 等待60ms,按下ESC键(ASCII=27)退出播放 if cv2.waitKey(60) == 27: break # 释放资源,关闭窗口 video_capture.release() cv2.destroyAllWindows()5.3.2 帧图像处理演示
每一帧frame就是普通图像,可以直接做各类图像处理,示例转为灰度播放:
import cv2 video_capture = cv2.VideoCapture(r'D:\pythoncode2\bigdata_ai40\data\wa.mp4') if not video_capture.isOpened(): print("无法打开视频") exit() while True: ret, frame = video_capture.read() if not ret: break # 直接对帧做图像处理 gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) cv2.imshow("gray_video", gray_frame) if cv2.waitKey(60) == 27: break video_capture.release() cv2.destroyAllWindows()5.4 调用摄像头
5.4.1 理论说明
调用摄像头的逻辑和读取本地视频几乎完全一致。
区别:VideoCapture不再传入文件路径,传入数字。
- 0:代表本机默认摄像头
- 外接多个摄像头依次尝试1、2
摄像头属于实时流,没有 “视频末尾”,只能通过按键手动结束循环。
5.4.2 完整实战代码
import cv2 # 0代表本机摄像头 cap = cv2.VideoCapture(0) if not cap.isOpened(): print("摄像头打开失败,请检查摄像头权限与设备") exit() while True: ret, frame = cap.read() if not ret: break cv2.imshow("camera", frame) # ESC按键退出 if cv2.waitKey(20) == 27: break cap.release() cv2.destroyAllWindows()5.5注意
- 视频路径写错、视频损坏,isOpened()返回 False,无法播放。
- 不要忘记release(),否则视频 / 摄像头资源不会释放,程序卡死。
- 播放视频时waitKey不能写 0,写 0 会一直等待按键,画面不会自动刷新。
- 一定要判断if not ret: break,读到视频结尾及时跳出循环,避免死循环。
5.6 本章小结
- 视频由大量图像帧构成,依靠连续播放帧实现动态效果。
- 使用cv2.VideoCapture(路径)读取本地视频,.isOpened()判断是否打开成功。
- read()得到ret状态和frame图像,帧可以复用所有图片处理代码。
- 调用摄像头只需要把参数改为数字0,其余逻辑和读视频完全一致。
- waitKey(毫秒)控制播放速度、监听 ESC 退出;结束必须release()释放资源。