Python基于 OpenCV 的视频与图片互转实现
本文介绍了使用OpenCV和Python实现视频与帧图片相互转换的技术。视频转帧功能可设定保存间隔,将视频逐帧或按间隔保存为图片;帧图片转视频则可将图片序列合成为视频。文章提供了详细的核心函数定义和使用示例,包括路径参数设置和间隔帧数控制,完整解析了两种转换的实现方法,为计算机视觉和视频处理领域的基础操作提供了实用解决方案。
·
在计算机视觉和视频处理领域,视频与帧图片的相互转换是一项基础且重要的技术。本文将分享如何使用 OpenCV 和 Python 实现视频转帧图片以及帧图片转视频的功能,并提供完整代码解析。
1.视频转帧图片功能解析
(1)核心函数定义如下:
video_path (str): 输入视频文件的路径
output_folder (str): 保存图片的目标文件夹
every_n_frames (int): 每隔多少帧保存一次,默认为1(逐帧保存)
import cv2
import os
def video_to_images(video_path, output_folder, every_n_frames=1):
"""
从视频中按指定间隔提取帧并保存为图片序列
参数:
video_path (str): 输入视频文件的路径
output_folder (str): 保存图片的目标文件夹
every_n_frames (int): 每隔多少帧保存一次,默认为1(逐帧保存)
"""
# 创建输出文件夹(如果不存在)
# exist_ok=True确保文件夹不存在时创建,存在时不报错
os.makedirs(output_folder, exist_ok=True)
# 打开视频文件
# cv2.VideoCapture可以处理多种视频格式和摄像头输入
cap = cv2.VideoCapture(video_path)
# 检查视频是否成功打开
# 失败可能由于文件不存在、格式不支持或权限问题
if not cap.isOpened():
print(f"错误: 无法打开视频文件 {video_path}")
return False
# 初始化计数器
# frame_count: 记录当前处理的总帧数
# saved_count: 记录实际保存的帧数
frame_count = saved_count = 0
# 循环读取视频帧
while True:
# 读取一帧视频
# ret: 布尔值,表示是否成功读取帧
# frame: 包含帧图像数据的numpy数组
ret, frame = cap.read()
# 检查是否成功读取帧
# 若失败,说明已到达视频末尾或发生错误
if not ret:
break
# 按指定间隔保存帧
# 例如every_n_frames=10时,每10帧保存一次
if frame_count % every_n_frames == 0:
# 生成格式化文件名,如"frame_0001.jpg"
# :04d确保数字部分始终为4位,不足补零
filename = f"frame_{saved_count+1:04d}.jpg"
# 保存帧为JPEG图片
# os.path.join确保路径分隔符在不同系统上的兼容性
cv2.imwrite(os.path.join(output_folder, filename), frame)
# 更新保存的帧数计数器
saved_count += 1
# 更新总帧数计数器
frame_count += 1
# 释放视频资源
# 必须调用以关闭视频文件并释放内存
cap.release()
print(f"成功从视频中提取 {saved_count} 帧,保存至 {output_folder}")
return True
(2)使用实例:
if __name__ == "__main__":
# 配置参数(使用前请根据实际情况修改)
INPUT_VIDEO = "./mpandpic/input.mp4" # 输入视频文件路径
OUTPUT_FOLDER = "./mpandpic/images" # 输出图片文件夹
EVERY_N_FRAMES = 10 # 每隔10帧保存一次,可调整以控制提取密度
# 调用函数执行视频帧提取
success = video_to_images(INPUT_VIDEO, OUTPUT_FOLDER, EVERY_N_FRAMES)
if success:
print("视频帧提取完成")
else:
print("视频帧提取失败")
运行完成之后打开输出图片文件夹:

2.帧图片转视频功能解析
(1)核心函数定义如下:
import cv2
import os
def images_to_video(image_folder, output_path, fps=30.0):
"""
将指定文件夹中的图片序列合成为视频文件
参数:
image_folder (str): 包含图片序列的文件夹路径
output_path (str): 输出视频文件的路径
fps (float): 视频帧率(每秒显示的帧数),默认为30.0
"""
# 定义支持的图片格式扩展名
valid_extensions = ('jpg', 'jpeg', 'png', 'bmp')
# 获取文件夹中所有文件,并筛选出符合条件的图片文件
# 使用sorted确保文件按名称排序,保证视频帧顺序正确
image_files = sorted(
f for f in os.listdir(image_folder)
if f.lower().endswith(valid_extensions)
)
# 检查是否存在符合条件的图片
if not image_files:
print(f"错误: 在 {image_folder} 中未找到支持的图片文件")
return False # 无图片时返回失败状态
# 读取第一张图片以获取视频尺寸
# shape属性返回(height, width, channels)三元组,取前两个值
first_image = cv2.imread(os.path.join(image_folder, image_files[0]))
height, width = first_image.shape[:2]
# 创建视频写入器对象
# fourcc指定视频编码格式,'mp4v'对应MP4格式
# fps参数控制视频播放速度
# (width, height)指定视频帧尺寸,必须与图片尺寸一致
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
# 遍历所有图片文件,逐帧写入视频
for image_name in image_files:
# 读取图片并写入视频
# 注意:所有图片应保持相同尺寸,否则可能导致视频生成失败
frame = cv2.imread(os.path.join(image_folder, image_name))
out.write(frame)
# 释放视频写入器资源,必须调用以完成视频写入
out.release()
print(f"视频已成功保存至: {output_path}")
return True # 返回成功状态
(2)使用实例:
if __name__ == "__main__":
# 配置参数(使用前请根据实际情况修改)
IMAGE_FOLDER = "./mpandpic/images" # 包含图片序列的文件夹
OUTPUT_VIDEO = "./mpandpic/output.mp4" # 输出视频文件路径
FPS = 3 # 视频帧率,控制播放速度
# 调用函数执行图片转视频操作
success = images_to_video(IMAGE_FOLDER, OUTPUT_VIDEO, FPS)
if success:
print("视频生成成功")
else:
print("视频生成失败")
运行结果:

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)