ffmpeg 视频合成,使用 alphamerge 对视频进行几何区域裁剪

做过视频合成的人都知道,视频合成的时候,有时候需要对视频进行裁剪,比如只需要视频的一部分,或者只需要视频的某个区域,这个时候就需要对视频进行裁剪。

如果只是要裁剪掉某个时间段,那比较简单,使用 ffmpeg 的 -ss 和 -t 参数就可以了,比如:

shell 复制代码
ffmpeg -i input.mp4 -ss 00:00:10 -t 00:00:20 -c copy output.mp4

如果是只需要视频中的某个区域怎么办呢?比如做绿幕视频合成,例如下面这个绿幕视频,其中内容是一只老虎,如果要将老虎叠加到另一个森林视频中合成。

这种视频可以使用 ffmpeg chromakey 滤镜来处理,根据色键来去除绿幕,然后叠加到其他视频上。

shell 复制代码
ffmpeg -i tiger.mp4 -i forest.mp4 -shortest -filter_complex "[1:v]scale=1920:1080,chromakey=0x15ff09:0.08:0.0[ckout];[0:v][ckout]overlay[out]" -map "[out]" -y output.mp4

这个命令中的 chromakey=0x15ff09:0.08:0.0 是一个 FFmpeg 中的滤镜,用于将视频中的某个颜色替换成透明。其中 0x15ff09 是要替换的颜色,0.08 是颜色的容差,0.0 是透明度。具体来说,这个滤镜会将颜色值为 0x15ff09 的像素替换成透明像素,容差为 0.08,透明度为 0.0。

但是这种方式的处理效果通常不太理想,如果主体形象中有绿色的部分,那么这部分也会被去除,导致主体形象出现空洞。

一般更建议使用 ffmpeg 的 alphamerge 滤镜来处理,如果要将 A.mp4 和 B.mp4 两个视频叠加合成。一般需要提供 A_mask.mp4 这样的视频,这个视频中的内容和 A.mp4 类似,包含其中的透明通道信息,如下所示:

可以使用下面的命令来合成视频:

shell 复制代码
ffmpeg -i digit.mp4 -i digit_mask.mp4 -i 1920.mp4 -filter_complex '[1][0]scale2ref[mask][main];[main][mask]alphamerge[vid];[vid][2:v]scale2ref=w=iw/2:h=ih/2[origin][digit];[digit][origin]overlay=x=-200:y=540[out]' -map 1:a -c:a copy -map [out] -y output.mp4

这种 mask 视频一般是和原视频一起生成的,时长也相同,这种 mask 视频就是专门用来抠像的,将视频中的绿幕去除,然后叠加到其他视频上。

那么如果我需要在视频中裁剪出一个区域,然后叠加到其他视频上,又该如何实现呢?

比如在人物的头部区域增加一个灰色的圆形区域,或者是圆角矩形,正方形等几何图形等。

依然可以使用 alphamerge 滤镜来实现, 在上一个命令的基础上,我们还需要动态生成一个包含几何区域的 PNG 图片来裁剪图形,除几何区域外,其他内容都是透明的。

现在,除了有 mask 视频之外,还有一个图片作为遮罩,需要使用两次 alphamerge 滤镜。现将人像抠出来,再在人像头部区域后面添加一个圆形区域,ffmpeg 合成命令如下:

shell 复制代码
ffmpeg -i digit.mp4 -i digit_mask.mp4 -i mask1920.png -i 1920.mp4 -filter_complex '[0][1]alphamerge[vid];[2][vid]overlay[vid2];[2]fps=25,loop=999:size=1[mask1920_fps];[mask1920_fps]format=rgba[msk];[msk]alphaextract[alfa];[vid2][alfa]alphamerge[rid];[3:v][rid]overlay[out]' -map 1:a -c:a copy -map [out] -y z.mp4

上面的命令需要的全部资源都在这里:

我们再借助 ChatGPT 来解释一下这行命令:

  1. -i digit.mp4:这是输入文件 digit.mp4,它是我们想要处理的视频文件。

  2. -i digit_mask.mp4:这是输入文件 digit_mask.mp4,它是一个视频文件,作为 digit.mp4 的遮罩(alpha 融合)。

  3. -i mask1920.png:这是输入文件 mask1920.png,它是一个图片文件,作为另一个遮罩。

  4. -i 1920.mp4:这是输入文件 1920.mp4,它是另一个视频文件,我们将在其上叠加遮罩。

  5. -filter_complex:这是复杂滤镜图形的开始。

  6. [0][1]alphamerge[vid]:这一步将 digit.mp4digit_mask.mp4 进行 alpha 融合,生成一个新的视频流 vid

  7. [2][vid]overlay[vid2]:这一步将 mask1920.png 和之前生成的 vid 进行叠加,生成另一个新的视频流 vid2。这一步是为了在数字人头像背后添加颜色形状。

  8. [2]fps=25,loop=999:size=1[mask1920_fps]:这一步将 mask1920.png 设置为持续循环的视频流,生成新的视频流 mask1920_fpsfps=25 设置 mask1920.png 的帧率为 25 帧/秒,loop=999:size=1mask1920.png 循环播放 999 次,但由于 size=1,实际上只有 1 帧。

  9. [mask1920_fps]format=rgba[msk]:这一步将之前生成的 mask1920_fps 转换为带有 alpha 通道的视频流,生成新的视频流 msk

  10. [msk]alphaextract[alfa]:这一步从视频流 msk 中提取 alpha 通道,生成新的视频流 alfa

  11. [vid2][alfa]alphamerge[rid]:这一步将 vid2alfa 进行 alpha 融合,得到一个新的视频流 rid。在这里,alfa 的 alpha 通道将被应用到 vid2 上,实现遮罩效果。

  12. [3:v][rid]overlay[out]:这一步将 1920.mp4rid 进行叠加,得到最终的输出视频流 out。在这里,rid 会覆盖 1920.mp4 的一部分区域,实现叠加效果。

  13. -map 1:a -c:a copy -map [out]:这一部分用于保留输入文件 digit_mask.mp4 的音频流,并将输出视频流 out 作为输出文件的视频流。

  14. -y z.mp4:这是输出文件的设置,z.mp4 是输出的视频文件名。

这样,整个命令实现了将 digit_mask.mp4mask1920.png 作为遮罩应用到 digit.mp41920.mp4 上,并输出为 z.mp4

相关推荐
崔庆才丨静觅5 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60616 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了6 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅6 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅6 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅7 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment7 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅7 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊7 小时前
jwt介绍
前端
爱敲代码的小鱼7 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax