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

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

chanra1n2年前 (2023-07-10)Python4740

代码使用 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截取多个视频中的图片,创建训练集” 的相关文章

math库的使用

math库的使用

math库包括4个数学常数math.pi      圆周率math.e       自然对数math.inf     正无穷大,负无穷大为-math.infmath.nan     非浮点数标记math库常用函数math.cell(x)      向上取整,返回不小于x的最小整数math.facto...

搜索字符串

搜索字符串

常用搜索字符串中子串的方法str.count(substring)      返回str中substring子串出现的无覆盖的次数str.find(s1)                    返回s1在这个字符串的最低下标,如果字符串中不存在s1,则返回-1str.rfind(s1)       ...

一文快速搞定基本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...

Python自动清理错误图片,深度学习训练数据集准备

Python自动清理错误图片,深度学习训练数据集准备

使用python运行from PIL import Image from pathlib import Path import os   path = r'.'  ...