AI视觉算法中的OpenCV API (二)

发布于:2025-09-13 ⋅ 阅读:(23) ⋅ 点赞:(0)
视频写入 (FourCC, VideoWriter)​

1. VideoWriter_fourcc - 视频编码器四字符代码

# OpenCV 3.x, 4.x
fourcc = cv2.VideoWriter_fourcc('M','J','P','G')

fourcc = cv2.VideoWriter_fourcc(*'H264')

fourcc = cv2.VideoWriter_fourcc(*'MJPG')
  • FourCC: 代表 ​Four ​Character ​Code,是一个4字节的代码,用于指定视频流的编码格式(Codec)​。它决定了视频数据如何被压缩。
  • 定义一个视频编码器(Codec)。视频编码器负责将连续的图像帧压缩成视频流,显著减小文件大小。

常用 FourCC 代码

  • Video Codecs by FOURCC - fourcc.org
  • ​**'XVID'​: MPEG-4 编码器。兼容性好,文件大小适中,是最常用**的选择之一。
  • ​**'MJPG'**​: Motion-JPEG 编码器。质量高,但文件非常大。
  • ​**'H264'​: H.264/AVC 编码器。压缩效率极高(文件小),质量好。​需要系统安装 H.264 编码器支持**​(如 Windows 上的 OpenH264 或 x264)。
  • ​**'MP4V'**​: MPEG-4 视频编码器。常用于 .mp4 文件。
  • ​**'AVC1'**​: 另一种表示 H.264 的方式。
  • ​**'DIVX'**​: DivX 编码器(基于 MPEG-4)。

常用 FourCC 代码与推荐的文件扩展名对应表

  • 文件扩展名​: 如 .avi.mp4.mov,用于指定容器格式(Container)​。容器是一个“包装盒”,里面可以存放由特定编码器压缩的视频流、音频流、字幕等信息。
  • 关键点在于:FourCC 编码器和文件扩展名容器之间并没有严格的、一对一的强制绑定关系,但存在广泛认可和兼容的“最佳实践”组合。​
  • 选择一个不常见的组合(例如,在 .mp4 文件里使用 XVID 编码)可能会导致某些播放器无法识别或播放。
FourCC 代码 推荐文件扩展名 说明与常见用途
​**'XVID'**​ .avi 最常用、兼容性最好的组合之一。XVID 是一个开源的 MPEG-4 视频编码器,生成的 .avi 文件可以在绝大多数设备和播放器上播放。文件大小和质量平衡得很好。
​**'MJPG'**​ .avi Motion-JPEG 编码,将每一帧都压缩为一张 JPEG 图片。​视频质量很高,但文件体积非常大。常用于对质量要求极高且不介意文件大小的场景。
​**'H264'**​ .mp4 H.264/AVC 编码,​当今最流行的编码标准。压缩效率极高(在相同质量下文件更小)。​注意​:OpenCV 可能需要系统安装额外的开源库(如 OpenH264 或 x264)才能使用此编码器。
​**'AVC1'**​ .mp4 本质上是 H.264 编码的另一种表示方法。行为与 'H264' 类似。
​**'MP4V'**​ .mp4 代表 MPEG-4 视频(Part 2),与 H.264(Part 10)不同。压缩效率通常不如 H.264,但兼容性可能更好。
​**'DIVX'**​ .avi DivX 编码器(也是基于 MPEG-4)。曾非常流行,现在多用于历史遗留项目。
​**'FMP4'**​ .mp4 FFmpeg 的 MPEG-4 编码器。如果你的 OpenCV 编译时包含了 FFmpeg 支持,可能会用到。
​**'PIM1'**​ .avi MPEG-1 编码。非常老的格式,文件大,质量一般,现较少使用。
​**'X264'**​ .mp4 特指使用 x264 库(一个优秀的开源 H.264 编码器实现)。这通常需要从源码自定义编译 OpenCV 才能直接使用。

选择建议​:

  • 为了最大兼容性​:使用 ​**'XVID'​ + ​.avi**。这是 OpenCV 中最可靠、问题最少的输出组合,几乎总能成功。
  • 为了更小的文件​:使用 ​**'H264'​ 或'AVC1' + ​.mp4**。这是目前网络传输和存储的标准格式。但需要确保你的 OpenCV 环境支持它(否则会写入失败或生成空文件)。
  • 高质量,不介意文件大小:'MJPG' + .avi**。

最重要的步骤​:

在编写代码时,始终检查 VideoWriter 对象是否通过 isOpened() 方法成功打开。如果首选的高效编码器(如 H.264)不可用,则回退到兼容性更好的编码器(如 XVID)。这是一种良好的编程实践,可以增强代码的健壮性。

fourcc = cv2.VideoWriter_fourcc(*'H264')
out = cv2.VideoWriter('test.mp4', fourcc, 20.0, (640, 480))
if not out.isOpened():
    print("错误:无法使用 H264 编码器!将回退到 XVID。")
    fourcc = cv2.VideoWriter_fourcc(*'XVID')
    out = cv2.VideoWriter('test.avi', fourcc, 20.0, (640, 480))

