用python写一个把视频每一帧提取为png图片
在运行此代码之前,请确保您已经安装了OpenCV
库。如果没有安装,可以使用以下命令进行安装:
bash
pip install opencv-python
下面是提取视频帧的Python脚本:
python
import cv2
# 视频文件路径
video_path = 'input_video.mp4'
# 读取视频文件
cap = cv2.VideoCapture(video_path)
# 获取视频的帧率
fps = int(cap.get(cv2.CAP_PROP_FPS))
# 获取视频的总帧数
frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
# 初始化帧计数器
frame_count_init = 0
# 检查是否成功打开视频文件
if not cap.isOpened():
print(f"无法打开视频文件: {video_path}")
else:
while True:
# 逐帧读取视频
ret, frame = cap.read()
# 如果读取帧失败,则退出循环
if not ret:
print("视频读取完毕或发生错误")
break
# 构建输出图片的文件名
frame_filename = f'frame_{frame_count_init:04d}.png'
# 保存帧为PNG图片
cv2.imwrite(frame_filename, frame)
print(f"已保存: {frame_filename}")
# 更新帧计数器
frame_count_init += 1
# 释放视频捕获对象
cap.release()
以下是对这段程序的介绍:
一、程序功能
该程序的主要功能是将指定的视频文件逐帧拆分为单独的 PNG 图片进行保存。
二、程序实现步骤
- 首先指定了要处理的视频文件路径
video_path = 'input_video.mp4'
。 - 接着使用
cv2.VideoCapture()
函数读取视频文件,并将其存储在cap
对象中。- 通过
cap.get(cv2.CAP_PROP_FPS)
获取视频的帧率,存储在fps
变量中。 - 通过
cap.get(cv2.CAP_PROP_FRAME_COUNT)
获取视频的总帧数,存储在frame_count
变量中。 - 初始化帧计数器
frame_count_init
为 0。
- 通过
- 然后检查视频文件是否成功打开,如果没有成功打开,则输出错误信息。如果成功打开,则进入循环处理每一帧。
- 在循环中,使用
cap.read()
逐帧读取视频,返回值ret
表示是否成功读取一帧,frame
表示读取到的帧图像。 - 如果读取帧失败,说明视频读取完毕或发生错误,退出循环。
- 构建输出图片的文件名,格式为
frame_{帧计数器:04d}.png
,确保文件名以四位数的帧序号命名,不足四位前面补零。 - 使用
cv2.imwrite()
函数将当前帧保存为 PNG 图片。 - 最后更新帧计数器。
- 在循环中,使用
- 程序最后使用
cap.release()
释放视频捕获对象,以释放资源。
你会发现这个程序无法实现用户自定义选择视频路径,还有输出的时候直接输出到当前目录,可能会导致文件夹很乱,所以需要优化一下:
- 添加图形化选择视频路径功能,使用tk库
- 修改图片输出目录,在当前文件夹创建一个名为
output
的目录,图片输出到该目录下
为了添加图形化选择视频文件的功能,我们可以使用tkinter库来创建一个简单的图形用户界面(GUI)。以下是修改后的代码,它允许用户通过文件对话框选择视频文件,并将提取的帧保存到名为output
的文件夹中。
请确保您已经安装了opencv-python
和tkinter
(通常它是Python标准库的一部分,不需要单独安装)。
下面是提取视频帧的Python脚本:
python
import cv2
import os
from tkinter import filedialog, Tk
# 创建一个Tkinter根窗口并隐藏
root = Tk()
root.withdraw()
# 使用文件对话框选择视频文件
video_path = filedialog.askopenfilename(title="选择视频文件", filetypes=[("视频文件", "*.mp4;*.avi;*.mov")])
# 检查是否选择了文件
if video_path:
# 创建output文件夹,如果不存在的话
output_folder = 'output'
if not os.path.exists(output_folder):
os.makedirs(output_folder)
# 读取视频文件
cap = cv2.VideoCapture(video_path)
# 获取视频的帧率
fps = int(cap.get(cv2.CAP_PROP_FPS))
# 获取视频的总帧数
frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
# 初始化帧计数器
frame_count_init = 0
# 检查是否成功打开视频文件
if not cap.isOpened():
print(f"无法打开视频文件: {video_path}")
else:
while True:
# 逐帧读取视频
ret, frame = cap.read()
# 如果读取帧失败,则退出循环
if not ret:
print("视频读取完毕或发生错误")
break
# 构建输出图片的文件名
frame_filename = f'frame_{frame_count_init:04d}.png'
# 完整的输出路径
output_path = os.path.join(output_folder, frame_filename)
# 保存帧为PNG图片
cv2.imwrite(output_path, frame)
print(f"已保存: {output_path}")
# 更新帧计数器
frame_count_init += 1
# 释放视频捕获对象
cap.release()
else:
print("没有选择视频文件")
程序实现步骤
-
用户选择视频文件:
- 创建一个隐藏的 Tkinter 根窗口。
- 使用
filedialog.askopenfilename
函数弹出文件对话框,让用户选择视频文件。支持的视频文件类型包括.mp4
、.avi
和.mov
。 - 如果用户选择了文件,视频文件的路径将存储在
video_path
变量中;如果用户未选择文件,则输出提示信息并结束程序。
-
处理视频文件:
- 如果选择了视频文件,首先检查是否存在名为"output"的文件夹,如果不存在则创建该文件夹,用于保存输出的图片。
- 使用
cv2.VideoCapture()
读取视频文件,并存储在cap
对象中。 - 像之前的程序一样,获取视频的帧率和总帧数,并初始化帧计数器。
- 检查视频文件是否成功打开,如果未成功打开则输出错误信息。
- 在循环中逐帧读取视频,对于每一帧:
- 构建输出图片的文件名,格式为
frame_{帧计数器:04d}.png
。 - 确定完整的输出路径,即"output"文件夹加上文件名。
- 使用
cv2.imwrite()
将当前帧保存为 PNG 图片到指定路径。 - 更新帧计数器。
- 构建输出图片的文件名,格式为
- 循环结束后,释放视频捕获对象以释放资源。