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

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

chanra1n1年前 (2023-07-10)Python3918

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

0.Python环境的搭建

0.Python环境的搭建

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

Python关于turtle的函数名

Python关于turtle的函数名

turtle.forward(distance)                   向当前画笔方向移动distance像素长度turtle.backward(distance)              向当前画笔相反方向移动distance像素长度turtle.right(degree)    ...

math库的使用

math库的使用

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

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.....

random库

random库

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