一二三,跟我一起唱《逆光》

基于first order motion model模型合成视频,照片变成视频。

成果首发微信票圈,内容先占坑再补。

——————————————————————————

前段时间郭美美的老歌《不怕不怕》(“蚂蚁呀嘿”)又火了一把,用Avatarify软件可以一键生成摇头晃脑唱歌的视频,因为有人将其搬上抖音而导致全网疯狂。在“蚂蚁呀嘿”渐渐退火之季,腾讯微视为了刷存在感也出了可以让“李焕英”老照片眨眼动起来的特效,这其中所用的技术归根到底还是来自NeurIPS 19的一篇论文《First Order Motion Model for Image Animation》。论文名翻译成中文可以叫到《用于图像动画的一阶运动模型》,作者在github上给出了pytorch的开源代码https://github.com/AliaksandrSiarohin/first-order-model

论文的原理解读可以参考这篇文章https://zhuanlan.zhihu.com/p/136606648 

但并非有了开源代码就立马能跑通程序

在github官方repo里有说明,如果需要运行demo文件,首先需要有引导的视频文件和图片文件,图片文件比较容易裁剪,而视频不易裁剪,作者给出了个程序crop-video.py可以检测人脸并生成剪切视频的ffmpeg命令,运行此程序并会传参就可以生成ffmpeg命令。看起来很简单的样子,但许多人卡死在第一步,官方repo的issue中有很多都提到自己crop video失败,为什么呢?

首先,运行crop-video.py需要有face-alignment包,官方的建议如下

git clone https://github.com/1adrianb/face-alignment
cd face-alignment
pip install -r requirements.txt
python setup.py install

通过克隆一个repo并安装,但实际不建议这样做,face-alignment这个repo中的requirements没有更新,里面很多包的版本都不再是最新,如果按上面的方法安装可能会将现有环境中的某些包(如torch)降级

所以经实际测试,如果想要其发挥作用,只需直接pip install face-alignment安装最近的face-alignment即可。安装好之后如果运行缺失其他包的再安装一下就行了。

安装完之后再进行视频分割,常见的一个错误类似

CannotReadFrameError: Could not read frame 860:
Frame is 0 bytes, but expected 308160.

这是什么问题呢,其实是imageio的一个bug,它有时候读取最后一帧会失败,解决此问题的方法也很简单,直接pip install imageio --upgrade即可,升级完缺失什么包再装上就好了。

还有一种问题,就是用crop-video.py生成了ffmpeg命令,但执行了之后没报错也没有结果,这是为啥呢?

有可能是源视频中动作幅度过大,只需将默认参数--min_frames改小一点即可,比如给它传50

解决了这几个问题,一般就可以生成ffmpeg命令了。但这只是半自动化的工作,生成了命令之后需要自己用ffmpeg剪切视频,如果电脑上没装ffmpeg,可以自行google一下安装方法,对于windows用户,ffmpeg官网上的编译好的exe,可以直接使用,对于google colab用户,也无需考虑ffmpeg的安装问题,colab自带的虚拟机里就有,可以直接把上一步生成的命令加到jupyter的cell里,记得前面加叹号。

剪切好了视频,还需要一张生成动画用的图片,官方的jupyter示例程序中说,对于图片剪裁,可以用系统自带的画图工具来解决,试了一下不是很好用,但官方repo中并没有人脸校正并缩放尺寸的程序,所以为了偷懒我就直接找了脸方向比较正的图片并用画图工具裁剪。注意裁剪时最好裁剪成512*512的图片,否则后面程序缩放会强行成这个尺寸且不顾原来的长宽比,如果原来没有裁剪好,后面缩放后失真就会比较严重,如果图片尺寸较大,512的倍数也可以,如1024*1024。

此处需补一个端到端的程序,利用face-alignment识别、校正并裁剪人脸,占坑下次填上。

两样素材都提供好了,便可以利用repo中的demo程序生成了。官方提供了预训练的几种模型,可以通过google drive或者yandex网盘下载。模型比较大,下载可能需要一定时间。用colab的同学就很方便了,可以直接把作者shared checkpoints copy到自己的google drive中并加载。

本次我用的是VoxCeleb对应的预训练模型。示例命令如下

!python demo.py  --config config/vox-256.yaml --driving_video crop.mp4 --source_image js.jpg --checkpoint ../vox-cpk.pth.tar --relative --adapt_scale --find_best_frame --result_video js.mp4

demo程序默认会将图片和视频缩放至512*512尺寸。

一开始,我下载到了蔡依林《怪美的》MV,从中截取了两段视频,并让“国民妈妈”张小斐来学她的动作。效果不佳,示例视频中大法官Jolin歪着头,而张小斐头是正着的,模仿出来有点失真。

然后又裁了一段视频,因为镜头拉得太近而Jolin正摇头晃脑走出门,动作幅度比较好,示例视频本身没有裁剪出比较好的效果。

又看了一遍MV,发现很难裁一段正脸的视频片段。没办法只好亲自上阵,手机自拍了一段自己唱歌的视频,重要的是口型。将自己的示例视频裁剪出来以后就可以生成动画了。从百度图片里面“请”来了张含韵、金莎、蔡依林三位大美女当模特,为了体现西安特色,又“请来”一尊兵马俑。4位模特唱歌的口型已经出来了,怎么合成到一起呢?

答案是:依靠强大的ffmpeg!参考了这篇博文https://blog.csdn.net/nonmarking/article/details/50513504

ffmpeg -i bmy.mp4 -i cyl.mp4 -i js.mp4 -i zhy-ng.mp4 -filter_complex "[0:v]pad=iw*2:ih*2[a];[a][1:v]overlay=w[b];[b][2:v]overlay=0:h[c];[c][3:v]overlay=w:h" out.mp4

用类似上述命令可以将4个视频合成4宫格视频

视频有了,那声音呢?

我有孙燕姿《逆光》的完整版mp3文件,可以通过ffmpeg或者QQ影音将对应的几句裁剪出来。

第一次合成之后发现声画并不同步,这是因为我在唱《逆光》时,为了呈现比较好的效果,从第2s才开始唱的,所以燕姿的背景音乐加进去快了一秒怎么办?

如果多裁一秒,又是之前的词,而并没有口型与之对应,于是,我给背景音乐加了一秒空白,参考了这篇博文https://blog.csdn.net/xuqikang/article/details/112571126

重新合成,这一下声画同步了。音视频合成命令如下

ffmpeg -i  result.mp4  -i  ng.mp3  -vcodec  copy  -acodec  copy  zhy-ng.mp4

如果要对视频进行消音处理,可以参考这篇博文:https://blog.csdn.net/u012725623/article/details/104008263

到此,视频就合成完了。不过,因为发到票圈,有被人盗用的风险,就加了水印,这个加水印我尝试用python加logo水印,效果不佳,于此用了vivo手机自带的视频编辑器加了水印,不过此水印较轻,位置也相对友好,如果想抹掉还是有可能的。反正水印是防君子不防小人的,就先这样吧。

所以github虽然提供了开源代码,但要实现端到端的功能,还有很多路要走,包括但不限于自己训练效果更好的模型等。

视频加文字水印,python也能实现,占坑再补。

另外的体会就是如果用VoxCeleb的预训练模型,示例视频头的动作不宜过大,也这是为啥网上那些让清朝皇帝动起来的视频只限于眨眼或微笑,还有老照片加动作也是一样,都是讨了巧。如果头左右摆幅过大,视频也能生成,但打失真较为严重,有点像纸片人的既视感。

Avatarify中可能有自己训练过的更好的模型,所以在唱“蚂蚁呀嘿”的时候除去转眼珠张嘴,头左右摆动幅度也不小,不过就算如此还是有失真,如果你仔细观察小马哥那一张,会发现背后的背景都扭曲了。

此处给个链接https://baijiahao.baidu.com/s?id=1692918792389693228&wfr=spider&for=pc

博文先记录上,随后再补图。

我做出来的效果,还在考虑要不要发上来,票圈里的朋友们已经见过了,博客园本身不支持上传视频,只能放外链,等我考虑好了再加进来。

posted @ 2021-03-14 18:37  飞向天边  阅读(132)  评论(0编辑  收藏  举报