讲师中心 微信公众号
AI工具推荐 视频效率加速

OpenCV VideoWriter 常见陷阱:如何避免生成空视频文件

老磊大大_2095

老磊大大_2095

发布时间:2025-08-14 18:48:01

|

477人浏览过

|

来源于php中文网

原创

OpenCV VideoWriter 常见陷阱:如何避免生成空视频文件

本文深入探讨了使用 OpenCV VideoWriter 模块生成视频时常见的“空文件”问题。核心原因在于 VideoWriter 的 frameSize 参数误将图像的 (height, width) 顺序传递为 (width, height)。教程将详细解释 VideoWriter 的正确用法、参数配置,并通过示例代码演示如何避免此陷阱,确保成功创建可播放的视频文件。

OpenCV VideoWriter 详解

opencv 提供了 cv2.videowriter 类,用于将一系列图像帧写入视频文件。它是图像处理和计算机视觉应用中创建视频输出的关键工具。正确理解和配置其参数对于生成有效的视频文件至关重要。

cv2.VideoWriter 的构造函数通常接收以下参数:

  • filename: 输出视频文件的路径和名称(例如 "output.mp4")。
  • fourcc: 视频编解码器。这是一个四字符代码(FourCC),用于指定视频流的压缩格式。例如,cv2.VideoWriter_fourcc(*'XVID') 或 cv2.VideoWriter_fourcc(*'mp4v')。不同的操作系统和 OpenCV 版本可能支持不同的编解码器,并且编解码器与文件容器(如 .mp4, .avi, .mkv)之间存在兼容性要求。
  • fps: 视频的帧率(每秒帧数)。
  • frameSize: 视频帧的尺寸,通常是一个 (width, height) 的元组或列表。这是本文要重点讨论的关键参数。
  • isColor: 可选参数,布尔值,表示视频是否为彩色。默认为 True。如果为 False,则表示灰度视频。

创建 VideoWriter 对象后,可以使用 write() 方法逐帧写入图像,并在所有帧写入完毕后调用 release() 方法释放资源并完成文件写入。

核心问题:frameSize 参数的陷阱

在实际应用中,许多开发者在使用 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,即:

Alpine Linux
Alpine Linux

获取最新发布版本;聚合最新版本架构

下载
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 接收到的是正确的宽度和高度顺序,从而解决了生成空文件的问题。

注意事项与最佳实践

  1. writer.release() 的重要性: 无论视频写入成功与否,务必在所有帧写入完毕后调用 writer.release()。这个方法会关闭文件句柄,刷新缓冲区,并完成视频文件的最终写入。如果忘记调用,即使代码没有报错,生成的视频文件也可能损坏或无法播放。将其放在 finally 块中是良好的编程习惯,确保即使发生异常也能被调用。
  2. fourcc 编解码器与容器的兼容性:
    • 不同的编解码器 (fourcc) 与文件容器(.mp4, .avi, .mkv 等)之间存在兼容性。例如,'mp4v' 和 'XVID' 通常用于 .mp4 或 .avi 文件,而 'x264' 更常用于 .mkv 或 .mp4 (如果系统支持 H.264 编码)。
    • 如果 fourcc 不受系统支持或与容器不兼容,writer.isOpened() 可能会返回 False,或者生成的文件无法播放。在 Linux 系统上,确保安装了 ffmpeg 或 gstreamer 等后端库,因为 OpenCV 依赖它们进行视频编解码。
    • 尝试不同的 fourcc 代码和文件扩展名组合,直到找到一个适合你系统和需求的。常见的 FourCCs 包括:
      • `*'mp

热门AI工具

更多
PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

相关专题

更多
磁盘配额是什么
磁盘配额是什么

磁盘配额是计算机中指定磁盘的储存限制,就是管理员可以为用户所能使用的磁盘空间进行配额限制,每一用户只能使用最大配额范围内的磁盘空间。php中文网为大家提供各种磁盘配额相关的内容,教程,供大家免费下载安装。

3890

2023.06.21

如何安装LINUX
如何安装LINUX

本站专题提供如何安装LINUX的相关教程文章,还有相关的下载、课程,大家可以免费体验。

3333

2023.06.29

linux find
linux find

find是linux命令,它将档案系统内符合 expression 的档案列出来。可以指要档案的名称、类别、时间、大小、权限等不同资讯的组合,只有完全相符的才会被列出来。find根据下列规则判断 path 和 expression,在命令列上第一个 - ( ) , ! 之前的部分为 path,之后的是 expression。还有指DOS 命令 find,Excel 函数 find等。本站专题提供linux find相关教程文章,还有相关

2493

2023.06.30

linux修改文件名
linux修改文件名

本专题为大家提供linux修改文件名相关的文章,这些文章可以帮助用户快速轻松地完成文件名的修改工作,大家可以免费体验。

5990

2023.07.05

linux系统安装教程
linux系统安装教程

linux系统是一种可以免费使用,自由传播,多用户、多任务、多线程、多CPU的操作系统。本专题提供linux系统安装教程相关的文章,大家可以免费体验。

5642

2023.07.06

linux查看文件夹大小
linux查看文件夹大小

Linux是一种自由和开放源码的类Unix操作系统,存在着许多不同的Linux版本,但它们都使用了Linux内核。Linux可安装在各种计算机硬件设备中,比如手机、平板电脑、路由器、视频游戏控制台、台式计算机、大型机和超级计算机。linux怎么查看文件夹大小呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

3313

2023.07.20

linux查看ip命令
linux查看ip命令

本专题为大家提供linux查看ip命令相关文章内容,感兴趣的朋友可以免费下载体验试试。

2825

2023.07.20

linux查看cpu使用率
linux查看cpu使用率

在linux的系统维护中,可能需要经常查看cpu使用率,分析系统整体的运行情况。本专题为大家带来了linux查看cpu使用率的相关文章,感兴趣的朋友千万不要错过了。

3039

2023.07.25

FrankenPHP集成Laravel详细教程
FrankenPHP集成Laravel详细教程

本专题提供FrankenPHP集成Laravel的详细配置指南,全面解析运行原理、开发环境搭建、Caddyfile配置、Octane工作模式、数据库连接、队列任务、定时任务和生产环境优化,解决部署过程中常见的报错与兼容性问题。

0

2026.10.08

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Buffalo框架快速入门指南
Buffalo框架快速入门指南

共0课时 | 0人学习

Valgrind支持平台说明
Valgrind支持平台说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn