一:简介

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

3DMM之EOS 原理解析相关推荐

  1. 【金融科技前沿】区块链和数字经济(区块链的缘起,现状和发展、区块链技术架构和原理解析 、区块链应用和案例综述)

    1.缘由 前段时间微众银行的区块链首席架构师张开翔老师给我们上了一堂近三小时的课,与其说是在上课,不如说是一场思想的享受.开翔老师跟我们学院联系挺密切的,之前比赛也见过他,我印象中他一直是一位顶级的技 ...

  2. Spark Shuffle原理解析

    Spark Shuffle原理解析 一:到底什么是Shuffle? Shuffle中文翻译为"洗牌",需要Shuffle的关键性原因是某种具有共同特征的数据需要最终汇聚到一个计算节 ...

  3. 秋色园QBlog技术原理解析:性能优化篇:用户和文章计数器方案(十七)

    2019独角兽企业重金招聘Python工程师标准>>> 上节概要: 上节 秋色园QBlog技术原理解析:性能优化篇:access的并发极限及分库分散并发方案(十六)  中, 介绍了 ...

  4. Tomcat 架构原理解析到架构设计借鉴

    ‍ 点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 Tomcat 架构原理解析到架构设计借鉴 Tomcat 发展这 ...

  5. 秋色园QBlog技术原理解析:性能优化篇:数据库文章表分表及分库减压方案(十五)...

    文章回顾: 1: 秋色园QBlog技术原理解析:开篇:整体认识(一) --介绍整体文件夹和文件的作用 2: 秋色园QBlog技术原理解析:认识整站处理流程(二) --介绍秋色园业务处理流程 3: 秋色 ...

  6. CSS实现元素居中原理解析

    原文:CSS实现元素居中原理解析 在 CSS 中要设置元素水平垂直居中是一个非常常见的需求了.但就是这样一个从理论上来看似乎实现起来极其简单的,在实践中,它往往难住了很多人. 让元素水平居中相对比较简 ...

  7. 秋色园QBlog技术原理解析:Web之页面处理-内容填充(八)

    文章回顾: 1: 秋色园QBlog技术原理解析:开篇:整体认识(一) --介绍整体文件夹和文件的作用 2: 秋色园QBlog技术原理解析:认识整站处理流程(二) --介绍秋色园业务处理流程 3: 秋色 ...

  8. 秋色园QBlog技术原理解析:UrlRewrite之无后缀URL原理(三)

    文章回顾: 1: 秋色园QBlog技术原理解析:开篇:整体认识(一) --介绍整体文件夹和文件的作用 2: 秋色园QBlog技术原理解析:认识整站处理流程(二) --介绍秋色园业务处理流程 本节,将从 ...

  9. Android之Butterknife原理解析

    转载请标明出处:[顾林海的博客] 个人开发的微信小程序,目前功能是书籍推荐,后续会完善一些新功能,希望大家多多支持! ##前言 Butterknife是一个专注于Android系统的View注入框架, ...

  10. 【深度学习】谷歌大脑EfficientNet的工作原理解析

    [深度学习]谷歌大脑EfficientNet的工作原理解析 文章目录 1 知识点准备1.1 卷积后通道数目是怎么变多的1.2 EfficientNet 2 结构2.1 方式2.2 MBConv卷积块2 ...

最新文章

  1. ios Runloop
  2. EF映射之DataBaseFirst
  3. php+mysql案例含源码_【专注】Zabbix源码安装教程—步骤详解(1)安装前准备
  4. 使用Nexus私服代理其他maven仓库(jitpack、jcenter)
  5. linux树莓派网易云音乐,基于树莓派的红外遥控版网易云音乐播放器
  6. WEB安全基础-Javascrp相关知识点之BOM
  7. PSD分层电商促销模板|换季大促销,不怕老板催你做海报了
  8. [导入]FtpClient Library升级到4.x
  9. CSS3中的过渡、动画和变换
  10. Kvaser新品推介:一款坚固耐用的单通道CAN / CAN FD转USB接口-Kvaser U100 编码:73-30130-01173-1
  11. win7企业版激活秘钥激活kms安装激活教程
  12. java实现读取163邮箱,qq邮箱的邮件内容
  13. OpenWrt之DNS 测试工具(nslookup、dig)
  14. 8 - 1 - Non-linear Hypotheses (10 min)
  15. RT-Thread学习笔记五——临界区与临界区保护
  16. JAVA_SE基础知识笔记
  17. 【C语言每日一题】——猜凶手
  18. 表单域 表单标签及表单控件的使用
  19. 未来:spring响应式编程 Hands-On Reactive Programming in Spring 5(二)------Basic Concepts
  20. 6大B2C购物系统比较

热门文章

  1. PCA主成分分析python实现
  2. GridView的dataformatstring设置
  3. WKWebView刷新URL
  4. Vue3动态路由与路由守卫
  5. 计算机操作系统期末考试大全,计算机操作系统期末考试试题含答案
  6. wow模型修改器_《魔兽世界》魔兽世界模型修改器攻略
  7. 设计模式观察者模式_观察者设计模式教程
  8. python的string与Unicode转换,gbk字符串编码
  9. 常见的IC封装形式大全(超详细)
  10. BI系统打包Docker镜像及容器化部署的具体实现