hi,欢迎访问本站!
当前位置: 首页学习笔记正文

人脸特征点提取详解

用户投稿 学习笔记 13阅读
前言

开先河之作,是1992年Cootes提出的ASM模型。ASM方法从局部的特征来检测点,对噪声很敏感。1998年Cootes提出改进都AAM,但对于初始化和appearance的改变很敏感。两者都使用了shape model(PCA),它的缺点是模型不够灵活,不能实现细微调整(如主成分维度不变)。

更多总结: 人脸关键点检测总结

CVPR2012上有一篇非常有名的特征点定位,提出了非参数的形状约束,使用了two level cascaded regression和shape indexed features,提高了对于人脸appearance的变换,提出了correlation based features selection,解决了大训练集的训练问题,提高了时间效率。

大致流程如下: 首先算法得输入是一张人脸图片,观察图片,发现其实人的五官大体位置是有的。算法一开始,就给了一个大体的初始位置。这个初始位置是根据经验设定的: 初始位置有了,我们在每个点的周围按照预先规定的要求取两个点,算出这两个点的灰度差值。然后将这个差值按照预先规定的方式归一化到0-511内,假设这个值为120。比较120与th1的大小,如果120>th1,那么我们生成一串数字【001】。如果120<=th1,那么我们再按照预先规定的方式取两个点,同样算出这两个点的灰度差值,同样按照的方式归一化到0-511内,假设这个值为50,然后比较50与th2的大小,如果50>th2,我们生成一串数字【100】;如果50<th2,那么我们就生成一串数字【010】。th1,th2也是预先规定的: 经过上面这样的一个决策树,我们得到一串数字100,或者010,或者001。

实际上,每个关键点生成了4个决策树,每个决策树中规定的取点位置不同,每个决策树中的th1,th2的具体取值也不同,也就是4个不同的树。经过一个树得到一串数字。经过4个树,得到4串数字,比如[100][010][001][010],连起来写的话,就是一串有12个值的数字[100 010 001 010]。这是一个稀疏向量,大部分数字都是0。

由于每个点有4个决策树,我们这里有5个关键点,所以我们事先准备了5* 4=20个决策树树。每个树得到3个数字。20个树就得到20* 3=60个数字,即长度为60的向量。

这60个数字,是由0和1组成的,所以叫binary feature,二值特征。又因为这些数字是在关键点初始位置周围取的点求的,所以又叫 local binary feature,LBF,局部二值特征。

一张图片得到了一个LBF特征。这个1x60的特征向量与另一个1x60的权重向量 w 1 w_1 w1​做点积,然后加上一个常数 b 1 b_1 b1​,就得到了一个值 δ 1 \delta_1 δ1​, 将这个 δ 1 \delta_1 δ1​加到初始位置的第1个点的x坐标上; 同样再与另一个1x60的向量 w 2 w_2 w2​做点积,再加上一个常数 b 1 b_1 b1​,就得到了一个值 δ 2 \delta_2 δ2​ ,将这个 δ 2 \delta_2 δ2​ 加到初始位置的第1个点的y坐标上。: δ 1 = L B F ∗ w 1 + b 1 \delta_1=LBF * w_1 +b_1 δ1​=LBF∗w1​+b1​ δ 2 = L B F ∗ w 2 + b 2 \delta_2=LBF * w_2 +b_2 δ2​=LBF∗w2​+b2​

这里 w 1 w_1 w1​, b 1 b_1 b1​, w 2 w_2 w2​, b 2 b_2 b2​都是预先训练好的,这里实际上是一个线性预测模型。为了移动一个点,用了4个决策树,生成一个LBF特征,又用了2个线性预测模型,分别预测了点在x轴,y轴上的移动量,完成一个点的移动。移动5个点,一共用了4* 5=20个决策树,2* 5=10个线性预测模型。

通过上述步骤就将第1个关键点移动了[ δ 1 \delta_1 δ1​, δ 2 \delta_2 δ2​],就把关键点从初始位置,移动到了关键点应该所在的位置: 同样的方法,我们得到 [ δ 3 , δ 4 ] , [ δ 5 , δ 6 ] , [ δ 7 , δ 8 ] , [ δ 9 , δ 1 0 ] [\delta_3,\delta_4],[\delta_5,\delta_6],[\delta_7,\delta_8],[\delta_9,\delta_10] [δ3​,δ4​],[δ5​,δ6​],[δ7​,δ8​],[δ9​,δ1​0],分别把第2,3,4,5个关键点进行移动: 将移动后的5个点,作为初始位置,上述步步骤,再对点移动一次。采用的还是采用20个决策树,10个线性模型.

但是要注意的是决策树的取点方式,th1,th2,线性模型的w,b都与第一次移动时不同,这些值也是专门设定的。

将移动后的5个点,作为初始位置,再对点移动一次。这里决策树和线性模型的参数又与前两次都不同。

FPS3000算法一共对点移动了四次,得到最终的关键点结果:将白色点移动到了蓝色点的位置。

上面过程中,所有预先设定的值,都是通过训练得到的,随机森林是由随机树组成的,随机树的核心元素是树,所以我们得先搞清楚树:

决策树训练

训练树的目的是利用树来提取特征,一棵树负责一个关键点。我们这个问题是为了求取点坐标的偏移量的。所以就以【(目标坐标-初始坐标)-偏移量】为loss。优化这个树,使loss取最小。

其实用图像的常用特征也是可以的,hog,lbp,sift,但是常用特征图是比较慢的。上述特征,都有“梯度”,这个是保证这些特征有效的核心思路。图像上,梯度的本质反应的是不同位置的像素值之差。那么我们的特征要设计成某两个点像素值之差,才能保证效果。

由于我们设计这个特征目的是要用初始点预测出偏移量的。所以特征要由初始点决定,所以就取初始点周围的点进行计算差:随机在初始点周围取两个点计算像素值的差值diff。

FPS3000算法中的取点方法,以及diff值的计算: 产生一组随机数 ( r 1 , θ 1 ) (r_1,\theta_1) (r1​,θ1​), 代表半径和角度。这样如果给了一个点 ( x 0 , y 0 ) (x_0,y_0) (x0​,y0​) ,就可以得到了一个新的点 ( x 1 , y 1 ) (x_1,y_1) (x1​,y1​),再产生一组随机数 ( r 2 , θ 2 ) (r_2,\theta_2) (r2​,θ2​),再由点 ( x 0 , y 0 ) (x_0,y_0) (x0​,y0​)得到新点 ( x 2 , y 2 ) (x_2,y_2) (x2​,y2​),计算公式如下:

x ∗ = x 0 + r ⋅ c o s ( θ ) x_* = x_0 + r\cdot cos(\theta) x∗​=x0​+r⋅cos(θ) y ∗ = y 0 + r ⋅ s i n ( θ ) y_* = y_0 + r\cdot sin(\theta) y∗​=y0​+r⋅sin(θ)

这样,我们就能计算两个点的差值了: d i f f = i m g ( x 1 , y 1 ) − i m g ( x 2 , y 2 ) diff = img(x_1,y_1)-img(x_2,y_2) diff=img(x1​,y1​)−img(x2​,y2​) fps3000算法里,提取了1000个随机diff来构造样本对: [ d i f f 1 , . . . . , d i f f 1000 ] [diff_1,....,diff_{1000} ] [diff1​,....,diff1000​] 训练时,我们取了1000个diff。训练完成后,我们只用取一个diff就能完成分类

假设有1356张图片可训练,一次训练一个关键点的一颗树,以第一个关键点为例:

