简介
基于深度卷积网络的人脸识别,流程基本上一致,如下图所示,可以看做是一个基本框架:
图1 人脸识别基本框架
由上图,可以看到,人脸识别分为以下几个主要步骤:
- 输入图像:可以做一些图像前处理操作,比如:调整亮度、去噪等
- 人脸检测:检测人脸位置,可以加入一些活体检测之类的算法
- 人脸对齐:实际场景中,人脸一般都是歪的,需要基于人脸关键点进行对齐
- 人脸裁剪:将对齐后人脸抠出,作为后续深度特征网络的输入
- 人脸特征提取:通过DCNN网络,对人脸图进行建模,得到人脸特征
- 人脸特征比对:使用比对算法,比对不同人脸特征,比如:余弦距离、欧氏距离等
详细介绍
Input Image -> Detect
输入:原始的可能含有人脸的图像
输出:活体人脸位置的bounding box
这一步称之为“人脸检测”(Face Detection),可以使用dlib、OpenCV现有的人脸检测方法,比如传统计算机视觉中的方法(Hog、Haar等特征)、深度学习YOLO等。
对人脸检测这一步感兴趣的可以参考下列资料:
dlib的实现: dlib C++ Library: Dlib 18.6 released: Make your own object detector!
openCV的实现:Face Detection using Haar Cascades
在金融等高安全场景,对检测到的人脸,还需判断是否为照片和视频等非活体人脸,需要将检测到的人脸输入活体分类网络,筛选出活体人脸。
另外,一般在进行该步骤之前,会进行图像预处理操作,这部分工作可能很多很复杂,比如:减少图像中的噪声干扰、提高清晰度,还有包括图像滤波、变换、转码、模数转化等,如下图所示,原始图像人脸太暗,需要先提个亮度,然后发现噪点太多,再做个降噪.....一顿操作后,感觉效果可以了,然后再进行之后流程:
图2 图像预处理
Detect -> Transform -> Crop
输入:原始图像 + 人脸位置bounding box
输出:“校准”过的只含有人脸的图像
对于输入的原始图像 + bounding box,这一步要做的事情就是要检测人脸中的关键点,然后根据这些关键点对人脸做对齐校准。所谓关键点(landmark),就是下图所示的绿色的点,通常是眼角的位置、鼻子的位置、脸的轮廓点等等,关键点个数有很多类型,可以参考资料(点击查看)。有了这些关键点后,我们就可以把人脸“校准”,或者说是“对齐”。解释一下:就是原先人脸可能比较歪,这里根据关键点,使用仿射变换将人脸统一“摆正”,尽量去消除姿势不同带来的误差。这一步我们一般叫Face Alignment(人脸对齐)。人脸对齐后,就可以进行人脸图扣取了。
图3 人脸对齐
对于人脸对齐感兴趣的,可以参考如下传统方法,特点是比较快,对应的论文是:
人脸关键点:
Crop -> Representation
输入:校准后的单张人脸图像(抠图后)
输出:人脸特征向量
这一步就是使用深度卷积网络,将输入的人脸图像,转换成一个向量的表示。在insightface中,使用的向量是512x1的,也就是一个512维的向量,该维度取决于特征网络,如下图是人脸特征提取网络示意图:
图4 人脸特征网络示意图
图5 人脸特征网络功能图
通过图4,不难发现,该网络就是一个分类网络,而实际特征提取的时候,只需要到conv5_3,,换言之,实际使用时,提取人脸特征,一般就是到卷积层的最后一层,而训练时,一般需要完整的分类网络(基于训练可行性)。
在理想的情况下,我们希望人脸特征向量具备如下性质:
- 同一个人的人脸图像,特征向量之间差异比较小
- 不同人的人脸图像,特征向量之间差异比较大
举个例子,如下是手写0-9数字CNN分类网络,让最后一层的向量变成2维后,可视化出来每一类对应的二维向量表示,图中每个颜色代表一个类别:
图6 手写0-9可视化特征向量
从图中可以看出,直接采用softmax训练得到的结果,不太符合我们理想特征的特点:我们希望同类尽可能接近,不同类尽可能的远,而图中,不同类之间距离很近,而同类之间(比如紫色)距离很远。
那么训练人脸特征的正确姿势是什么呢?其实有很多种方法,如下图所示,展示了几种损失函数类型。
图7 不同类型损失函数
损失函数介绍,可以参考如下:
通过设计不同的loss,最大程度达到我们理想的特征,如下图是采用center loss(中心点)训练后,可视化的MINIST(0-9分类)特征图分布,相对于图6,更加接近理想特征。
图8 采用center loss后的手写0-9可视化特征向量图
center loss介绍可以参考如下:
Recognition
经过上述流程,可以训练出人脸特征提取模型,之后就是基于该模型进行人脸比对,人脸比对有几个场景:
- 人脸验证(Face Identification):就是检测A、B是否是属于同一个人。只需要计算向量之间的距离,设定合适的报警阈值(threshold)即可。
- 人脸识别(Face Recognition):这个应用是最多的,给定一张图片,检测数据库中与之最相似的人脸。显然可以被转换为一个求距离的最近邻问题。
- 人脸聚类(Face Clustering):在数据库中对人脸进行聚类,直接K-Means即可。
关于向量距离计算,人脸识别一般采用余弦距离,其他还有欧氏距离、汉明距离、标准化欧式距离等,详细可以参考:
常用聚类算法,可以参考:
参考: