广播说明:
进入深度学习时代,如下的方法已经失去可比性,且我们的代码实现地很粗糙,如果坚持要用,推荐如下代码
https://github.com/wanglin193/SupervisedDescentMethod (看起来作者对sdm实现的不错)
另外一篇基于深度学习的基于回归的方法,也是使用的基于SDM的相同的思路,但是全部深度学习化,
更加鲁棒。 见:《Stacked Hourglass Network for Robust Facial Landmark Localisation》
本方法是当前人脸对齐最流行的算法,速度很快,很稳定。下面我将介绍一下这篇文章的整体思路和相关细节。
在介绍之前,先给出几个有用的链接:
1.)
本论文作者主页,形象地介绍了SDM的特点:
http://xiong828.github.io/sdm.html
2. )
superviseddescent C++11版本的实现:
http://patrikhuber.github.io/superviseddescent/
下面开始介绍:
人脸对齐就是要找人脸的特征点。如图
。
我们要找到眼睛、鼻子、嘴巴等特征点。那么如何去做呢?方法有很多。本文讲述了使用SDM去求特征点的方法。假设我们有一个初始的特征点x0x0,希望通过迭代,逐步求出准确地特征点x∗x∗。这就是大致的思路。
SDM方法(Supervised Descent Method )
Derivation of SDM
给定一幅含有m个像素的图像d∈Rm×1d∈Rm×1,d(x)∈Rp×1d(x)∈Rp×1用来索引图像的p个特征点,x代表p个特征点。h(d(x))∈R128p×1h(d(x))∈R128p×1代表SIFT特征向量。在训练阶段,我们假设准确的p个特征点已知,设为x∗x∗。我们另外选取训练集特征点的平均值x0x0作为初始值。如图:
这样,Face Alignment可以通过在ΔxΔx求解如下的最优化问题:
这里 Φ∗=h(d(x∗))Φ∗=h(d(x∗))代表手工标记的特征点的SIFT特征。在训练阶段, Φ∗Φ∗和 ΔxΔx已知。
对上面关于 ΔxΔx求导,令 f′(x0+Δx)=0f′(x0+Δx)=0,可得
,这里 Φ0=h(d(x0))Φ0=h(d(x0)).
令 R=−2H−1JTh,ΔΦ0=Φ0−Φ∗R=−2H−1JhT,ΔΦ0=Φ0−Φ∗,于是R可看作 Δx1Δx1到 ΔΦ0ΔΦ0的线性回归系数。但是,我们知道在测试阶段, Φ∗Φ∗是未知的,但是固定的。因此我们不再使用 Φ∗Φ∗做训练,而是改用下面的公式:
使用训练样本,我们的方法可以学习 R0,b0R0,b0.
通常这种方法不可能一步迭代完成,需要进行多步,除非f是二次的。为了处理这个非二次的方程,SDM将产生一系列的下降方向 {Rk}{Rk}和偏差 {bk}{bk}.
即
Learning for SDM
假定给定一系列人脸{di}{di}与对应的特征点{xi∗}{x∗i}.对于每张图片,从初始的特征点xi0x0i出发,R0,b0R0,b0可以通过求解最优化问题获得:
这里 Δxi=xi∗−xi0,Φi0=h(di(xi0))Δxi=x∗i−x0i,Φ0i=h(di(x0i)).
我们假定 xi0x0i可以从服从正态分布的人脸检测框对齐采样。于是上面的最优化问题化为:
以上方程是个线性的最优化问题,可以直接求解。
当第一步求解完毕后,代入方程式(1),可以求出 x1x1,进而又可以计算特征向量 Φik=h(di(xik))Φki=h(di(xki))和 Δxki∗=xi∗−xikΔx∗ki=x∗i−xki.这样 Rk,bkRk,bk可以通过一个新的线性回归得到。
随着k的增大,误差逐渐减小,一般4到5次的迭代就可以达到比较好的效果。
Training for SDM
当我们计算出一系列的{Rk},{bk}{Rk},{bk},我们就可以通过迭代式(1)通过迭代求解特征点。一般初始的特征点可以选取训练时的初始特征点。
后续我们还会给出SDM方法的Matlab代码及相关说明,你就会看到比较清楚的步骤和效果了。