对每张图上的第一个关键点,提取1000个 diff 构造成一个特征向量。得到共1356个特征向量,每个向量有1000个diff。也就是说有1356个diff1,1356个diff2,…1356个diff1000.计算每张图上,第一个关键点的初始位置和标注位置的差值,构成我们的待预测的值,目标值从1356个 d i f f 1 diff_1 diff1​中,随机取一个值,设这个值为th1,然后比较每个 d i f f 1 diff_1 diff1​与th1的大小,小于等于th1的放到一类left,大于th1的放到另外一类right,利用这个th1,将1356个特征向量分成两类,然后计算每类的 l o s s = v a r ( e r r ) loss=var(err) loss=var(err),再加权求和得到两类的总 l o s s 1 loss_{1} loss1​.注意到这个diff1对应着自己的独有的取点方法。从1356个diff2中,和上面相同,随机取一个值,设这个值为th2,然后比较每个diff2与th2的大小,小于等于th2的放到一类left,大于th2的放到另外一类right,利用这个th2,将1356个特征向量分成两类,然后计算每类的loss=var(err),再加权求和得到两类的总 l o s s 2 loss_{2} loss2​.这个diff2也对应着它自己独有的取点方式。计算 l o s s d 3 , l o s s d 4 , . . . , l o s s 1000 lossd_3,lossd_4,...,loss_{1000} lossd3​,lossd4​,...,loss1000​,我们一共得到1000个loss: [ l o s s 1 , l o s s 2 , l o s s 3 , . . . , l o s s 1000 ] [loss_1,loss_2,loss_3,...,loss_{1000}] [loss1​,loss2​,loss3​,...,loss1000​]查看所有loss中谁最小,找到最小loss其对应的th,还有其对应的diff,以及diff对应的独有的取点方法,找到对应的left类和right类。我们就把这个th和其对应的独有的取点方式保存到树的第一个节点。到这里我们完成了第一个节点的训练对6步中的left类的特征向量,重复3-6步,得到第一个节点的左节点的th,取值方法和left类,right类。到这里我们完成了第一个节点的左节点的训练。对7步中的left类,重复3-6步,得到第一个节点的左节点的左节点th,取值方法。得到第一个节点的左节点的左节点的训练。对7步中的right类,重复3-6步,得到第一个节点的左节点的右节点的th,取值方法。得到第一个节点的左节点的右节点的训练。对6步中的right类,重复3-6步,得到第一个节点的右节点的th,取值方法。

通过上述步骤,我们用1356张图片,完成了一颗树的训练。每张图片的第一个关键点周围随机取了1000个diff进行了训练,训练过程中的每个节点的th也是随机取了,经过计算比较,选择出了最合适的取点方式 ( r , θ ) (r,\theta) (r,θ)以及th值。由于是随机取的,所以这个树叫随机决策树。

通过这个随机决策树,我们可以得到这个随机决策树对应的LBF特征[010],这就是第一个关键点对应的LBF特征。

我们针对第1个关键点,训练了一个随机决策树,提取到了LBF[010]。我们还可以针对第2个,第3个…关键点,训练一个随机决策树,提取LBF。把每个关键点的LBF放到一起,拼接起来,得到图片上所有关键点的 L B F a l l LBF_{all} LBFall​

怎么让随机决策树训练成为森林呢?

从1356张图片,随机取N张图片,用这N张图片,训练一个随机决策树再从1356张图片,随机取N张图片,用这N张图片,训练一个随机决策树再训练一个随机决策树再训练一个随机决策树

上述这样4个随机样本图片训练的随机树,就构成了随机森林。

这里有2层的随机。随机样本训练的随机决策树们,构成了随机森林。重复这个过程:随机的选取图片集,在关键点周围随机的取点,训练出随机树。把森林中所有树的LBF拼接到一起,就构成了所有关键点的LBF。

把森林中,所有树的LBF拼接到一起,就构成了所有关键点的LBF。

怎么完成随机森林的训练?

重复这个过程:随机的选取图片集,在关键点周围随机的取点,训练出随机树。

再探framwork

上图描述了整个framework。首先使用随机森林对每个landmark学习抽取local binary features(LBF)的方式 Φ t = { ϕ l t } Φ_t=\{ϕ^t_l\} Φt​={ϕlt​}。再把LBF输入到一个全局的回归器进行回归,预测出landmark的真实位置。

其中 ϕ l t {ϕ^t_l} ϕlt​表示第 t 级第 l l l个landmark对应的随机森林。这个maping可以输出LBF特征。 Φ t Φ_t Φt​则是 { ϕ 1 t , ϕ 2 t , . . . ϕ l t } \{ϕ^t_1,ϕ^t_2,...ϕ^t_l\} {ϕ1t​,ϕ2t​,...ϕlt​},即所有landmark特征的组合。

训练阶段如下,对 s a m p l e i sample_i samplei​的第t个训练阶段,首先用 ϕ t ϕ_t ϕt​提取出相应的LBF特征。然后以最小化 E 为目标得到 R t Rt Rt, 最后把上一次的估计和本次估计的Δ求和作为新阶段输出:

f e a t u r e s i = ϕ t ( I i , S i t − 1 ) features_i=ϕ^t(I_i,S^{t−1}_i) featuresi​=ϕt(Ii​,Sit−1​) ------------- (1) Δ S i ^ = S i ^ − S i − 1 Δ\hat{S_i}=\hat{S_i}−S^{i−1} ΔSi​^​=Si​^​−Si−1 -------------------------- (2) E = ∑ ∣ ∣ S i ^ − R t ( f e a t u r e s i ) ∣ ∣ E=\sum{||\hat{S_i}-R^t(features_i)||} E=∑∣∣Si​^​−Rt(featuresi​)∣∣ ---- (3) Δ S = R t ( f e a t u r e s i ) ΔS=R^t(features_i) ΔS=Rt(featuresi​) ------------------ (4) S i t = S i t − 1 + Δ S i S^t_i=S^{t−1}_i+ΔS_i Sit​=Sit−1​+ΔSi​ ------------------------- (5) 式中 I I I表示人脸图像, R t R_t Rt​需要根据图像和形状的位置信息,预测出一个形状变化,就是位置变化量 ( δ x , δ y ) (\delta_x,\delta_y) (δx​,δy​),而 S i S_i Si​则为第i阶段的位置信息 ( x , y ) (x,y) (x,y)

特征提取

shape indexed features 使用的是像素对之间的差值来计算特征,这种提取方式计算复杂度非常低,也助理整个算法的提速。

整体流程是:

为了保证特征在脸部尺度变化和旋转情况下的稳定性,首先要计算一个从当前形状到平均形状的的变换矩阵;对转换后的图像的每个像素,都使用离其最近的一个landmark来作为这个像素的index;随机的在这些像素中选取P个,可以生成 P 2 P^2 P2 个像素对;(详情参照后面的特征点生成处)。一般我们取P=2个每个像素对之间intensity的差值即可以作为特征值。

实际使用时,我们的每个决策树实际上有4个分支。单个决策树LBF特征有4个。

并且我们能看到,再不断的迭代中,决策树的半径参数会逐渐缩小: 算了,懒得写了,写累了。。。。极简入门看下面的笔记吧: 《Face Alignment by Explicit Shape Regression》笔记 FaceAlignMentByExplicitShapeRegression阅读记录

特征点生成

第一层的每个若分类器 R t R^t Rt,随机选取P个像素,每两个之间做差生成一个features,于是就有PP个特征,更准确来说是P(P-1)/2个特征:

ESR方法采用的是在两个关键点附近随机出两个点,做这两个点之间的差值作为形状索引特征。

RCPR方法采用的选取两个关键点的中点,外加一个随机偏置来生成特征点,用两个这样的特征点的差值作为形状索引特征。

在LBF算法中,由于随机森林是针对单个关键点的,所有随机树种使用到的特征点不会关联到其他关键点,只有在当前关键点的附近区域随机产生两个特征点,做像素差值来作为形状索引特征。

随机选取的特征点并一定不可靠,实际上可采取correlation based features selection(CFS)。

特征选择CFS

CFS(correlation-based feature selection) 特征估计方法是估计特征子集并对特征子集进行排秩(不是对单个特征)。其核心是采用启发的方式评估特征子集的价值。 启发方式基于的假设:好的特征子集包含与类高度相关的特征,但特征之间彼此不相关。

