写在前面
基于单张图像的三维人脸建模较为基础的方法就是99年的这篇《A Morphable Model For The Synthesis Of 3D Faces》,直到现在还可以在各种会议上看到其方法的变形与改进。但是关于其的中文资料却是少之又少,因此在读这篇论文时,便产生了把笔记记录下来的想法,由于刚开始读文献,对各种涉及到的方法理解不深刻,难免会有错误,望各位指出。
算法的大致思路是利用一个人脸数据库构造一个平均人脸形变模型,在给出新的人脸图像后,将人脸图像与模型进行匹配结合,修改模型相应的参数,将模型进行形变,直到模型与人脸图像的差异减到最小,这时对纹理进行优化调整,即可完成人脸建模。
算法主要流程
从上面的叙述中,我们可以直观的想象,主要有两个步骤,第一个是从人脸数据库中所有脸构建出一个平均的脸部模型,第二个完成形变模型与照片的匹配。这两个步骤中,都暗含了人脸与人脸之间的每一个点都拥有对应关系,且必须找到这种对应关系,完成点与点之间的配准,是最主要的难题。
因此在进行建模的过程中,需要完成以下两个关键的问题:
- 模型与照片的配准
- 如何避免生成怪异不可能的模型
文章主要组织为以下几部分对思路进行介绍:
三维形变的脸部模型
这里作者将人脸分为了两种向量:
一种是形状向量(shape-vector),包含了
X
,
Y
,
Z
X, Y, Z
X,Y,Z坐标信息:
S
=
(
X
1
,
Y
1
,
Z
1
,
X
2
,
Y
2
,
Z
2
,
.
.
.
.
.
.
,
X
n
,
Y
n
,
Z
n
)
T
S = (X_{1}, Y_{1}, Z_{1}, X_{2}, Y_{2}, Z_{2},......,X_{n},Y_{n},Z_{n})^{T}
S=(X1,Y1,Z1,X2,Y2,Z2,......,Xn,Yn,Zn)T
这里的n指的是模型的顶点数,同以下纹理向量的n。
另一种是纹理向量(texture-vector), 包含了
R
,
G
,
B
R, G, B
R,G,B颜色值信息:
T = ( R 1 , G 1 , B 1 , R 2 , G 2 , B 2 , . . . . . . , R n , G n , B n ) T T = (R_{1}, G_{1}, B_{1}, R_{2}, G_{2}, B_{2},......,R_{n},G_{n},B_{n}) ^{T} T=(R1,G1,B1,R2,G2,B2,......,Rn,Gn,Bn)T
在有了以上的表示方法后,我们使用的建立三维形变的脸部模型由
m
m
m个脸部模型组成,其中每一个都包含相应的$S_{i}, T_{i} $两种向量。这样在表示新的三维脸部模型的时候,我们可以用以下的方式表示:
S
n
e
w
M
o
d
e
l
=
∑
i
=
1
m
a
i
S
i
S_{newModel} = \sum_{i=1}^{m} a_{i}S_{i}
SnewModel=i=1∑maiSi
T
n
e
w
M
o
d
e
l
=
∑
i
=
1
m
b
i
T
i
T_{newModel} = \sum_{i=1}^{m} b_{i}T_{i}
TnewModel=i=1∑mbiTi
其中
∑
i
=
1
m
a
i
=
∑
i
=
1
m
b
i
=
1
\sum_{i=1}^{m} a_{i} = \sum_{i=1}^{m} b_{i} = 1
∑i=1mai=∑i=1mbi=1
原文这里的m是“exemplar faces”的个数,我的理解是采集的人脸样本数
这样一个新的脸部模型就可以由已有的脸部模型线性组合,因此也可以把新的脸部模型进行如下的表示,
{
S
n
e
w
M
o
d
e
l
(
a
⃗
)
,
T
n
e
w
M
o
d
e
l
(
b
⃗
)
}
\{ S_{newModel}(\vec a ), T_{newModel}(\vec b )\}
{SnewModel(a),TnewModel(b)}其中
a
⃗
=
(
a
1
,
a
2
,
.
.
.
a
m
)
T
,
b
⃗
=
(
b
1
,
b
2
,
.
.
.
b
m
)
T
\vec a = (a_{1}, a_{2}, ...a_{m})^{T}, \vec b = (b_{1}, b_{2}, ...b_{m})^{T}
a=(a1,a2,...am)T,b=(b1,b2,...bm)T
在参数化模型之后,就可以通过改变 a ⃗ \vec a a和 b ⃗ \vec b b来生成新的脸部模型。
为了从已有的 m m m个人脸数据模型中找到一个平均脸部特征,利用Principal Component Analysis(PCA)方法来找到这样一个平均脸部模型。
以下的步骤均为PCA算法流程,
- 计算 S ˉ , T ˉ \bar S, \bar T Sˉ,Tˉ
- 中心化人脸数据, 求得 △ S = S i − S ˉ \triangle S = S_{i} - \bar S △S=Si−Sˉ, △ T = T i − T ˉ \triangle T = T_{i} - \bar T △T=Ti−Tˉ
- 分别计算协方差矩阵 C S , C T C_{S}, C_{T} CS,CT
- 求得相应协方差矩阵的特征值和特征向量
在完成以上步骤的后,新的脸部模型的就可以用以下的公式进行表示:
S
n
e
w
M
o
d
e
l
=
S
ˉ
+
∑
i
=
1
m
−
1
α
i
s
i
S_{newModel} = \bar S + \sum_{i=1}^{m-1} \alpha_{i}s_{i}
SnewModel=Sˉ+i=1∑m−1αisi
T
n
e
w
M
o
d
e
l
=
T
ˉ
+
∑
i
=
1
m
−
1
β
i
t
i
T_{newModel} = \bar T + \sum_{i=1}^{m-1} \beta_{i}t_{i}
TnewModel=Tˉ+i=1∑m−1βiti
其中,
α
,
s
\alpha, s
α,s,
β
,
t
\beta, t
β,t分别为协方差矩阵
C
S
,
C
T
C_{S}, C_{T}
CS,CT的特征值和特征向量。
这个时候,系数
α
⃗
\vec \alpha
α,
β
⃗
\vec \beta
β的概率分别为
p
(
α
⃗
)
∼
e
−
1
2
∑
i
=
1
m
(
α
i
/
σ
i
2
)
p(\vec \alpha ) \thicksim e^{\frac{-1}{2} \sum_{i=1}^{m} (\alpha_{i}/\sigma_{i}^{2})}
p(α)∼e2−1∑i=1m(αi/σi2)
p
(
β
⃗
)
∼
e
−
1
2
∑
i
=
1
m
(
β
i
/
σ
i
2
)
p(\vec \beta ) \thicksim e^{\frac{-1}{2} \sum_{i=1}^{m} (\beta_{i}/\sigma_{i}^{2})}
p(β)∼e2−1∑i=1m(βi/σi2)
这里的m-1是特征向量的个数,这里很多人有疑问,m-1并不是表示减少使用的样本数,是从m个样本中提取出m-1个不相交子空间的特征向量。举个例子, 在开源的2009版BFM的里,采集了200个人脸样本数据,得到的特征向量数量是199个(BFM项目的链接)
其中不同 σ 2 \sigma ^ {2} σ2分别为对应协方差矩阵 C S , C T C_{S}, C_{T} CS,CT的特征值。
看到这里,可能会有人和我一样有疑问,为什么不用之前的表示方法, 而是将用PCA方法进行处理,仅仅是为了把 m m m维的参数降到 m − 1 m-1 m−1维么?
其实在PCA过程中,最后得到协方差矩阵的特征向量是相互正交的,这样,通过PCA分析,我们我们得到的是 m − 1 m-1 m−1个互不相交的子空间,例如,这 m − 1 m-1 m−1的向量可以是对应眼睛、鼻子,等互不关联脸部的部分,这样在进行修改的时候,可以达到只修改一部分脸部特征的效果,避免对其他子空间进行影响。
但我们仍需注意,尽管有了上面的特征值以及 m − 1 m-1 m−1个互不相交的子空间,仍然还是无法直接和具体人脸的眼睛、鼻子等联系对应起来。
以上介绍了三维形变模型的基本理论,但是在实际使用的时候,需要进行特殊处理的还有面部表情以及相应的脸部特征:
- 面部表情
由于面部表情在不同人脸上的表示是大致相同的,比如简单的笑,会有嘴角翘起,眼睛眯起等,因此可以使用同一个参数应用到不同人脸上,即可达到想要的效果,具体使用《Computer generated animatoin of faces》中使用的方法,记录同一张脸分别在有表情以及没有表情的模型,使用以下的公式
△ S = S e x p r e s s o i n − S n e u t r a l \triangle S = S_{expressoin} - S_{neutral} △S=Sexpressoin−Sneutral , △ T = T e x p r e s s o i n − T n e u t r a l \triangle T = T_{expressoin} - T_{neutral} △T=Texpressoin−Tneutral,然后将得到的 △ S \triangle S △S、 △ T \triangle T △T应用到目标脸部,即可得到拥有表情的三维模型。 - 脸部特征
不同于上面的面部表情具有统一性,面部特征在不同的个体的差异会变得很明显,例如脸颊、嘴巴、眉毛的宽度。因此在具体实现的时候,我们需要手动标定出这些特征点,来找到输入图像与模型的对应关系。
具体可以使用以下的公式进行表达:
△ S = ∑ i = 1 m μ i ( S i − S ˉ ) \triangle S = \sum_{i=1}^{m} \mu_{i}(S_{i} - \bar S) △S=∑i=1mμi(Si−Sˉ) , △ T = ∑ i = 1 m μ i ( T i − T ˉ ) \triangle T = \sum_{i=1}^{m} \mu_{i}(T_{i} - \bar T) △T=∑i=1mμi(Ti−Tˉ)
其中,$\mu 表 示 了 相 应 特 征 所 占 的 比 重 , 这 样 表示了相应特征所占的比重,这样 表示了相应特征所占的比重,这样(\triangle S, \triangle T) 可 以 作 用 于 任 何 一 个 三 维 模 型 , 来 使 它 拥 有 或 去 掉 对 应 的 脸 部 特 征 。 但 是 对 应 的 特 征 很 多 , 如 果 所 有 特 征 都 用 手 工 标 定 基 本 上 不 太 现 实 , 因 此 , 做 出 假 设 可以作用于任何一个三维模型,来使它拥有或去掉对应的脸部特征。 但是对应的特征很多,如果所有特征都用手工标定基本上不太现实,因此,做出假设 可以作用于任何一个三维模型,来使它拥有或去掉对应的脸部特征。但是对应的特征很多,如果所有特征都用手工标定基本上不太现实,因此,做出假设\mu(S,T) 是 一 个 线 性 函 数 , 这 样 寻 找 是一个线性函数,这样寻找 是一个线性函数,这样寻找\triangle \mu$可以转化为存在确定值的最优解问题, 达到最优解条件为以下值最小:
∥ △ S ∥ M 2 = < △ S , C S − 1 △ S > \Vert \triangle S \Vert^{2}_{M} = <\triangle S, C^{-1}_{S} \triangle S> ∥△S∥M2=<△S,CS−1△S>, ∥ △ T ∥ M 2 = < △ T , C T − 1 △ T > \Vert \triangle T \Vert^{2}_{M} = <\triangle T, C^{-1}_{T} \triangle T> ∥△T∥M2=<△T,CT−1△T>
将形变模型与照片对应
在有了形变模型之后,对于一张给定的人脸照片,我们需要将模型与人脸照片进行配准,然后对模型的参数进行调整,使其与照片中的人脸差异值达到最小。简单而言,不断依据模型与输入的人脸照片进行比对,不断进行迭代,使两者之间的比对误差达到最小,这个时候,我们可以近似认为该模型即为对应输入的人脸照片的三维模型。
为了可以使形变模型与输入的照片进行量化比较,需要利用模型重建出模型照片,使得模型图片
I
m
o
d
e
l
(
x
,
y
)
I_{model}(x,y)
Imodel(x,y)与输入的图像
I
i
n
p
u
t
(
x
,
y
)
I_{input}(x,y)
Iinput(x,y)之间的欧氏距离最小,即
E
I
E_{I}
EI最小:
I
m
o
d
e
l
(
x
,
y
)
=
(
I
r
,
m
o
d
(
x
,
y
)
,
I
g
,
m
o
d
(
x
,
y
)
,
I
b
,
m
o
d
(
x
,
y
)
)
T
I_{model}(x, y) = (I_{r,mod}(x, y), I_{g,mod}(x, y),I_{b,mod}(x, y))^{T}
Imodel(x,y)=(Ir,mod(x,y),Ig,mod(x,y),Ib,mod(x,y))T,
E
I
=
∑
x
,
y
∥
I
i
n
p
u
t
(
x
,
y
)
−
I
m
o
d
e
l
(
x
,
y
)
∥
2
E_{I} = \sum_{x, y} \Vert I_{input}(x,y) - I_{model}(x,y)\Vert^{2}
EI=x,y∑∥Iinput(x,y)−Imodel(x,y)∥2
这里先提一下,由 α ⃗ 、 β ⃗ \vec \alpha 、\vec \beta α、β系数决定好的的脸部模型,在渲染的时候我们还需要的参数$\vec \rho , 它 包 括 了 相 机 参 数 , 对 象 尺 寸 , 图 像 的 旋 转 和 平 移 , 环 境 的 光 照 强 度 等 等 , 因 此 我 们 可 以 继 续 将 脸 部 模 型 扩 充 表 示 为 , 它包括了相机参数,对象尺寸,图像的旋转和平移,环境的光照强度等等,因此我们可以继续将脸部模型扩充表示为 ,它包括了相机参数,对象尺寸,图像的旋转和平移,环境的光照强度等等,因此我们可以继续将脸部模型扩充表示为(\vec \alpha 、\vec \beta、\vec \rho)$。
所以原问题可以转化为,寻找到相应的参数 ( α ⃗ 、 β ⃗ 、 ρ ⃗ ) (\vec \alpha 、\vec \beta、\vec \rho) (α、β、ρ),使得条件概率 p ( I i n p u t ∣ α ⃗ 、 β ⃗ 、 ρ ⃗ ) p(I_{input} \lvert \vec \alpha 、\vec \beta、\vec \rho) p(Iinput∣α、β、ρ)达到最大值。
根据贝叶斯定理, 在考虑到输入图片中存在噪声的情况,引入标准误差
σ
N
\sigma_{N}
σN,可以得出
p
(
I
i
n
p
u
t
∣
α
⃗
、
β
⃗
、
ρ
⃗
)
∼
e
−
1
2
σ
N
2
⋅
E
I
p(I_{input} \lvert \vec \alpha 、\vec \beta、\vec \rho) \thicksim e^{\frac{-1}{2\sigma^{2}_{N}} \cdot E_{I}}
p(Iinput∣α、β、ρ)∼e2σN2−1⋅EI
因此最大化该条件概率可以转化为最小化以下代价函数:
E
=
1
σ
N
2
E
I
+
∑
j
=
1
m
−
1
α
j
2
σ
S
,
j
2
+
∑
j
=
1
m
−
1
β
j
2
σ
T
,
j
2
+
∑
j
=
1
m
−
1
(
ρ
j
−
ρ
ˉ
j
)
2
σ
ρ
,
j
2
E=\frac{1}{\sigma^{2}_{N} }E_{I}+ \sum_{j=1}^{m-1} \frac{\alpha^{2}_{j}}{\sigma^{2}_{S, j}} + \sum_{j=1}^{m-1} \frac{\beta^{2}_{j}}{\sigma^{2}_{T, j}} +\sum_{j=1}^{m-1} \frac{(\rho_{j} - \bar \rho_{j})^{2}}{\sigma^{2}_{\rho, j}}
E=σN21EI+j=1∑m−1σS,j2αj2+j=1∑m−1σT,j2βj2+j=1∑m−1σρ,j2(ρj−ρˉj)2
在寻找最优解的时候,计算 I m o d e l ( x , y ) I_{model}(x,y) Imodel(x,y)的时候会产生的问题是,此时的model 是一个Mesh网格,如何提取出相应的(x,y)坐标的属性值,
I
r
,
m
o
d
e
l
,
k
=
(
i
r
,
a
m
b
+
i
r
,
d
i
r
⋅
(
n
k
l
)
)
R
ˉ
k
+
i
r
,
d
i
r
s
⋅
(
r
k
v
k
)
ν
I_{r, model, k} = (i_{r, amb} + i_{r, dir} \cdot (n_{k}l))\bar R_{k} + i_{r,dir}s \cdot (r_{k}v_{k})^{\nu}
Ir,model,k=(ir,amb+ir,dir⋅(nkl))Rˉk+ir,dirs⋅(rkvk)ν
上面的式子中,
l
l
l是光照的方向,
v
k
v_{k}
vk是相机位置和三角形中心位置的正交化差值,
r
k
=
2
(
n
l
)
n
−
l
r_{k} = 2(nl)n-l
rk=2(nl)n−l是反射光的方向向量,
s
s
s表示表面的反射率,
ν
\nu
ν控制镜面反射的角分布。如果存在阴影投影到一个三角形的中心位置的时候,以上公式可以化简为:
I
r
,
m
o
d
e
l
,
k
=
i
r
,
a
m
b
R
ˉ
k
I_{r, model, k} = i_{r, amb} \bar R_{k}
Ir,model,k=ir,ambRˉk,对于高分辨的三维网格(即更密的三维网格)的时候,每个三角形之间的差异会变得很小,因此
E
I
E_{I}
EI可以由以下的公式近似得到:
E
I
≈
∑
k
=
1
n
t
a
k
⋅
∥
I
i
n
p
u
t
(
p
ˉ
x
,
k
,
p
ˉ
y
,
k
)
−
I
m
o
d
e
l
,
k
∥
2
E_{I} \approx \sum_{k=1}^{nt} a_{k}\cdot \Vert I_{input}(\bar p_{x,k}, \bar p_{y,k}) - I_{model, k}\Vert ^{2}
EI≈k=1∑ntak⋅∥Iinput(pˉx,k,pˉy,k)−Imodel,k∥2
a
k
a_{k}
ak是三角形k对应的图像区域,在进行计算的时候,使用随机梯度下降的方法来达到最优值,为了避免由于噪声出现的陷入局部最优的情况,每次计算的时候,从
κ
⊂
(
1...
n
t
)
\kappa \subset ({1...n_{t}})
κ⊂(1...nt)随机取出子集进行计算,然后进行以下的计算:
E
κ
=
∑
k
∈
κ
∥
I
i
n
p
u
t
(
p
ˉ
x
,
k
,
p
ˉ
y
,
k
)
−
I
m
o
d
e
l
,
k
∥
2
E_{\kappa} = \sum_{k \in \kappa} \Vert I_{input}(\bar p_{x, k}, \bar p_{y, k}) - I_{model, k}\Vert^{2}
Eκ=k∈κ∑∥Iinput(pˉx,k,pˉy,k)−Imodel,k∥2
配准流程:
- 对输入图像进行down-sample(下采样)处理,
- 先从 α ⃗ 、 β ⃗ \vec \alpha 、\vec \beta α、β进行优化,然后加入 ρ ⃗ \vec \rho ρ,在每次的子迭代过程中,逐步添加需要的元素和组件。
- 先尝试较大值 σ N \sigma _{N} σN, 然后逐渐减小 σ N \sigma _{N} σN
- 在最后的迭代过程中,脸部模型的分解为小的Segment, 这个时候固定好 ρ ⃗ \vec \rho ρ, 然后对于每一个Segment, 分别对 α ⃗ \vec \alpha α和 β ⃗ \vec \beta β参数进行优化,这样可以使得脸部的细节特征达到一个较好的优化。
找到最优值 α ⃗ 、 β ⃗ 、 ρ ⃗ \vec \alpha 、\vec \beta、\vec \rho α、β、ρ后,相应的三维脸部模型就可以按照参数建立得到。
后记
写到的这里就结束了,基于图像的建模的方法已经记录了下来,还有一少部分有空的时候再贴上来,由于刚开始读文献,对各种涉及到的方法理解不深刻,难免会有错误,望各位指出。