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

ppylox
·5/20/2024·0 阅读
AI 摘要模型根据正文自动生成,仅供参考

本文介绍在Windows下用ffmpeg提取文件夹内MP4视频关键帧并保存为图片的方法。先将ffmpeg的bin目录加入系统Path,再用命令`ffmpeg -i input.mp4 -vf "select='not(mod(n,30))',setpts=N/30/TB" -vsync 0 output_%03d.png`按每30帧提取一帧并自动命名。批量处理可编写bat脚本,遍历目录下所有MP4,为每个视频生成带文件名和计数前缀的图片序列,需修改源目录与输出目录并以管理员权限运行。该方法常用于AI换脸及Stable Diffusion LoRA训练素材准备。

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

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

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

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

所以如何将视频文件拆成一张张图片呢,我们可以通过鼎鼎大名的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\nsetlocal enabledelayedexpansion\n\n\nrem 定义字符集\nset "charset=abcdefghijklmnopqrstuvwxyz0123456789"\n\n\nrem 设置视频源目录\n@REM set "video_source=C:\\Users\\vis\\Desktop\\in"\nset "video_source=C:\\Users\\vis\\Desktop\\in"\nrem 设置图片输出目录\nset "image_output=C:\\Users\\vis\\Desktop\\out"\n\nrem 检查输出目录是否存在,不存在则创建\nif not exist "%image_output%" mkdir "%image_output%"\nset "frame_counter=0"\nrem 遍历视频目录\nfor /R "%video_source%" %%i in (*.mp4) do (\n\n    \n    rem 获取视频文件的基本名称\n    set basename=%%~ni\n    echo Processing !basename!\n    rem 构建完整的图片输出路径\n    set "image_path=!image_output!\\!basename!_frame_!frame_counter!_%%03d.png"\n    @REM echo Processing "%%i"...\n    echo Processing !image_path!\n    ffmpeg -i "%%i" -vf "select='not(mod(n,30))',setpts=N/30/TB" -vsync 0 !image_path!\n    @REM ffmpeg -i input.mp4 -vf "select='not(mod(n,30))',setpts=N/30/TB" -vsync 0 output_%03d.png\n)\n\necho All videos processed.\npause\nendlocal

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


注意一定要用管理员权限打开这个文件

相关文章

评论 (0)

暂无评论,来写第一条吧