https://zhuanlan.zhihu.com/p/665898585
SadTalker技术原理
- 论文:《SadTalker: Learning Realistic 3D Motion Coefficients for Stylized Audio-Driven Single Image Talking Face Animation》
- 官方代码:https://github.com/OpenTalker/SadTalker
- 我用modelscope封装的sadtalker:https://github.com/wwdok/sadtalker_modelscope
通过一张人脸图像和一段语音音频生成谈话头部视频仍然面临许多挑战,即不自然的头部运动、扭曲的表情以及身份特征的改变。我们认为,这些问题主要是由于从耦合的二维运动场中学习导致的。另一方面,直接使用三维信息也会遇到表情僵硬和视频不连贯的问题。我们提出了SadTalker,它能够从音频中生成三维形态模型(3DMM)的三维运动系数(头部姿态、表情),并隐式地调整一种新型的三维感知面部渲染,以生成谈话头部视频。为了学习逼真的运动系数,我们分别显式地建模了音频与不同类型运动系数之间的联系。具体来说,我们提出了ExpNet,通过提炼系数和三维渲染的面部图像,从音频中学习精确的面部表情。至于头部姿态,我们设计了一个条件变分自编码器(PoseVAE)来合成不同风格的头部运动。最后,生成的三维运动系数被映射到所提出面部渲染的无监督三维关键点空间中,并合成最终的视频。我们进行了大量实验,以证明我们的方法在运动和视频质量方面的优越性。
图2. 主要流程。我们的方法使用三维形态模型(3DMM)的系数作为中间运动表示。为此,我们首先从音频中生成逼真的三维运动系数(面部表情β,头部姿态ρ),然后这些系数被用来隐式地调整三维感知面部渲染,以生成最终的视频。
ExpNet
图3. ExpNet的结构。我们引入了一个单目3D面部重建模型[5](包括Re和Rd)来学习逼真的表情系数。其中,Re是一个预训练的三维形态模型(3DMM)系数估计器,而Rd是一个没有可学习参数的可微3D面部渲染器。我们使用参考表情β0来减少身份的不确定性,并使用预训练的Wav2Lip[30]生成的帧和第一帧作为目标表情系数,因为它仅包含与嘴唇相关的运动。
PoseVAE
图4. 所提出的PoseVAE的管道。我们通过条件变分自编码器(VAE)结构学习输入头部姿态ρ0的残差。给定以下条件:第一帧ρ0、风格标识Zstyle和音频片段a{1,...,t},我们的方法学习残差头部姿态∆ρ{1,...,t} = ρ{1,...,t} − ρ0的分布。训练后,我们仅通过姿态解码器和条件(cond.)就可以生成风格化的结果。
有了源图片、源3D关键点、驱动3D关键点,将它们送给Image Generator,就能合成每一帧画面了。 Face vid2vid和3D-aware Face Render的工作流程如下图所示:
提出的FaceRender以及与face-vid2vid[42]的比较。给定源图像Is和驱动图像Id,face-vid2vid在未经监督的3D关键点空间(包括Xc、Xs和Xd)中生成运动。然后,通过外观A0和这些关键点可以生成图像。由于我们没有驱动图像,我们使用明确的分离式3D形态模型(3DMM)系数作为替代,并将其映射到未经监督的3D关键点空间中。
至于mappingNet的训练,包含两个步骤:首先,按照原论文中的方法训练 face-vid2vid。第二步,冻结appearance encoder, canonical keypoints estimator 和 image generator的所有参数,重构pipeline后在真实视频的 3DMM 系数上训练mappingNet。最终生成视频按照face-vid2vid的原始实现方式进行。
这一部分论文中讲得比较少,因为大部分内容都是借鉴自face-vid2vid的论文《One-shot free-view neural talking-head synthesis for video conferencing》,项目主页:https://nvlabs.github.io/face-vid2vid/ 。
Image Generator代码中对应的是class OcclusionAwareSPADEGenerator。要想看懂里面的代码,需要对3D版的卷积算子和3D版的grid_sample算子比较熟悉
如果你想体验SadTalker,除了跑官方代码仓库外,也可以试试我用modelscope封装的sadtalker库( https://github.com/wwdok/sadtalker_modelscope ),它的优点是把模型权重也打包进去了,国内下载速度很快,几行代码就可以调用sadtalker的能力。