当前位置: 首页 > article >正文

【 用python写一个把视频每一帧提取为png图片】

用python写一个把视频每一帧提取为png图片

在运行此代码之前,请确保您已经安装了OpenCV库。如果没有安装,可以使用以下命令进行安装:

pip install opencv-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 图片进行保存。

二、程序实现步骤

  1. 首先指定了要处理的视频文件路径 video_path = 'input_video.mp4'
  2. 接着使用 cv2.VideoCapture() 函数读取视频文件,并将其存储在 cap 对象中。
    • 通过 cap.get(cv2.CAP_PROP_FPS) 获取视频的帧率,存储在 fps 变量中。
    • 通过 cap.get(cv2.CAP_PROP_FRAME_COUNT) 获取视频的总帧数,存储在 frame_count 变量中。
    • 初始化帧计数器 frame_count_init 为 0。
  3. 然后检查视频文件是否成功打开,如果没有成功打开,则输出错误信息。如果成功打开,则进入循环处理每一帧。
    • 在循环中,使用 cap.read() 逐帧读取视频,返回值 ret 表示是否成功读取一帧,frame 表示读取到的帧图像。
    • 如果读取帧失败,说明视频读取完毕或发生错误,退出循环。
    • 构建输出图片的文件名,格式为 frame_{帧计数器:04d}.png,确保文件名以四位数的帧序号命名,不足四位前面补零。
    • 使用 cv2.imwrite() 函数将当前帧保存为 PNG 图片。
    • 最后更新帧计数器。
  4. 程序最后使用 cap.release() 释放视频捕获对象,以释放资源。

你会发现这个程序无法实现用户自定义选择视频路径,还有输出的时候直接输出到当前目录,可能会导致文件夹很乱,所以需要优化一下:

  • 添加图形化选择视频路径功能,使用tk库
  • 修改图片输出目录,在当前文件夹创建一个名为output的目录,图片输出到该目录下
    为了添加图形化选择视频文件的功能,我们可以使用tkinter库来创建一个简单的图形用户界面(GUI)。以下是修改后的代码,它允许用户通过文件对话框选择视频文件,并将提取的帧保存到名为output的文件夹中。
    请确保您已经安装了opencv-pythontkinter(通常它是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("没有选择视频文件")

程序实现步骤

  1. 用户选择视频文件

    • 创建一个隐藏的 Tkinter 根窗口。
    • 使用 filedialog.askopenfilename 函数弹出文件对话框,让用户选择视频文件。支持的视频文件类型包括 .mp4.avi.mov
    • 如果用户选择了文件,视频文件的路径将存储在 video_path 变量中;如果用户未选择文件,则输出提示信息并结束程序。
  2. 处理视频文件

    • 如果选择了视频文件,首先检查是否存在名为“output”的文件夹,如果不存在则创建该文件夹,用于保存输出的图片。
    • 使用 cv2.VideoCapture() 读取视频文件,并存储在 cap 对象中。
    • 像之前的程序一样,获取视频的帧率和总帧数,并初始化帧计数器。
    • 检查视频文件是否成功打开,如果未成功打开则输出错误信息。
    • 在循环中逐帧读取视频,对于每一帧:
      • 构建输出图片的文件名,格式为 frame_{帧计数器:04d}.png
      • 确定完整的输出路径,即“output”文件夹加上文件名。
      • 使用 cv2.imwrite() 将当前帧保存为 PNG 图片到指定路径。
      • 更新帧计数器。
    • 循环结束后,释放视频捕获对象以释放资源。

http://www.kler.cn/news/359297.html

相关文章:

  • 【鸡翅Club】项目启动
  • HAL+M4学习记录_8
  • MySQL常见优化策略
  • xRDP – 在 Ubuntu 18.04、20.04、22.04、22.10、23.04(脚本版本 1.4.7)上轻松安装 xRDP
  • 如何使用外呼电话机器人的功能可以更高效的获客?
  • 高可用之限流-07-token bucket 令牌桶算法
  • hive on tez 指定队列后任务一直处于running状态
  • 开发规范 - mac系统1小时装机极速装机开发环境
  • 软件定义汽车时代,当前智能汽车软件开发模式是什么?
  • 探究互联网数字化商品管理变革:从数据化到精准运营的路径转型
  • 数据结构与算法JavaScript描述练习------第14章高级算法
  • CTFHUB技能树之SQL——整数型注入
  • .net framework 3.5sp1插件怎么安装
  • 【机器学习】任务七:聚类算法 (K-means 算法、层次聚类、密度聚类对鸢尾花(Iris)数据进行聚类)
  • 什么SNMP协议,怎么使用python调用SNMP访问设备
  • 【移动应用开发】界面设计(二)实现水果列表页面
  • 关于测试用例的写法
  • 云原生-降本增效最佳案例分享-学习笔记
  • WEB前端作业1
  • GO语言指针有那些限制