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

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

chanra1n2年前 (2023-07-10)Python4183

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

0.Python环境的搭建

0.Python环境的搭建

   请打开网页  https://www.python.org/downloads/windows/    Windows环境下的Python        这里我选择...

math库的使用

math库的使用

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

  索引运算符【】

索引运算符【】

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

random库

random库

random()            生成一个[0.0,1.0)之间的随机小数randint(a,b)     生成一个[a,b]之间的整数uniform(a,b)     生成一个[a,b]之间的随机小数对random库的引用方法与math库一样,采用下面两种方式实现:import random...

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

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

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

(原创)使用Python对任意网站图片进行爬取,仅用于学习

(原创)使用Python对任意网站图片进行爬取,仅用于学习

import os import time import argparse import requests import re import io from urllib.parse import ...