启发式方程: M e r i t s = k r c f − k + k ( k − 1 ) r f f − Merit_s=\frac{kr^ { -}_{ cf }}{\sqrt{k+k(k - 1)r^ { - }_{ff}}} Merits​=k+k(k−1)rff−​ ​krcf−​​ M e r i t s Merit_s Merits​为包含k个特征的特征子集S的merit(类别区分能力), r c f ˉ \bar{r_{cf}} rcf​ˉ​为类别c与特征f的平均相关系数, r f f ˉ \bar{r_{ff}} rff​ˉ​为特征f中间的平均相关系数。r为Pearson相关系数,所有的变量需要标准化。

分子部分表示特征子集S的类预测能力;分母部分表示特征子集中的特征冗余程度。分子越大表示预测能力越强,分子越小表示冗余度越小。

底下的 k + k ( k − 1 ) r f f ˉ k+k(k-1)\bar{r_{ff}} k+k(k−1)rff​ˉ​实际上分为两部分,我们计算Pearson相关系数矩阵的时候,自相关的k个相关系数为1,黄色的一共k(k-1),其平均值为 r f f ˉ \bar{r_{ff}} rff​ˉ​,两者之和即特征之间相关性的平均值

详细可参考基于特征相关性的偏最小二乘特征选择方法

CFS首先从训练集中计算特征-类和特征-特征相关矩阵,然后用最佳优先搜索(best first search)搜索特征子集空间。

也可使用其他的搜索方法,包括前向选择(forward selection),后向消除(backward elimination)。前向选择刚开始没有特征,然后贪心地增加一个特征直到没有合适的特征加入。后向消除开始有全部特征,然后每一次贪心地去除一个特征直到估计值不再降低。

最佳优先搜索如下类似于贪心算法,详细如下:

可以开始于空集或全集,以空集M为例,开始时没有特征选择,并产生了所有可能的单个特征;计算特征的估计值(由merit值表示),并选择merit值最大的一个特征进入M,然后选择第二个拥有最大的merit值的特征进入M,如果这两个特征组合的merit值小于原来的merit值,则去除这个第二个最大的merit值的特征,然后在进行下一个,这样依次递进,找出使merit最大的特征组合。

在面对高维数据的今天,特征选择成为机器学习的一个重要任务,数百或数千个特征的数据集可能包含高度不相关和冗余的信息,这可能极大地降低学习算法的性能。特征选择算法分为两大类,filter(滤波器)模型或wrapper模型(Das,2001;Kohavi&John,1997)。filter模型依赖于训练数据的一般特征来选择一些特征,而不涉及任何学习算法。wrapper模型在特征选择中需要一个预先挖掘的学习算法,并使用其性能来评估和确定选择了哪些特征。

对于每个新的特征子集,wrapper模型需要学习一个假设(或分类器)。它倾向于找到更适合于预定学习算法的特征,从而产生更好的学习性能,但它也倾向于比filter模型更昂贵的计算(Lan gley,1994)。当特征个数很大时,由于其计算效率,通常选择filter模型。

特征工程更多方法可参考:特征工程——特征选择(Feature Selection),特征关联

Explicit Shape Regression非参数法

使用了two level cascaded regression和shape indexed features两个东西。

local binary features 就是局部二值特征,之前说过 shape indexed features

双层 cascaded回归 第一层有10级,第二层有500级,这样分层的好处,比单独使用一个5000级而只有1层的效果要好很多。

我们的人脸对齐是通过多次Shape regression迭代实现的(cascaded),由初始化到一轮迭代之后的shape,到最后贴合实际的人脸:

R t R^t Rt是使用前一个shape的shape indexed features学习来的,能够帮助boosted regression实现更好的几何不变性。

shape indexed features

主要参考: 人脸识别中的人脸关键点landmark算法:FPS3000

C++实现和解读Face Alignment at 3000fps via Local Binary Feature

人脸关键点数据集整理

标签:
声明:无特别说明,转载请标明本文来源!
发布评论
正文 取消