在人脸识别领域,有一些经典的算法,如特征脸、局部二值模式法、Fisherface等。然而,这里选择了一种广泛使用和流行的方法作为示例,称为OpenFace。当然我们不做实际测试,只是通过它了解识别原理。
OpenFace是一种基于模型的方法。它是一个开源库,包括landmark,head pose,Actionunions,eye gaze等功能,以及一个用于训练和检测所有源代码的开源人脸框架。
在前面的步骤中,我们已经介绍了如何利用HOG方法提取图像中人脸的特征数据,即成功检测到人脸。
这时候又出现了一个问题,就是这张脸的姿势好像不是那么“正”。同一个人,如果她的姿势和面部朝向不一样,人类还能认出她,但计算机不一定能认出她。
解决这个问题的一种方法是检测人脸主要特征的特征点,然后根据这些特征点对人脸进行对准和标定。这种方法是由瓦希德卡泽米和约瑟芬沙利文在2014年发明的。他们为面部的重要部位选择了68个标志点,这68个标志点的位置是固定的,所以经过一些训练就可以在任何一张脸上找到。
图片来源:OpenFace API
有了这68个点,我们就可以对人脸进行校正,主要是通过仿射变换来拉直原来歪扭的脸,尽量消除误差。这里的仿射变换主要涉及一些旋转、放大、缩小或者轻微的变形,而不是夸张的扭曲,所以看不出来。
图片来源:OpenFace github帮助页面
过程大概是这样的。原脸有一定程度的修正。
这样,我们可以输入原始人脸图像和HOG的特征向量,得到一个只包含姿态正确的人脸的图像。
注意,现阶段不能直接对比这张人脸图像,因为工作量太大,我们要做的是继续提取特征。
然后,我们把这张人脸图像输入到一个神经网络系统中,让它为这张脸生成128维向量,也可以说是这张脸的128个测量值,可以代表眼睛之间的距离,眼睛和眉毛之间的距离,耳朵的大小等等。这里只是举个例子供你理解。事实上,我们不知道128维向量代表什么特征。
当然,这一步说起来简单,但难点在于如何训练这样一个卷积神经网络。具体的训练方法不是我们需要了解的,但是可以了解一下训练思路。训练时,我们可以输入一张人脸图像的矢量表示、同一张人脸不同姿势的矢量表示和另一张人脸的矢量表示,重复类似操作,不断调整。调整的目标是使同一类别的对应向量表示尽可能接近,即同一个人的向量表示尽可能接近,同样,不同类别的向量表示尽可能接近。
其实训练的思路也很好理解,因为不管一个人的脸怎么变,有些东西在一段时间内是固定的,比如两眼的距离,耳朵的大小,鼻子的长短等等。
得到这128个测量值后,最后一步很简单,就是将这128个测量值与我们训练测试过的所有面部数据进行对比,最接近的测量值就是我们要识别的人。这样,一个人脸识别就可以完成了。