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

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

chanra1n1年前 (2023-07-10)Python3868

代码使用 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://world.myfpga.cn/index.php/post/317.html

分享给朋友:

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

1.Python基本的使用

1.Python基本的使用

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

2.Python中的基本运算

2.Python中的基本运算

我们打开Python,请你尝试输入如下算式并尝试理解有什么为什么是这样的?1+1 1+1.0 1-2 2-3.5 1*1 1*1.1 1/2 2/1 2/3 3/2 3//2 3/1.0 5/2.5我们不难得到如下结果2 2.0 -1 -1.5 1 1.1 0.5...

  索引运算符【】

索引运算符【】

选择字符串的子序列语法【start:finish】        start:子序列开始位置的索引值        finish:子序列结束位置的下一个字符的索引值如果不提供start或者finish,默认start为第一个字符,finish为最后一个字符。例如>>>my_str=...

搜索字符串

搜索字符串

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

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

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

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