面部动作迁移任务的目标,是把一段驱动视频中的表情和头部姿态迁移到静态源人脸上,生成时间连贯的合成视频。过去以 First Order Motion Model 为代表的一类方法,通过检测稀疏关键点并在图像平面做局部仿射变换,能够实现基本的口型同步和眨眼复现,但当驱动角色出现大幅侧转、抬头或遮挡时,二维关键点所隐含的几何约束会变得不稳定,生成结果容易出现五官漂移、面部轮廓扭曲。核心原因在于平面关键点无法表达人脸的深度结构,例如鼻梁高度、眼窝凹陷、下巴与颈部之间的前后关系。

DaGAN 的全称是 Depth-Aware Generative Adversarial Network,它把单目深度估计引入动作迁移流程。与显式使用三维可变形模型的方法不同,DaGAN 不要求预先建立高质量的三维人脸模板,而是直接从每一帧图像中估计一个深度图作为几何先验。这个深度图并不是真实物理尺度的三维重建结果,它是网络学习到的一种几何表示,用于约束生成器在合成过程中保持合理的空间结构。深度信息与RGB纹理信息形成互补:RGB负责外观和颜色,深度负责体积和轮廓。
一、从二维关键点到深度感知的范式变化
传统二维动作迁移方法通常把人脸表示为若干稀疏关键点,并在关键点周围计算局部仿射变换。由于关键点只包含横纵坐标信息,网络无法判断某个区域是靠近相机还是远离相机。正脸源图像在驱动视频出现接近九十度侧脸时,二维关键点只能强行拉扯眼角和嘴角坐标,导致鼻子、下巴和下颌线区域严重拉伸。遮挡条件下,部分关键点可能检测失败,局部仿射假设随之失效,生成的人脸会出现明显的伪影。
深度图提供了一种更直观的几何表达方式。每个像素记录该点到相机的相对距离,人脸区域中的鼻梁、嘴唇、眼窝等结构在深度图上具有清晰的高低变化。对动作迁移来说,如果生成器能够获知驱动帧中鼻梁相对脸颊更靠前,那么合成侧脸时就不容易把鼻子拍平。深度图还可以进一步转化为法向图或视差图,与RGB特征融合后指导 warp 场的计算,使纹理变形与几何变形保持一致。
下面是一段使用 OpenCV 准备深度图的示例,它展示了如何将带无效值的深度图归一化到网络可接受的输入范围。
import cv2
import numpy as np
def normalize_depth(depth_map):
# 深度图可能存在无穷远或异常点
valid = np.isfinite(depth_map)
if valid.sum() == 0:
return np.zeros_like(depth_map)
min_val = depth_map[valid].min()
max_val = depth_map[valid].max()
norm = np.zeros_like(depth_map)
norm[valid] = (depth_map[valid] - min_val) / (max_val - min_val + 1e-6)
return norm
depth = cv2.imread('depth.exr', cv2.IMREAD_UNCHANGED)
depth_norm = normalize_depth(depth)
二、DaGAN 的深度感知生成架构
DaGAN 的整体网络通常由三部分组成:深度估计器、生成器和判别器。深度估计器负责从驱动帧中恢复深度图,生成器接收源图像、运动信息以及驱动深度图并输出合成帧,判别器则判断生成结果是否真实、是否保持源人物身份。深度估计器可以采用轻量的编解码结构,也可以基于预训练单目深度模型进行微调,其输出分辨率一般与输入图像保持一致,以便在空间上对齐纹理特征。
深度特征与RGB特征的融合方式直接影响生成质量。一种常见设计是,深度图先经过一个小的特征编码器得到多尺度深度特征,RGB驱动帧也经过编码器得到多尺度纹理特征。在生成器的每个上采样层,深度特征通过拼接或空间自适应归一化与RGB特征结合。另一种路径是把深度图用于修正估计的 warp 场:深度变化越大的区域,越容易受到旋转和遮挡影响,网络可以降低这些区域的插值权重,从而减少纹理拉扯。
下面是一个简单的深度特征融合模块示例,它把深度特征投影到与RGB特征相同的通道数后相加,再通过归一化和激活函数增强非线性。
import torch
import torch.nn as nn
class DepthFusionBlock(nn.Module):
def __init__(self, rgb_dim, depth_dim):
super().__init__()
self.depth_proj = nn.Conv2d(depth_dim, rgb_dim, 3, padding=1)
self.norm = nn.BatchNorm2d(rgb_dim)
self.act = nn.LeakyReLU(0.2)
def forward(self, rgb_feat, depth_feat):
depth_feat = self.depth_proj(depth_feat)
fused = rgb_feat + depth_feat
fused = self.act(self.norm(fused))
return fused
三、损失函数:如何约束几何一致性
DaGAN 训练依赖多个损失协同工作。基础重建损失通常使用 L1 或感知损失,让生成帧在像素和特征空间接近真实驱动帧。单独使用 L1 会导致生成结果偏向模糊,因此需要对抗损失提升纹理细节和真实感。为了保持源人物身份,还可以引入身份特征损失,把源图像与生成图像分别送入人脸识别网络,计算特征向量之间的距离。这样即使用户换了夸张表情,人物身份也不容易被带偏。
深度一致性损失是 DaGAN 的核心约束之一。具体做法是把生成帧再次输入深度估计器,比较生成帧深度图与驱动帧深度图之间的差异。如果生成帧在几何上偏离驱动人脸,那么它的预测深度也会与目标深度不一致,该损失会迫使生成器不仅画对颜色和纹理,还要画对空间结构。为了避免背景区域干扰,通常会对人脸前景区域加掩码加权,让损失主要集中在面部有效区域。
下面是一段计算深度一致性损失的简单实现。
import torch.nn.functional as F
def depth_consistency_loss(generated, driving_depth, mask, depth_estimator):
gen_depth = depth_estimator(generated)
diff = (gen_depth - driving_depth).abs()
diff = diff * mask
loss = diff.sum() / (mask.sum() + 1e-5)
return loss
四、与主流动作迁移方法的对比
First Order Motion Model 使用二维稀疏关键点和局部仿射变换,优点是训练稳定、推理速度快,但对大姿态和遮挡非常敏感。face-vid2vid 引入三维关键点和显式三维人脸先验,几何稳定性更强,但依赖三维人脸重建,部署复杂度较高。DaGAN 以单目深度估计作为中间表示,避免显式三维建模,同时又在二维生成管线中保留了深度约束,因此更像一种折中方案。在大姿态场景下,DaGAN 生成的脸部轮廓和面部结构通常比纯二维方法更稳定。
下表对比了几类代表性方法在几何表示、大姿态表现和部署需求上的差异。
| 方法 | 几何表示 | 大姿态表现 | 是否需要3D标注 |
|---|---|---|---|
| FOMM | 2D稀疏关键点 | 容易漂移 | 否 |
| face-vid2vid | 3D关键点与形变模型 | 较稳定 | 是 |
| DaGAN | 单目深度图 | 明显改善 | 否 |
DaGAN 也有自身局限。深度估计器本身在极端光照、运动模糊或遮挡严重时可能产生伪影,错误的深度约束反而会降低合成质量。此外,深度表示对背景和头发的处理仍然困难,生成帧边缘可能出现深度不连续导致的细微毛刺。实际项目中通常需要结合人脸分割掩码,把深度损失限制在前景区域,并在训练中逐步增加深度约束权重。
五、实践部署与调优建议
训练数据最好包含多角度、多表情和多光照的说话人视频,并对人脸区域进行裁剪和对齐。深度图可以用预训练深度估计模型离线生成,也可以在线估计。离线生成深度序列能够降低训练阶段的显存和时间开销,但要求驱动视频来源相对固定;在线估计则可以应对任意新的驱动视频,但会增加推理计算量。对于训练数据较少的情况,可以先固定深度估计器,只训练生成器和判别器,待模型稳定后再联合微调深度分支。
推理阶段优化同样重要。生成器和深度估计器可以导出为 ONNX 或 TensorRT,并使用 FP16 精度加速。若显存有限,可以将深度图分辨率降低到原始尺寸的四分之一或八分之一,仍然能够保留主要几何信息。对于实时数字人应用,建议把特征 warp 部分替换为 CUDA 自定义算子,减少中间张量在 CPU 与 GPU 之间的搬运。生成结果输出前可以增加一次轻量滤波,以缓解深度边界处的高频伪影。
下面是一个简单的推理脚本框架,展示了模型从输入到输出的典型调用方式。
import torch
def run_inference(model, source_img, driving_img, device):
model.eval()
with torch.no_grad():
source = source_img.unsqueeze(0).to(device)
driving = driving_img.unsqueeze(0).to(device)
output = model(source, driving)
return output.squeeze(0).cpu()
总的来说,DaGAN 的关键价值在于把单目深度估计引入动作迁移,用显式几何先验弥补二维关键点表示的结构歧义。它适合对侧脸、俯仰和较大头部姿态有要求的数字人、虚拟主播以及视频编辑场景。实际落地时,需要根据数据规模和实时性要求,在深度估计精度、推理速度与生成质量之间做合理权衡。