windows下如何通过ffmpeg提取文件夹下的mp4视频文件关键帧并另存为图片

大家好我是图恩,如果你经历过以前的胶卷电影时代,那么你应该明白当时的电影是怎么播放的,之所以叫胶卷,是因为当时的一部电影就是由一张张小的胶片拼接卷成一卷而来,有点像现在的胶带。

一部电影可能由成千上万张小的胶片制作而成,所谓的胶片,可以理解为就是一张照片,照片之间的画面呈现出连续的画面,以一定的速度拉动这盘交卷,然后通过光线穿过照片投射到荧幕上,就能看到会动的画面,也就是电影了。

所以实际上电影就是由一张张连续的图片拼接而来,只不过由于现代的设备越来越先进,这种原始的视频媒介早已淘汰。

明白了这个原理,我们可以将一个视频文件拆成一张张图片,然后再拼接起来,仍然能得到原来的电影。

所以如何将视频文件拆成一张张图片呢,我们可以通过鼎鼎大名的ffmpeg这款开源音视频软件实现。

软件的下载就不再赘述,到官网就能下载到文件,下载完成后需要将ffmpeg配置到系统环境中,方便通过命令行调用。

打开系统的环境变量,选择编辑path选项,将ffmpeg的bin目录添加到新建的变量中。

添加完成后就可以直接使用命令行来使用了,比如以下命令就是将名为input.mp4视频文件以每30帧的间隔提取一张图片,并且自动命名。

ffmpeg -i input.mp4 -vf "select='not(mod(n,30))',setpts=N/30/TB" -vsync 0 output_%03d.png

在现在的一些AI换脸视频的操作中比较常见,即先将原视频提取成图片,在重新绘制每一张图片,然后在拼接所有的图片,就可以达到换脸效果。

另外一种常用场景就是AI绘画的训练,通常情况AI绘画的训练需要大量的图片作为参考,通过对图片的分析识别,最终能生成跟参考图片相似效果的图片,比如stable diffusion的Lora训练。

通过拆解关键帧,然后将关键帧的图片投入到Lora的训练,就可以拥有自己的lora模型。

除了单个文件的关键帧提取,更重要的是批量提取,比如一下是一个文件下的所有mp4文件的关键帧提取。

@echo off
setlocal enabledelayedexpansion


rem 定义字符集
set "charset=abcdefghijklmnopqrstuvwxyz0123456789"


rem 设置视频源目录
@REM set "video_source=C:\Users\vis\Desktop\in"
set "video_source=C:\Users\vis\Desktop\in"
rem 设置图片输出目录
set "image_output=C:\Users\vis\Desktop\out"

rem 检查输出目录是否存在,不存在则创建
if not exist "%image_output%" mkdir "%image_output%"
set "frame_counter=0"
rem 遍历视频目录
for /R "%video_source%" %%i in (*.mp4) do (

    
    rem 获取视频文件的基本名称
    set basename=%%~ni
    echo Processing !basename!
    rem 构建完整的图片输出路径
    set "image_path=!image_output!\!basename!_frame_!frame_counter!_%%03d.png"
    @REM echo Processing "%%i"...
    echo Processing !image_path!
    ffmpeg -i "%%i" -vf "select='not(mod(n,30))',setpts=N/30/TB" -vsync 0 !image_path!
    @REM ffmpeg -i input.mp4 -vf "select='not(mod(n,30))',setpts=N/30/TB" -vsync 0 output_%03d.png
)

echo All videos processed.
pause
endlocal

新建一个bat后缀的批处理文件,将以上代码复制到其中,修改video_source跟image_output目录,就可以批量的提取该目录下的所有视频文件的关键帧了,不用一个个的去操作了。

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):