从源代码理解3DDFA_V2的推理过程
默认crop_policy = 'box'
,bbox
宽和高的平均值记为old_size
,找到bbox
的中心(center_x, center_x)
,从中心向四周扩展尺寸为int(old_size * 1.58)
,从而截取出一个正方形
resize截取的正方形,使得尺寸为120x120
,输入网络,输出为一个62维向量,做denorm
解析62维向量,前12维还原为3x4
变换矩阵(Row-major表示,前3列为R
,最后1列为offset
),然后40维shape系数,最后10维exp系数
pts3d = R @ (self.bfm.u + self.bfm.w_shp @ alpha_shp + self.bfm.w_exp @ alpha_exp). \
reshape(3, -1, order='F') + offset # (3, 38365), np.float32型
pts3d = similar_transform(pts3d, roi_box, size)
【重点理解similar_transform】
- 可视化平均脸
self.bfm.u
,包含38365个顶点(下巴和左眼一侧涂粉色,便于观察)
c=0, [-78194.804688, 76469.000000], span=154663.812500
c=1, [-90549.601562, 88859.593750], span=179409.187500
c=2, [12451.929688, 132685.437500], span=120233.507812
2. Rotation + translation
R =
[[ 0.00041103, -0.00001579, -0.00027028],
[-0.00003433, 0.00048299, -0.00007941],
[ 0.00026137, 0.00007537, 0.00040724]]
R不是一个正交矩阵,包含了scale成分
Q:如何从R中分解出xyz3个维度的scale成分,并检查它们是否相等?
或者说R除以scale,能够变成一个正交矩阵?
3D vertices被缩小了,并且向右进行了旋转(yaw为负值)
c=0, [-46.478928, 26.152172], span=72.631104
c=1, [-48.969337, 35.275150], span=84.244492
c=2, [-12.467479, 54.472210], span=66.939690
offset =
[[ 73.81529 ],
[ 74.7374 ],
[-66.671585]]
Q:在正交投影下,offset的z轴有什么意义?(按照论文的说法,这个值应该是0才对)
或者说只需要11维来表示3x4矩阵就足够了啊
c=0, [27.336365, 99.967468], span=72.631104
c=1, [25.768059, 110.012543], span=84.244484
c=2, [-79.139061, -12.199375], span=66.939682
此时3D vertices xy坐标的范围落在[0, 120]内,z坐标未知
3. 进入similar_transform
函数
x、z坐标减1(理由 for Python compatibility,暂时无法理解),y坐标做flip
放大至与bbox图像吻合(bbox一定是正方形,scale_x
等于scale_y
),然后加上bbox左上角,最终与图像吻合
对于z轴,放大同样的倍数,然后将最小值移动到0,z轴取值越大,离相机越近
c=0, [306.172302, 843.037231], span=536.864929
c=1, [433.077942, 1055.785156], span=622.707214
c=2, [0.000000, 494.795898], span=494.795898
渲染的时候,x轴向右,y轴向下,光源放在(0, 0, 5)处,与归一化到standard cube(-1到1区间)的3D vertices进行shading
只有z轴的相对差异影响渲染效果,平移无所谓