人脸识别,通常也叫人像识别、面部识别,是基于人的脸部特征信息进行身份识别的一种生物识别技术。
人脸识别系统,可以广泛应用于公安、金融、机场、地铁、边防口岸等多个对人员身份进行自然比对识别的重要领域。例如、身份证查验、金融开户、人脸门禁、人脸考勤、身份识别、网吧身份证核查、访客登记、实名制验证等场合。
人脸识别的过程大致如下:
在我们常见的人脸识别应用场景中,人脸图像源通常来自摄像头采集、照片或者一段视频录像。例如,常见的考勤系统的人脸源就来自实时的摄像头采集。
预处理是将人脸图像标准化。
在人脸图像采时,诸如光照明暗程度、距离远近、焦距大小以及设备性能的优劣等因素,一般会造成采集的人脸图像存在噪声、对比度不够,人脸在整幅图像中的大小和位置不确定。为了保证人脸图像中人脸大小,位置以及人脸图像质量的一致性,必须对图像进行预处理。
以知名的opencv为例,其提供的一些方法有:
▼直方图均衡
图像的直方图是它的像素灰度分布的图形表示
直方图均衡化,是把一个分布(给定的直方图)映射到另一个分布(一个更宽更统一的强度值分布),所以强度值分布会在整个范围内展开。
简单来说,就是在一定范围内,使每个灰度的像素数大致平衡。可行的方法是使用累积分布函数。对于直方图H(i),其累积分布H′(i)为:
将灰度i调整为其累积概率H′(i)*255。
直方图均衡,直观来看(摘自opencv的示例)
▼中直滤波
中值滤波是一种非线性的信号处理方法,对于图像来说,中值滤波器遍历每个像素,并用其相邻像素的灰度中位数(位于单个像素周围的正方形邻域)中替换每个像素。
进行中值滤波不仅可以去除孤点噪声,而且可以保持图像的边缘特性,不会使图像产生显著的模糊。
▼灰度归一化
归一化是一种简化计算的方式。
例如,[0,1]标准化,其过程是遍历数组r里的每一个数据,将Max和Min的记录下来,并通过Max-Min作为基数(即Min=0,Max=1)进行数据的归一化处理:
对于图像的灰度归一化,一般是把每个像素的灰度映射的[0,255]之间,也就是我们常说的“灰度图像”。
人脸检测,就是判定给定图像中是否存在人脸;如果存在人脸,则给出人脸所在区域坐标范围。
人脸检测的难点在于:
评价一个人脸检测算法的好与坏是检测率和误报率:
按照发展过程,分为早期模版匹配人脸检测算法、AdaBoost学习人脸检测算法,以及当前基于深度学习框架的人脸检测算法。
这些基于深度学习的人脸检测算法都实现了比传统Boosting算法更高的精度。但计算量很大,常常需要显卡加速,这也限制了它们在实际中的应用。
在实际工程应用中,用得广泛的人脸检测算法还是基于Adaboost的这些算法,主要是其计算量小,特别适合在嵌入式端实现,或者是基于浅层的神经网络检测算法。
特征提取指的是使用计算机提取图像信息,决定每个图像的点是否属于一个图像特征。特征提取的结果是把图像上的点分为不同的子集,这些子集往往属于孤立的点、连续的曲线或者连续的区域。
对于人脸特征而言,符合人自然直觉的特征通常是“额头”、“眉毛”、“眼睛”、“鼻子”、“嘴巴”、“双颊”等面部器官,而且各个面部器官的位置关系也属于特征,例如两眼之间的距离、眼睛和鼻子的距离等。
如图,dlib库可检测的人脸的68个特征点,五官51个,轮廓17个。
人脸特征提主要方法有:
在线系统,通常分人脸采集端做一些人脸预处理、检测,服务端做人脸注册、特征提取和比对。在线系统大致如下
人脸识别的本质是计算两幅图像中人脸的相似程度,其过程分为两个阶段:
特征比对一般分为1:1和1:N,简单来说就是验证“我是我”和搜索“我是谁”。
1:1比对,常见于会员登陆,将实时采集的“我A”的人脸图像和系统已经存在的“我B”的图像进行特征比对,验证“我A”和“我B”的相似程度是否达到了预设阈值。
1:N比对,我们常见的应用场景可能就是刷脸考勤了,将实时采集的“我”的人脸图像和系统已经存在的所有人脸图像进行特征搜索,找到达到预设阈值且最像“我”的图像。
特征比对的结果,往往都有置信概率(或者说相似系数),概率越大比对结果越可信。
人脸识别系统,其过程大同小异,按照是否联网可分为离线识别系统、在线识别系统。
离线系统,通常是人脸的预处理、检测、注册、比对等都可以在单机上完成。
在线系统,通常分人脸采集端做一些人脸预处理、检测,服务端做人脸注册、特征提取和比对。在线系统大致如下:
其中,对于在线系统,特征提取也可以放在终端进行,其优点就是分担了服务端的计算压力,减少了终端和服务端之间的通信带宽;但缺点也很明显,人脸识别算法升级成本较高,需要一个一个终端升级。
人脸识别发展至今,已经较为成熟和完善了,商用或者开源的解决方案也有不少。其中知名开源库,如opencv、dlib都较为常用,且都可以多平台使用。
本文选择开源库SeetaFace作为人脸识别引擎,其原因为SeetaFace较为小巧、方案基本完整、易用性、准确率较好,虽然不如opencv完整、dlib专业,但已经达到了可用级别。
该引擎由中科院计算所山世光研究员带领的人脸识别研究组研发。代码基于C++实现,且不依赖于任何第三方的库函数,开源协议为BSD-2。(注:最新的版本为SeetaFace2,但并未开放源码,只提供了Window、Linux、Android上的二进制库文件)
SeetaFace基于C++实现且不依赖于任何第三方的库函数,这意味着只要平台支持C++语言环境,即可集成SeetaFace。
▼引擎组成
SeetaFace人脸识别引擎包括了搭建一套全自动人脸识别系统所需的三个核心模块,即:人脸检测模块、面部特征点定位模块、人脸特征提取与比对模块。
因为SeetaFace基于C++,且不依赖其他第三方库,所以我们可选的平台较为广泛,Window、Linux、MacOS、Android、IOS均可,较为流行的树莓派上也可以使用。
本文选择使用移动平台Android和IOS,也就是只要一部Android或者IOS手机即可——这样的智能手机已经具备了人脸识别所需要的所有硬件资源和软件环境。
为简单起见,我们选择使用离线模式搭建单机版人脸识别系统。(尽管是离线单机,但很容易扩展成在线模式)
本文大致介绍了如何搭建一套在线或者离线人脸识别系统。本文所采用的SeetaFace引擎并虽然小巧、使用方便,但其作者并没有开放模型训练部分,只能使用作者提供的训练好的模型。
尽管如此,SeetaFace已经能够满足多平台人脸识别系统的基本需求了。