3DMM之EOS 原理解析

一:简介

eos: 一个轻量级的头型3D Morphable面部模型拟合库

GitHub - patrikhuber/eos: A lightweight 3D Morphable Face Model fitting library in modern C++14

1 目前支持以下三种3DMM

Surrey Face Model (SFM),

4D Face Model (4DFM)

Basel Face Model (BFM) 2009

2 使用到的计算相关库 Eigen,glm

3 其中具体示例代码对应的是一个低分辨率的SFM模型sfm_shape_3448.bin

3D 顶点数: 3448个

三角形个数:6736个

输入特征点个数:68个

PCA:

形状PCA: 63 个特征向量 63 * (3448 * 3)

表情PCA: 6 个特征向量 6 * (3448 * 3)

提供了三个文件

1   2D与3D特征点序号对应关系表:

landmarks 与 3D mesh顶点对应数据:只有内部的50个顶点;不包含16个轮廓点。

下巴底部点有对应的3D顶点,1-8为右轮廓点,10-17位左轮廓点

2   3D mesh 可能为边缘轮廓点的序号,分左边轮廓和右边轮廓

3D mesh上可能的边缘轮廓点序号,左轮廓有17个候选点,右轮廓有17个候选点;

3    相邻面,相邻顶点关系图

根据三角形关系可以得到10184个边,可以一个10184*2 的顶点相邻关系矩阵

根据这10184个边,每一个边对应两个三角形面,可以得到10184*2的三角形相邻关系矩阵

图1:2D与3D特征点序号对应关系表

图2:3D mesh 可能为边缘轮廓点的序号

图3: 相邻面 

 

最终X_projection 是三维模型投影到二维平面的点,其中

需要求解的参数有:形状系数 α以及表情系数 β,旋转矩阵R,位移t_2d 以及缩放参数s。

P_orth为一个已知的正交投影矩阵。

最终的目标就是最小化输入的特征点X与投影到二维平面的X_projection的差。

1 求解旋转矩阵相关参数[1]

基于黄金标准算法求相机仿射矩阵,然后进行分解得到R,S,T

2 求解形状系数 α以及表情系数 β [2]

其中表情使用非负最小二乘法,形状使用最小二乘求解系数

[1]: Gold Standard Algorithm for estimating an affine camera matrix from world to image correspondences

[2] O. Aldrian & W. Smith, Inverse Rendering of Faces with a 3D Morphable Model, PAMI 2013.

二 算法总体介绍

即使只进行一次迭代,结果也很好;

当用于单图像拟合和,为了使所有参数完全收敛,最多需要300次迭代;

在实时跟踪中,如果基于前一帧作为初始参数,只需要迭代1-5次效果就很好;

这里的表情拟合和形状拟合是交替的,其实理论上可以将他们进行堆叠,一次性求解,

当然这两个特征向量很可能不是正交的。 但是在任何情况下,交替使用一般认为不会造成 任何伤害。

具体的算法大致流程:

1 获得相机pose

2 计算表情系数

开始循环迭代

{

1 3Dmesh 轮廓点确定(可见边+不可见边);

2 计算仿射矩阵

3 形状系数求解

4 表情系数求解

}

3DMM = mean + a * shape_pca + b * exp_pca

第一步:初始化 a和b均为0;没有颜色pca

current_combined_shape = mean + a * shape_pca + b * exp_pca

current_mesh(current_combined_shape,uv坐标,三角形关系图)

第二步:

vector model_points; // the points in the 3D shape model

vector vertex_indices; // their vertex indices 同样对应的也不一定是68个

vector image_points; // the corresponding 2D landmark points 不一定是68个

根据配置表:

可以确定内部50个2D和3D特征点对应关系;左右16个轮廓特征点和嘴角里面2个没有。

第三步:姿态初始估计:

基于上面对应的50个特征点求解R,S,t

基于黄金标准算法求相机仿射矩阵,然后基于SVD进行分解得到R,S,T,这里谈到 QR(正交三角)分解法也应该可以。

具体代码计算:旋转矩阵会转为四元数,进而得到一个3*4 的仿射矩阵;

第四步:表情拟合,更新参数b

因为脸的形状变化很大,取决于表情。(还是基于上面50对特征点)

因为表情是Blendshapes

fit_blendshapes_to_landmarks_nnls:morphablemodel::Blendshapes

fit_shape_to_landmarks_linear :morphablemodel::PcaModel

采用的非负数最小二乘法,不支持任何正则化;不是采用的pca向量基,而是采用 blendshape,也不是采用mean,而是当前的mean + a*shape_pca(但是其实好像还是mean)。感觉这了blendshape跟pca向量基没啥区别;

第五步: 更新当前形状和mesh

current_combined_shape = mean + a * shape_pca + b * exp_pca

current_mesh(current_combined_shape,uv坐标,三角形关系图)

第六步:迭代

6.1 计算偏航角yaw:示例-29度,向左;

6.2 确定没有遮挡的轮廓点点

6.2.1 确定可能的轮廓点

2D轮廓点有16个特征点,3D顶点提供了可能为轮廓点3D顶点序号34个。

寻找3D顶点中候选轮廓点,一共有左轮廓17个点,右轮廓17个点

根据阈值7.5度,当绝对值介于7.5,认为人脸朝正,34个轮廓点均被选中;

大于7.5,当脸部朝左,选中右边的17个轮廓点,反之选中左边的17个轮廓点;

6.2.2 配对2D轮廓点与3D候选顶点

例如示例为-29度,朝左,所以这一步只能确定右轮廓对应的3D顶点;

针对2D轮廓点右边每一个特征点,计算3D顶点中与之最近的顶点,构成关系对;

这样可以进一步确定8个3D顶点。

6.3 更新确定的2D特征点与3D顶点关系,增加右轮廓的8个顶点;

50 + 8

6.4 确定遮挡面轮廓点:进一步确定上面没有找到对应点的左轮廓点

确定了42个3D顶点;这步是很关键的,需要仔细看。

6.5 更新确定的2D特征点与3D顶点关系,增加左轮廓的42个顶点;

50 + 8 + 42 (2D顶点存在重复)

6.6 姿态估计:基于上面对应的100个特征点求解R,S,t

6.7 形状拟合:更新参数a

此时平均脸为mean + b * exp_pca

这里采用的拟合算法参考 Inverse Rendering of Faces with a 3D Morphable Model, PAMI 2013,它是一个线性的,封闭的解,有正则化;

6.8 表情拟合:更新参数b

此时平均脸为:mean + a * pca_shape

这里采用的拟合算法参考

6.9 整个算法注重得到参数a和b,并没有确定最终对应的68个3D顶点;

7 输出结果mesh

  

结论:

@1 难点还是在于遮挡面的轮廓点选择;trade off关键点;

eos采取了一种接近全局搜索的方法;

eos:基于法向量,计算相邻法向量是否同向;

顶点自检,发出射线是否射中三角形;

基于2D顶点构建kd树,距离在阈值以内的保留;

2 是否可优化:内部点选择都是直接基于映射表获得;

3 目前的fitting C++ 在选择遮挡轮廓点的时候比较简单,没有

考虑姿态的影响,应该是考虑到速度的平衡;

4 耗时情况:迭代一次,整体耗时254ms,其中寻找遮挡边轮廓点223ms。

 @为什么先生2012

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值