人脸识别概述
人脸识别,特指利用分析比较人脸视觉特征信息进行身份鉴别的计算机技术。属于生物特征识别技术的一种。
广义的人脸识别实际包括构建人脸识别系统的一系列相关技术,包括人脸图像采集、人脸定位、人脸识别预处理、身份确认以及身份查找等;而狭义的人脸识别特指通过人脸进行身份确认或者身份查找的技术或系统。
人脸识别典型流程
典型流程分为3个步骤:
1)人脸检测: 对图像中人脸位置的检测
2)人脸对齐: 对人脸的位置进行矫正居中
3)人脸特征表示:用深度网络学习高维特征
人脸检测算法简介
人脸检测的目标是找出图像中所有的人脸所对应的位置,算法的输出是人脸外接矩形在图像中的坐标,可能还包括姿态如倾斜角度等信息。
人脸检测算法研究分为3个发展阶段:
- 基于模板匹配的算法
- 基于AdaBoost的框架
- 基于深度学习的算法
一、基于模板匹配的人脸检测算法
用一个人脸模板与被检测图像中的各个位置进行匹配,确定这个位置是否有人脸。即针对图像中某个区域进行人脸-非人脸二分类的判别。
二、基于AdaBoost框架的人脸检测算法
Boost算法是基于PAC(Probably Approximately Correct)学习理论而建立的一套集成算法。Boost的核心思想就是利用多个简单的若干分类器,构建出准确率高的强分类器。
三、基于深度学习算法的人脸检测算法
CNN应用在人脸检测后,在精度上大幅度超越了之前的AdaBoost框架。
Cascade CNN 是传统技术和深度网络结合的一个代表。其包含了多个分类器,这些分类器采用级联结构进行组织,用卷积网络作为每一级的分类器。
人脸识别算法简介
人脸识别算法的研究分为3个发展阶段:
- 早期算法:基于几何特征、模板匹配、子空间等
- 人工特征+分类器
- 基于深度学习的算法
一、早期算法
线性降维:(子空间算法)将人脸图像当作一个高维向量,将其投影到低维空间后,期望得到的低维向量对不同的人具有区分度。
非线性降维:(流形学习)假设向量点在高维空间中的分布具有某些几何形状,然后在保持这些几何形化约束的前提下将向量投影到低维空间中。
二、人工特征+分类器
比较成熟的分类器如逻辑回归、贝叶斯、支持向量机、神经网络等。用于人脸识别的计算机视觉中描述图像的特征如 HOG、SIFT、Gabor、LBP等。
三、基于深度学习的人脸识别算法
主要两个经典模型:Facebook 在 CVPR 2014 发布的 DeepFace 和 Google 在CVPR 2015 发布的 FaceNet。
DeepFace
DeepFace是深度卷积神经网络在人脸识别领域的奠基之作。使用3D模型来解决人脸对齐问题,同时又使用了9层深度网络来做人脸特征表示。损失函数使用了Softmax Loss,最后通过特征嵌入(Feature Embedding)得到固定的人脸特征向量。DeepFace在LFW上取得了97.35%的准确率。
模型架构如图:
FaceNet
Google提出了使用三元组损失函数(Triplet Loss)代替Softmax Loss。在一个超球空间上进行优化使类内距离更紧凑,类间距离更远,最后得到了一个紧凑的128维人脸特征,其网络使用 GoogleNet 的 Inception 模型,模型参数量更小,精度更高。FaceNet 是一个解决人脸识别和人脸聚类问题的全新深度神经网络架构,其在LFW(Labeled Faces in the Wild)人脸识别数据集上十折平均精度达到99.63%。
模型架构如下:
人脸检测工具介绍
OpenCV
开源计算机视觉库(Open Source Computer Vision Library,OpenCV),遵从BSD协议许可,具有C++,Python和Java接口,支持Windows,Linux,Mac OS,iOS 和Android。OpenCV专为提高效率而设计,专注于实时应用。该库以优化的C/C++编写,通过OpenCL可以启用多核处理和硬件加速模式。
安装OpenCV的Python接口:pip3 install opencv-python
实现(基于OpenCV API)
import cv2
import sys
## Get user supplied values
# 获取图片路径
imagePath = sys.argv[1]
# 已经下载好的正面人脸特征值(.xml文件)
cascPath = "haarcascade_frontalface_default.xml"
## Create the haar cascade
# 应用cascade分类器
faceCascade = cv2.CascadeClassifier(cascPath)
## Read the image
# 如果有错误,下面这行代码改成相对路径形式加载图片 "iamge = cv2.imread('./test_face_detection.jpg')"
image = cv2.imread(imagepath)
# 用cv2的COLOR_BGR2GRAY方法转变为灰度图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
## Detect faces in the image
# 用分类器的detectMultiScale方法来检测人脸,默认参数
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30)
)
# len(faces):人脸框的个数
print("Found {0} faces!".format(len(faces)))
## Draw a rectangle around the faces
# (x,y):矩形框左上角的坐标,w:矩形框的宽度,h:矩形框的高度
# 利用左上角和右下角的坐标画矩形框,(0,255,0)是RGB三通道,此处表示绿色框
for (x, y, w, h) in faces:
cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2)
# ”Faces found“ 图像文件取名
cv2.imshow("Faces found", image)
# 设置窗口停留(无限长延时)
cv2.waitKey(0)
face_recongnition库进行人脸检测
使用Dlib(一个包含机器学习算法的C++开源工具包)最先进的面部识别功能构建而成,具有深度学习功能。支持批处理。该模型在LFW上的准确率为99.38%。
安装:pip3 install face_recognition
Notes:安装 face_recognition之前需要安装依赖库 cmake、dlib。
实现(基于 face_recognition)
import cv2
import sys
import face_recognition
# Get user supplied values
imagePath = sys.argv[1]
# Load the image with face_recognition
image = face_recognition.load_image_file(imagePath)
# Detect faces in the image(face_location方法)
face_locations = face_recognition.face_locations(image)
print("Found {0} faces!".format(len(face_locations)))
# Read the image with openCV
image = cv2.imread(imagePath)
# Draw a rectangle around the faces
# (top,right,bottom,left):分别是上、右、底、左的坐标。如左上角坐标(left, top)
for (top, right, bottom, left) in face_locations:
cv2.rectangle(image, (left, top), (right, bottom), (0, 255, 0), 2)
cv2.imshow("Faces found", image)
cv2.waitKey(0)
比较
前面用 OpenCV API 实现中的cascade特征是一个正面特质,也就是所用特征就不全,所以检测效果就不太好。face_recognition 的效果就相对好一点。
两种API返回的检测框的坐标也不一样。前者是左上角的坐标和检测框的宽高,后者是检测框上下左右的坐标位置。
FaceNet模型解析
如图是基于深度神经网络搭建的基本框架。首先对输入图像数据的人脸进行检测,然后进行人脸对齐。把得到的人脸图片输入到深度神经网络,通过卷积学习到人脸的特征向量。最后是利用了三元组Loss对比人脸特征向量进行比对(计算距离),如果小于设定阈值,则认为是同一个人,否则不是同一个人。
FaceNet 在复杂光照和姿态下表现也比较出色
上图每行都是同一个人,阈值为1.1。该模型可以准确的检测出每行两个人脸图片(光照和姿态不同)之间的距离小于给定阈值,而从列上来看,距离都大于给定阈值,也就是说列向不是同一个人。
一、The Triplet Loss
核心思想:应用 Triplet Loss 前把人脸图像编码为d维空间向量。训练使得同一人的不同人脸向量间距离小,不同人间向量距离大。
(该图来源于吴恩达深度学习)
Notes: 从左至右称作Anchor(A),Positive§,Negtive(N)。
其中Anchor(基准人脸图像)、Postive(同一人的人脸图像)、Negtive(不同人的人脸图像)
或者也可以通过下图来理解,学习之前 Anchor和Negtive之间的距离进,与Postive之间的距离远。学习之后,Anchor与Negtive之间的距离远,与Postive之间的距离进。
距离需要满足如下公式:
∣ ∣ f ( A ( i ) ) − f ( P ( i ) ) ∣ ∣ 2 2 + α < ∣ ∣ f ( A ( i ) ) − f ( N ( i ) ) ∣ ∣ 2 2 \mid \mid f(A^{(i)}) - f(P^{(i)}) \mid \mid_2^2 + \alpha < \mid \mid f(A^{(i)}) - f(N^{(i)}) \mid \mid_2^2 ∣∣f(A(i))−f(P(i))∣∣22+α<∣∣f(A(i))−f(N(i))∣∣