
opencv 提供了 cv2.videowriter 类,用于将一系列图像帧写入视频文件。它是图像处理和计算机视觉应用中创建视频输出的关键工具。正确理解和配置其参数对于生成有效的视频文件至关重要。
cv2.VideoWriter 的构造函数通常接收以下参数:
创建 VideoWriter 对象后,可以使用 write() 方法逐帧写入图像,并在所有帧写入完毕后调用 release() 方法释放资源并完成文件写入。
在实际应用中,许多开发者在使用 cv2.VideoWriter 时会遇到一个令人困惑的问题:代码运行没有报错,也生成了视频文件,但文件大小极小(通常只有几百字节),且无法正常播放。通过媒体信息工具检查,文件结构似乎不完整,例如 VLC 播放器可能会提示“无法找到任何集群或章节”。
这个问题的根本原因在于 frameSize 参数的误用。当从图像(如 NumPy 数组)获取尺寸时,我们通常习惯于 img.shape 返回 (height, width, channels) 的顺序。然而,cv2.VideoWriter 的 frameSize 参数却明确要求 (width, height) 的顺序。
错误示例:
假设你有一张尺寸为 120 像素高 x 160 像素宽的图片。当你读取这张图片并检查其 shape 时,你会得到 (120, 160, 3) (对于彩色图片)。如果直接将 (120, 160) 作为 frameSize 传递给 VideoWriter,即:
import cv2
# 假设图片尺寸是 160宽 x 120高
# 错误地将 (height, width) 传递给 frameSize
fourcc = cv2.VideoWriter.fourcc(*'x264')
# 错误的 frameSize: [120, 160] (实际是 height, width)
writer = cv2.VideoWriter("py_test_error.mkv", fourcc, 60.0, [120, 160])
def record_error(writer_obj):
for i in range(121):
img = cv2.imread(f"capture.{i}.jpg") # 假设图片是 160x120
if img is None:
print(f"Error: Could not read image capture.{i}.jpg")
continue
writer_obj.write(img)
record_error(writer)
writer.release() # 释放资源
print("视频文件生成完毕,但可能为空。")在这种情况下,VideoWriter 期望的帧尺寸是 120 像素宽 x 160 像素高,而你实际写入的图像是 160 像素宽 x 120 像素高。尺寸不匹配导致 VideoWriter 无法正确处理帧数据,从而生成一个空的或损坏的视频文件。
解决这个问题的关键在于确保 frameSize 参数的值严格遵循 (width, height) 的顺序,并且与你实际写入的图像帧的尺寸相匹配。
正确示例:
如果你的图片是 160 像素宽 x 120 像素高,那么 frameSize 应该设置为 [160, 120]。
import cv2
import os
# 假设当前目录下有 capture.0.jpg 到 capture.120.jpg 共121张图片
# 这些图片尺寸均为 160宽 x 120高
def record_frames(writer_obj):
for i in range(121):
img_path = f"capture.{i}.jpg"
img = cv2.imread(img_path)
if img is None:
print(f"警告: 无法读取图像 {img_path},跳过此帧。")
continue
# 确保写入的图像尺寸与 VideoWriter 期望的 frameSize 一致
writer_obj.write(img)
print("所有图像帧已写入。")
# 1. 定义输出文件路径和编解码器
output_filename = "py_test_correct.mkv"
# 推荐使用 'mp4v' 或 'XVID' 对于 .mp4/.avi 容器,
# 'x264' 对于 .mkv 容器通常效果更好,但需要系统支持。
fourcc = cv2.VideoWriter.fourcc(*'x264')
# 2. 定义帧率
fps = 60.0
# 3. 定义正确的帧尺寸:(宽度, 高度)
# 假设图片是 160宽 x 120高
frame_width = 160
frame_height = 120
frame_size = (frame_width, frame_height)
# 4. 创建 VideoWriter 对象
try:
writer = cv2.VideoWriter(output_filename, fourcc, fps, frame_size)
if not writer.isOpened():
print(f"错误: 无法打开视频写入器。请检查编解码器和文件路径。")
else:
print(f"成功创建 VideoWriter 对象,准备写入 {output_filename}")
# 5. 写入所有帧
record_frames(writer)
print(f"视频文件 '{output_filename}' 生成完毕。")
except Exception as e:
print(f"发生异常: {e}")
finally:
# 6. 释放 VideoWriter 资源,确保文件被正确写入和关闭
if 'writer' in locals() and writer.isOpened():
writer.release()
print("VideoWriter 资源已释放。")在上述代码中,frame_size = (frame_width, frame_height) 确保了 VideoWriter 接收到的是正确的宽度和高度顺序,从而解决了生成空文件的问题。
以上就是OpenCV VideoWriter 常见陷阱:如何避免生成空视频文件的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号