大家好我是图恩,如果你经历过以前的胶卷电影时代,那么你应该明白当时的电影是怎么播放的,之所以叫胶卷,是因为当时的一部电影就是由一张张小的胶片拼接卷成一卷而来,有点像现在的胶带。
一部电影可能由成千上万张小的胶片制作而成,所谓的胶片,可以理解为就是一张照片,照片之间的画面呈现出连续的画面,以一定的速度拉动这盘交卷,然后通过光线穿过照片投射到荧幕上,就能看到会动的画面,也就是电影了。
所以实际上电影就是由一张张连续的图片拼接而来,只不过由于现代的设备越来越先进,这种原始的视频媒介早已淘汰。
明白了这个原理,我们可以将一个视频文件拆成一张张图片,然后再拼接起来,仍然能得到原来的电影。
所以如何将视频文件拆成一张张图片呢,我们可以通过鼎鼎大名的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目录,就可以批量的提取该目录下的所有视频文件的关键帧了,不用一个个的去操作了。
注意一定要用管理员权限打开这个文件