2. VideoWriter - 视频写入器

  • 创建一个对象,用于将连续的图像帧写入视频文件。
out = cv2.VideoWriter(filename, fourcc, fps, frame_size[, isColor])

语法:

  • filename: 要保存的视频文件路径(包括扩展名,如 'output.avi' 或 'result.mp4')。
  • fourcc: 由 VideoWriter_fourcc 创建的编码器对象。
  • fps: 视频的帧率(每秒帧数)。应与输入源(如摄像头或视频文件)的帧率匹配或根据需求设定。
  • frame_size: 视频帧的尺寸,以元组形式表示 (width, height)。​必须与你要写入的每一帧图像的尺寸完全一致!​
  • isColor (可选): 指定是否为彩色视频。默认为 True。如果写入灰度帧,设为 False 可能更高效。

核心方法​:

  • ​**out.write(frame)**​: 将一帧图像(frame,一个 NumPy 数组)写入视频文件。这是循环中最常用的方法。
  • ​**out.release()​: ​非常重要!​**​ 在完成所有帧的写入后,必须调用此方法来正确关闭视频文件,释放资源并确保文件完整可播。忘记调用会导致视频文件损坏或无法播放。

3. 完整工作流程示例

import cv2

# 1. 打开摄像头 (输入源)
cap = cv2.VideoCapture(0)  # 0 表示默认摄像头

# 2. 获取摄像头参数 (用于设置VideoWriter)
fps = cap.get(cv2.CAP_PROP_FPS)  # 获取摄像头帧率
# 如果摄像头返回0,设置一个合理的帧率 (如20)
if fps <= 0:
    fps = 20.0
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))  # 获取帧宽度
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))  # 获取帧高度
frame_size = (width, height)

# 3. 定义视频编码器 (FourCC) 和创建 VideoWriter 对象 (输出)
fourcc = cv2.VideoWriter_fourcc(*'XVID')  # 使用XVID编码器, 注意 '*' 解包
# 创建输出文件 'output.avi'
out = cv2.VideoWriter('output.avi', fourcc, fps, frame_size)

# 4. 循环处理每一帧
while cap.isOpened():
    # 读取一帧
    ret, frame = cap.read()
    if not ret:
        print("无法从摄像头读取帧!")
        break

    # 例如:将帧转换为灰度图 (实际项目中替换为你的AI模型推理)
    processed_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
   
    # 5. 将处理后的帧写入输出视频文件
    out.write(processed_frame)  # 写入处理后的帧

    # 6. (可选) 在本地显示结果
    cv2.imshow('Processed Video', processed_frame)

    # 按 'q' 键退出
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 7. 释放资源 (非常重要!)
cap.release()  # 释放摄像头
out.release()  # 释放VideoWriter,确保文件正确关闭
cv2.destroyAllWindows()  # 关闭所有窗口
print("视频已保存为 'output.avi'")

4.详解 cv2.waitKey(1):图像刷新与键盘输入的完美结合

  • cv2.waitKey(1) 是 OpenCV 图像处理中一个看似简单但极其重要的函数,它在实时应用中扮演着关键角色。
  • 函数原型:
  • retval = cv2.waitKey([, delay])
  • 参数:
  • delay: 等待键盘事件的时间(以毫秒为单位)。默认值为0。
  • 返回值:
  • retval: 返回按下的键的ASCII码值。如果没有按键被按下,则返回-1。

4.1 ​图像窗口刷新机制

  • cv2.waitKey() 是 OpenCV 窗口系统的事件处理核心
  • 调用此函数会强制刷新所有通过 cv2.imshow() 显示的窗口
  • 没有这个调用,窗口会显示为灰色或显示旧内容,无法更新为最新图像帧

4.2  ​键盘事件检测

  • 函数会检测并返回最近按下的按键的 ASCII 码值
  • 参数 1 表示等待时间为 ​1 毫秒,这是一个非阻塞式等待
  • 在等待期间,它会检查是否有按键事件发生

4.3 waitKey(0) - 无限等待

  • 程序会暂停,直到用户按下任意键
  • 常用于静态图像显示场景
  • 示例:显示一张图片后等待用户按键关闭窗口

4.4 waitKey(1) - 短时等待(推荐用于实时应用)

  • 等待 ​1 毫秒后继续执行
  • 在等待期间检查按键事件
  • 保持程序流畅运行的同时响应按键
  • 最佳实践​:在视频处理循环中使用

4.4  waitKey(25) - 控制帧率

  • 等待 25 毫秒 ≈ 40 FPS (1000ms/25ms)
  • 可用于控制视频播放速度

4.5 & 0xFF

  • waitKey() 返回的是 ​32 位整数
  • 在 64 位系统上,高位可能包含无关数据
  • & 0xFF 操作只保留最低的 8 位(一个字节)
  • 确保我们只获取有效的 ASCII 码值


网站公告

今日签到

点亮在社区的每一天
去签到