
cv2.videowriter是opencv中用于将图像帧写入视频文件的核心类。它的构造函数定义如下:
cv2.VideoWriter(filename, fourcc, fps, frameSize[, isColor])
参数解释:
许多用户在使用 cv2.VideoWriter 时,会遇到生成的文件大小很小(例如几百字节),且无法正常播放的问题。通过 mediainfo 等工具检查,文件似乎是合法的视频文件,但播放器(如 VLC)会报错,提示找不到集群或章节。
这个问题的根本原因在于 frameSize 参数的误用。图像处理中,我们习惯于 (高度, 宽度) 的顺序(例如 NumPy 数组的 shape 属性),但 cv2.VideoWriter 明确要求 (宽度, 高度)。如果传入的尺寸与实际帧的尺寸不匹配,或者顺序颠倒,VideoWriter 将无法正确写入视频流,导致生成空文件。
例如,如果你的图片是 120 像素高 x 160 像素宽,那么正确的 frameSize 应该是 (160, 120),而不是 (120, 160)。
以下是修正后的代码示例,演示如何正确使用 cv2.VideoWriter 从一系列 JPG 图片生成视频:
import cv2
import os # 用于检查文件是否存在,非必需
def create_video_from_images(image_prefix, start_index, end_index, output_filename, fps):
"""
使用OpenCV从一系列图片生成视频文件。
Args:
image_prefix (str): 图片文件名前缀,例如 "capture."
start_index (int): 图片文件名的起始索引(包含)。
end_index (int): 图片文件名的结束索引(包含)。
output_filename (str): 输出视频文件名,例如 "py_test.mkv" 或 "output.mp4"。
fps (float): 视频帧率。
"""
# 1. 读取第一张图片以获取正确的帧尺寸
# 假设图片命名为 capture.0.jpg, capture.1.jpg, ...
first_image_path = f"{image_prefix}{start_index}.jpg"
first_img = cv2.imread(first_image_path)
if first_img is None:
print(f"错误:无法读取第一张图片 {first_image_path}。请检查路径和文件名。")
return
# 核心修正:frame_size 必须是 (宽度, 高度)
# img.shape 返回 (高度, 宽度, 通道数)
frame_height, frame_width, _ = first_img.shape
frame_size = (frame_width, frame_height)
print(f"检测到图片尺寸:宽度={frame_width}, 高度={frame_height}。")
# 2. 定义视频编码器 (FOURCC)
# 不同的编码器和容器组合有不同的兼容性。
# 常用且兼容性较好的组合:
# - 'XVID' 或 'DIVX' for .avi
# - 'mp4v' 或 'H264' for .mp4
# - 'x264' for .mkv (通常需要系统安装H.264编码器支持)
# 注意:某些编码器可能需要系统额外安装相应的库。
# 示例使用 'XVID',通常兼容性较好,适用于 .avi
# fourcc = cv2.VideoWriter.fourcc(*'XVID')
# 示例使用 'mp4v',适用于 .mp4
# fourcc = cv2.VideoWriter.fourcc(*'mp4v')
# 示例使用 'x264',适用于 .mkv 或 .mp4,如果系统支持H.264编码
# 确保输出文件扩展名与选择的fourcc兼容
fourcc = cv2.VideoWriter.fourcc(*'x264')
# 3. 初始化 VideoWriter 对象
print(f"尝试初始化 VideoWriter: 文件='{output_filename}', 编码='{fourcc}', FPS={fps}, 尺寸={frame_size}")
out = cv2.VideoWriter(output_filename, fourcc, fps, frame_size)
# 检查 VideoWriter 是否成功打开
if not out.isOpened():
print(f"错误:无法打开视频写入器 '{output_filename}'。")
print("可能原因:")
print(" - 指定的 FourCC 编码器不受系统支持。")
print(" - 输出文件路径无效或没有写入权限。")
print(" - 输出文件扩展名与 FourCC 编码器不兼容。")
print(" - 尝试更换 FourCC 编码器或输出文件扩展名。")
return
# 4. 遍历图片并写入视频
print(f"开始写入 {end_index - start_index + 1} 帧到视频...")
for i in range(start_index, end_index + 1):
img_path = f"{image_prefix}{i}.jpg"
img = cv2.imread(img_path)
if img is None:
print(f"警告:无法读取图片 {img_path}。跳过此帧。")
continue
# 确保读取的图片尺寸与VideoWriter期望的尺寸一致
# 如果不一致,可以选择跳过或进行resize
if img.shape[1] != frame_size[0] or img.shape[0] != frame_size[1]:
print(f"警告:图片 {img_path} 尺寸为 {img.shape[1]}x{img.shape[0]},与视频预期尺寸 {frame_size[0]}x{frame_size[1]} 不符。将进行缩放。")
img = cv2.resize(img, frame_size)
out.write(img)
# print(f"已写入帧 {i}")
# 5. 释放 VideoWriter 对象
# 这一步至关重要,它会关闭文件并确保所有缓存的帧都已写入。
out.release()
print(f"视频 '{output_filename}' 已成功创建。")
# --- 示例用法 ---
if __name__ == "__main__":
# 请确保在运行此脚本前,在当前目录下有 'capture.0.jpg' 到 'capture.120.jpg' 这些图片文件。
# 可以通过以下方式生成一些虚拟图片用于测试:
# import numpy as np
# for i in range(121):
# # 创建一个 120高 x 160宽 的黑色图片
# dummy_image = np.zeros((120, 160, 3), dtype=np.uint8)
# # 可选:在图片上绘制一些内容以便区分
# cv2.putText(dummy_image, str(i), (50, 60), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2, cv2.LINE_AA)
# cv2.imwrite(f"capture.{i}.jpg", dummy_image)
# print("虚拟图片已生成。")
image_prefix = "capture."
start_index = 0
end_index = 120 # 如果是 capture.0.jpg 到 capture.120.jpg,共121张
output_video_file = "py_test.mkv" # 也可以是 "py_test.mp4", "py_test.avi"
frame_rate = 60.0
create_video_from_images(image_prefix, start_index, end_index, output_video_file, frame_rate)
# 验证文件是否生成且大小正常(大于几百字节)
if os.path.exists(output_video_file):
file_size = os.path.getsize(output_video_file)
print(f"生成的视频文件 '{output_video_file}' 大小为 {file_size} 字节。")
if file_size < 1024: # 简单判断,实际视频文件应远大于此
print("警告:文件大小异常,可能仍存在问题。")
else:
print(f"错误:视频文件 '{output_video_file}' 未生成。")
通过准确理解并正确设置 cv2.VideoWriter 的 frameSize 参数(即 (宽度, 高度)),并结合合适的 fourcc 编码器、容器选择以及调用 release() 方法,可以有效避免生成空文件或无法播放的视频。在遇到问题时,系统性地检查这些关键点将大大提高故障排除的效率。
以上就是OpenCV视频写入空文件:尺寸参数的常见陷阱与解决方案的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号