核心函数
cv2.VideoCapture
是 OpenCV 中用于视频采集的核心对象。它抽象了视频输入源,无论是来自硬件摄像头、视频文件,还是网络流(如 IP 摄像机)。
构造函数(初始化)
创建 VideoCapture
对象的关键在于传入正确的参数,以指定视频源。
语法 | 说明 |
---|---|
cap = cv2.VideoCapture(index) |
实时流: 传入整数 index 。通常 0 代表系统默认摄像头,1 代表第二个摄像头,以此类推。 |
cap = cv2.VideoCapture(filename) |
文件流: 传入视频文件的路径字符串 filename (如 'video.mp4' 或 'C:/path/to/video.avi' )。 |
cap = cv2.VideoCapture(url) |
网络流: 传入网络视频流的 URL 字符串(需确保 OpenCV 编译时支持相应的后端,如 GStreamer)。 |
核心方法
方法 | 功能 | 返回值/说明 |
---|---|---|
cap.isOpened() |
检查视频源是否成功初始化和打开。 | True (成功) 或 False (失败) |
ret, frame = cap.read() |
从视频流中读取下一帧。 | ret (bool ): 表示是否成功读取帧;frame (numpy.ndarray ): 读取到的帧图像(BGR 格式)。 |
cap.release() |
释放视频采集资源。在完成视频操作后必须调用。 | 无 |
cap.get(propId) |
获取视频属性,如帧宽度、高度、FPS 等。 | 返回属性值(通常为 float )。 |
cap.set(propId, value) |
设置视频属性。 | True (成功) 或 False (失败)。 |
关键属性标识符(propId
)
在 cap.get()
和 cap.set()
中使用的常量,用于指定操作的视频属性:
标识符 | 说明 |
---|---|
cv2.CAP_PROP_FRAME_WIDTH |
帧的宽度(像素) |
cv2.CAP_PROP_FRAME_HEIGHT |
帧的高度(像素) |
cv2.CAP_PROP_FPS |
视频帧率(Frames Per Second) |
cv2.CAP_PROP_FRAME_COUNT |
视频文件中的总帧数 |
cv2.CAP_PROP_POS_FRAMES |
当前帧的位置(基于 0 的索引) |
示例
示例1:实时摄像头视频采集(实时流)
python
import cv2
# 1. 初始化 VideoCapture 对象,参数 0 表示默认摄像头
cap = cv2.VideoCapture(0)
# 检查摄像头是否成功打开
if not cap.isOpened():
print("错误:无法打开摄像头。请检查设备索引或驱动。")
exit()
print("摄像头已打开,按 'q' 键退出...")
# 实时流处理循环
while True:
# 2. 读取一帧
# ret 为布尔值,表示是否成功读取
# frame 为读取到的帧图像(numpy 数组)
ret, frame = cap.read()
# 如果未成功读取帧(如流结束或读取错误),则退出循环
if not ret:
print("无法接收帧(可能是流结束)。退出...")
break
# *** 在这里可以对 frame 进行各种图像处理操作 ***
# 例如:转换为灰度图
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 3. 显示结果帧
# 显示原始彩色帧
cv2.imshow('Live Camera Feed', frame)
# 也可以显示处理后的灰度帧
# cv2.imshow('Gray Frame', gray_frame)
# 4. 设置退出条件
# cv2.waitKey(1) 等待按键 1 毫秒
# 0xFF == ord('q') 检查按下的键是否是 'q'
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 5. 释放资源并关闭窗口
cap.release()
cv2.destroyAllWindows()
print("资源已释放,程序退出。")
示例2:读取视频文件(文件流)
python
import cv2
import time
# 假设你的视频文件名为 'test_video.mp4' 且在当前目录下
video_path = 'test_video.mp4'
# 1. 初始化 VideoCapture 对象,参数为视频文件路径
cap = cv2.VideoCapture(video_path)
# 检查视频文件是否成功打开
if not cap.isOpened():
print(f"错误:无法打开视频文件: {video_path}")
exit()
# 2. 获取视频属性
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)
print(f"视频分辨率: {frame_width}x{frame_height}")
print(f"视频帧率 (FPS): {fps:.2f}")
# 计算每帧应等待的毫秒数 (播放速度控制)
# 默认 FPS,如果读取失败,则使用 25 毫秒/帧 (约 40 FPS)
delay = int(1000 / fps) if fps > 0 else 25
print(f"每帧等待时间: {delay} 毫秒")
# 文件流处理循环
while cap.isOpened():
# 3. 读取一帧
ret, frame = cap.read()
if ret:
# 4. 显示帧
cv2.imshow('Video File Player', frame)
# 5. 等待按键
# waitKey(delay) 控制播放速度
# 按 'q' 退出
if cv2.waitKey(delay) & 0xFF == ord('q'):
break
else:
# 如果读取失败(通常是文件末尾),则退出循环
print("视频播放结束。")
break
# 6. 释放资源并关闭窗口
cap.release()
cv2.destroyAllWindows()
print("资源已释放,程序退出。")
示例3:拉取 RTSP 网络实时流
python
import cv2
import time
# !!!重要!!!
# 请替换为您实际的 RTSP URL
# 格式通常为: rtsp://用户名:密码@IP地址:端口/路径
RTSP_URL = 'rtsp://guest:password@192.168.1.100:554/live/ch0' # 替换为您的实际地址
# 1. 初始化 VideoCapture 对象,传入 RTSP URL
# 注意:网络流的初始化时间可能较长,程序会阻塞直到连接尝试结束
cap = cv2.VideoCapture(RTSP_URL, cv2.CAP_FFMPEG) # 明确指定使用 FFmpeg 后端,增强兼容性
# 检查流是否成功打开
if not cap.isOpened():
print(f"错误:无法打开 RTSP 流:{RTSP_URL}")
print("请检查 URL 格式、用户名密码、网络连通性以及 OpenCV 的 FFmpeg 支持。")
exit()
print(f"RTSP 流已成功连接,分辨率:{int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))}x{int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))}")
print("按 'q' 键退出...")
# RTSP 实时流处理循环
while True:
# 2. 读取一帧
# 网络流可能会因为网络延迟或断开导致读取失败
ret, frame = cap.read()
# 如果未成功读取帧,可能是网络中断或流结束
if not ret:
print("警告:无法从 RTSP 流接收帧。尝试重新连接或退出...")
# 尝试等待并重新读取
time.sleep(0.1)
continue
# *** 在这里可以进行实时处理,例如绘制文本、目标检测等 ***
cv2.putText(frame, 'RTSP Live Stream', (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
# 3. 显示结果帧
cv2.imshow('RTSP Stream Player', frame)
# 4. 设置退出条件
# 对于实时流,waitKey(1) 保证了尽可能快的帧率显示
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 5. 释放资源并关闭窗口
cap.release()
cv2.destroyAllWindows()
print("RTSP 资源已释放,程序退出。")
保存视频:cv2.VideoWriter
虽然请求是关于采集,但在实际应用中,采集往往伴随着处理和保存。cv2.VideoWriter
类用于将处理后的帧写入视频文件。
核心 API
语法 | 说明 |
---|---|
out = cv2.VideoWriter(filename, fourcc, fps, frame_size) |
构造函数:创建一个 VideoWriter 对象,准备写入视频文件。 |
out.write(frame) |
将一帧图像写入视频文件。 |
out.release() |
关闭视频文件并释放资源。 |
参数说明:
filename
:输出视频文件的路径,例如'output.avi'
。fourcc
:四字符代码 (FourCC),用于指定视频编码器。fps
:输出视频的帧率。frame_size
:帧的宽度和高度,格式为(width, height)
元组。
视频编码格式参考(FourCC)
格式 | FourCC | 文件扩展名 | 说明 |
---|---|---|---|
MPEG-4 | 'mp4v' |
.mp4 |
通用、兼容性好 |
XVID | 'XVID' |
.avi |
常用 AVI 格式 |
MJPG | 'MJPG' |
.avi |
运动JPEG编码 |
H.264 | 'X264' |
.mp4 |
需要系统支持 H.264 编码器 |
DIVX | 'DIVX' |
.avi |
常见编码 |
示例
示例1:采集实时流并保存视频
python
import cv2
# 1. 初始化 VideoCapture 对象,参数 0 表示默认摄像头
cap = cv2.VideoCapture(0)
# 检查摄像头是否成功打开
if not cap.isOpened():
print("错误:无法打开摄像头。请检查设备索引或驱动。")
exit()
print("摄像头已打开,按 'q' 键退出...")
# 获取帧的尺寸和 FPS
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = 20.0 # 设置保存视频的帧率
# 1. 定义 FourCC 编码和 VideoWriter 对象
# 使用 mp4v 编码,保存为 MP4 文件
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter('output.mp4', fourcc, fps, (frame_width, frame_height))
while True:
ret, frame = cap.read()
if ret:
# 2. 将原始帧写入输出文件
out.write(frame)
# 显示帧 (与前例相同)
cv2.imshow('Live Camera Feed and Saving', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
# 3. 释放 VideoCapture 和 VideoWriter 资源
cap.release()
out.release()
cv2.destroyAllWindows()
print("视频已保存到 output.mp4。")
示例2:拉取rtsp实时流并保存视频
python
import cv2
import time
# !!!重要!!!
# 请替换为您实际的 RTSP URL
# 格式通常为: rtsp://用户名:密码@IP地址:端口/路径
RTSP_URL = 'rtsp://admin:Gzd@791369209@192.168.0.111:554/Streaming/Channels/101' # 替换为您的实际地址
# 初始化 VideoCapture 对象,传入 RTSP URL
# 注意:网络流的初始化时间可能较长,程序会阻塞直到连接尝试结束
cap = cv2.VideoCapture(RTSP_URL, cv2.CAP_FFMPEG) # 明确指定使用 FFmpeg 后端,增强兼容性
# 检查流是否成功打开
if not cap.isOpened():
print(f"错误:无法打开 RTSP 流:{RTSP_URL}")
print("请检查 URL 格式、用户名密码、网络连通性以及 OpenCV 的 FFmpeg 支持。")
exit()
print(f"RTSP 流已成功连接,分辨率:{int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))}x{int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))}")
print("按 'q' 键退出...")
# 获取帧的尺寸和 FPS
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = 20.0 # 设置保存视频的帧率
# 1. 定义 FourCC 编码和 VideoWriter 对象
# 使用 mp4v 编码,保存为 MP4 文件
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter('output_rtsp.mp4', fourcc, fps, (frame_width, frame_height))
while True:
ret, frame = cap.read()
if ret:
# 2. 将原始帧写入输出文件
out.write(frame)
# 显示帧 (与前例相同)
cv2.imshow('Live Camera Feed and Saving', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
# 3. 释放 VideoCapture 和 VideoWriter 资源
cap.release()
out.release()
cv2.destroyAllWindows()
print("视频已保存到 output.mp4。")