OpenCV(四):视频采集与保存

核心函数

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() 关闭视频文件并释放资源。

参数说明:

  1. filename :输出视频文件的路径,例如 'output.avi'
  2. fourcc:四字符代码 (FourCC),用于指定视频编码器。
  3. fps:输出视频的帧率。
  4. 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。")
相关推荐
minhuan2 小时前
构建AI智能体:五十七、LangGraph + Gradio:构建可视化AI工作流的趣味指南
人工智能·语言模型·workflow·langgraph·自定义工作流
WWZZ20253 小时前
ORB_SLAM2原理及代码解析:SetPose() 函数
人工智能·opencv·算法·计算机视觉·机器人·自动驾驶
lisw053 小时前
AIoT(人工智能物联网):融合范式下的技术演进、系统架构与产业变革
大数据·人工智能·物联网·机器学习·软件工程
mtouch3333 小时前
GIS+VR地理信息虚拟现实XR MR AR
大数据·人工智能·ar·无人机·xr·vr·mr
一人の梅雨3 小时前
1688 拍立淘接口深度开发:从图像识别到供应链匹配的技术实现
人工智能·算法·计算机视觉
苏打水com3 小时前
字节跳动前端业务:从「短视频交互」到「全球化适配」的技术挑战
前端·音视频
dundunmm4 小时前
【数据集】WebQuestions
人工智能·llm·数据集·知识库问答·知识库
却道天凉_好个秋4 小时前
OpenCV(五):鼠标控制
人工智能·opencv·鼠标控制
IT_陈寒4 小时前
Redis性能优化:5个被低估的配置项让你的QPS提升50%
前端·人工智能·后端