当前位置:首页 > Software > Python > 正文内容

(原创)使用FFmpeg截取多个视频中的图片,创建训练集

chanra1n1年前 (2023-07-10)Python4072

代码使用 Python 中的 subprocess 模块和 FFmpeg、FFprobe 工具来从视频文件中截取多个截图,并使用 PIL 库来检查截图文件是否损坏,如果损坏了就不保存该文件。

下面是代码的具体流程:

首先读取配置文件或命令行参数来指定截图数量、截图大小、截图时间间隔和截图质量等参数,并指定视频文件所在文件夹路径和截图保存文件夹路径以及 FFmpeg 和 FFprobe 的路径。

然后获取视频文件所在文件夹下的所有子文件夹名称,遍历每个子文件夹,对每个视频文件进行处理。

对于每个视频文件,使用 FFprobe 工具获取视频文件的总时长(duration),然后计算出要截取的多个截图的时间点和时间间隔。

对于每个视频文件,创建一个与视频文件同名的子文件夹,用于保存该视频文件的多个截图。

对于每个视频文件,使用 FFmpeg 工具在第1、第5、第10帧处截取三个截图,并在每隔一定时间间隔处截取 num_screenshots 个截图,共计 num_screenshots + 3 个截图。截图保存在之前创建的子文件夹中。

对于每个截图文件,使用 PIL 库打开该文件,如果文件无法正常打开,就说明该文件已经损坏,需要将其删除。

对于每个截图文件,检查其文件大小是否小于2KB,如果是则删除该文件。

如果处理视频文件时出现异常,就打印错误信息。

import os
import shlex
import subprocess
from PIL import Image

# 读取配置文件或命令行参数来指定截图数量、截图大小等参数
num_screenshots = 5
screenshot_size = '-1:480'
screenshot_interval = 'not(mod(n\,100))'
quality = '2'

# 视频文件所在文件夹路径和截图保存文件夹路径
video_folder = "C:/Users/ChanRa1n/Desktop/VideoLibary"
img_folder = "C:/Users/ChanRa1n/Desktop/TestVideo_img"

# FFmpeg和FFprobe的路径
ffmpeg_path = "C:/Program Files/ffmpeg-2023-07-10-git-1c61c24f5f-full_build/bin/ffmpeg"
ffprobe_path = "C:/Program Files/ffmpeg-2023-07-10-git-1c61c24f5f-full_build/bin/ffprobe"

# 获取所有子文件夹名称
subfolders = [f for f in os.listdir(video_folder) if os.path.isdir(os.path.join(video_folder, f))]

# 遍历所有子文件夹,对每个视频截取多个图片并保存到对应的子文件夹为名的目录下
for subfolder in subfolders:
    try:
        # 获取视频文件列表
        video_folder_path = os.path.join(video_folder, subfolder)
        video_files = [f for f in os.listdir(video_folder_path) if os.path.isfile(os.path.join(video_folder_path, f))]

        # 遍历视频文件列表,对每个视频截取多个图片
        for video_file in video_files:
            # 获取视频文件路径和文件名
            video_path = os.path.join(video_folder_path, video_file)
            video_name = os.path.splitext(video_file)[0]

            # 创建截图保存文件夹
            img_subfolder = os.path.join(img_folder, subfolder)
            os.makedirs(img_subfolder, exist_ok=True)

            # 截取多个图片,分别在第1、第5、第10帧和每隔一定时间间隔
            cmd = shlex.split(f"{ffprobe_path} -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 {shlex.quote(video_path)}")
            duration = float(subprocess.check_output(cmd).decode('utf-8').strip())

            interval = duration / (num_screenshots + 3)
            for i, time in enumerate([1, 5, 10]):
                img_name = f"{video_name}_{i+1}.jpg"
                img_path = os.path.join(img_subfolder, img_name)

                cmd = shlex.split(f"{ffmpeg_path} -ss {time} -i {shlex.quote(video_path)} -vframes 1 -q:v {quality} {shlex.quote(img_path)}")
                subprocess.run(cmd, check=True, shell=False)

                # 使用PIL库检查截图文件是否损坏,如果损坏了就删除该文件
                try:
                    with Image.open(img_path) as im:
                        pass
                except Exception as e:
                    os.remove(img_path)
                    continue

            for i in range(1, num_screenshots+1):
                img_name = f"{video_name}_{i+3}.jpg"
                img_path = os.path.join(img_subfolder, img_name)

                cmd = shlex.split(f"{ffmpeg_path} -ss {interval*(i-1)} -i {shlex.quote(video_path)} -vframes 1 -q:v {quality} {shlex.quote(img_path)}")
                subprocess.run(cmd, check=True, shell=False)

                # 使用PIL库检查截图文件是否损坏,如果损坏了就删除该文件
                try:
                    with Image.open(img_path) as im:
                        pass
                except Exception as e:
                    os.remove(img_path)

                # 检查文件大小,如果小于2KB则删除
                if os.path.getsize(img_path) < 2048:
                    os.remove(img_path)

    except Exception as e:
        print(f"Error processing videos in {subfolder}: {e}")


扫描二维码推送至手机访问。

版权声明:本文由我的FPGA发布,如需转载请注明出处。

本文链接:https://myfpga.cn/index.php/post/317.html

分享给朋友:

“(原创)使用FFmpeg截取多个视频中的图片,创建训练集” 的相关文章

1.Python基本的使用

1.Python基本的使用

我们打开python或者通过运行python也可以,请复制如下代码,然后按下Enter键,看看会发生什么?print('\n'.join([''.join([('MyFpga'[(x-y) % len('MyFpga'...

for循环

for循环

range()函数range(start,end,step)range()函数返回一个可迭代对象(可理解为一个序列,序列中的数包括start,不包括end)例如range(1,101),返回1-100的序列。range(101),范围0-100的序列。range(1,100,2),返回1,3,5.....

列表作为函数参数

列表作为函数参数

列表作为函数参数,函数中可以修改原列表def multiply(values,factor):     for i in range(len(values)):        values[i]*=factor          aList=[1,2,3,4,5]  multiply(aL...

一文快速搞定基本Python

一文快速搞定基本Python

本文适宜有熟练其他高级语言编程基础的同行参阅,或复习用,转载请保留作者信息 Myfpga.cn Chanra1n输入输出#input输入命令,中间的即提示语,左面的a为输入的值存到哪里 a=input("请输入a的值:") #print()可以直接print("He...

anaconda打不开的解决方法

anaconda打不开的解决方法

报错内容Navigator Error An unexpected error occurred on Navigator start-up Report Please report this ...

体温打卡python 可通过账户密码获取对应ID号

体温打卡python 可通过账户密码获取对应ID号

仅用于学习和测试,请勿自动填报或者干任何违法的事情import datetime import hashlib import random from urllib.parse import quote import req...