文章目录
前言
如何用人工"智障"快速的识别人脸呢?首先我们拿到一张图片,需要去看看图片中是否有人脸,如果有人脸,我们需要把人脸截取出来,放入到特征提取网络中去提取特征,再把提取好的特征向量进行分类,这样就实现人脸识别了。是不是也没有想象中的那么难呢?
本篇博客使用mtcnn作为人脸定位的网络,facenet作为特征提取网络,使用svm作为分类器,将facenet提取到的128维特征向量,用于训练svm,通过svm实现人脸的识别。这样简单的人脸识别系统就完成了。
接下来我会简要的介绍一下,mtcnn ,facenet 和svm的原理。
附上资源链接:
项目完整:https://pan.baidu.com/s/1rmRItADJdwvCQrC3TNPwRQ
提取码:gwto
GitHub地址:https://github.com/jiantenggei/face_recognization
提示:
本篇博文只是教大家搭建一个简单的人脸识别系统,并没有解决网络单次训练的问题。
单次训练就是说,训练完后,当新的人脸存入到数据库中,不许要重新训练网络,只需要少量的几张图片就可以准确识别。本文用的方法,当新的人脸进来是需要重新训练svm分类器。所以比较简单。
一、原理介绍
我们是站在巨人的肩膀上,完成自己的任务,mtcnn和facenet使用别人已经预训练好的网络模型,我们只训练svm。
1.mtcnn
mtcnn (Multi-task convolutional neural network,多任务卷积神经网络),将人脸区域检测和关键点检测放在了一起,检测的关键掉包括眼睛,鼻子,嘴角,五个关键点。
我们来看一下他的工作流程:
首先呢,将原图裁剪成不同的尺寸,再resize成12*12,再输入到P-Net中。
P-Net(Proposal Network)
P-Net的网络结构如上图所示,通过浅层的全卷积网络来获得Bounding-Box回归向量,并使用NMS(非极大值抑制)进行大部分窗口的过滤,
R-Net(Refine Network)
图片经过P-Net之后,会产生很多的预测窗口,将预测窗口全部送入到R-Net中,通过R-Net后,会消除掉质量很差的候选框,最后对剩下的候选框进行 Bounding-Box回归和NMS进一步优化预测结果。最后将输出较为可信的区域给O-Net。
O-Net (Output Network)
这一层会产生更细致的人脸信息,最后还回产生5个关键点landmark。
2. facenet
facenet 是谷歌提出的人脸算法,提出cnn+triplet loss mining的方法,在在LFW数据集上,准确率为0.9963,在YouTube Faces DB数据集上,准确率为0.9512。我们来看一下facenet的网络结构:
DEEP ARCHITECTURE 是一个卷积网络,它可以是Mobilenet或者是ResnetV1,主要作用就是用于特此区域 在通过L2正则化,再embeding成一个128维的向量,再用triplet loss计算损失。但再实际的训练中,还要引入一个优化器来帮助网络收敛。
facenet是将人脸特征映射到128维的特征空间中,然后通过计算欧式距离来判断分类。上图就是triplet loss的学习过程。
3. SVM(Support Vector Machine)
SVM 支持向量机,将facenet提取到的128维的特征向量,输入到支持向量机中进行训练,用支持向量机来做分类判断。那有人可能就要问了,为什么不在facenet后之间链接全连接层来做分类呢。因为这样的做的话,需要训练的参数会很多,如果你要去识别1w个人 那么参数就是128*1w。如果每个人只提供的图片不多。那么网络是很难训练的。对于支持向量机,则需要很少的训练数据,就可以达到一个还不错的效果。支持向量机是将低维线性不可分的向量,映射到高维可分。介绍玩原理,我们可以来看如何实现的了。
二、人脸识别实现
1.准备工作
引入mtcnn
下载链接:https://github.com/ipazc/mtcnn
将图中的文件夹下载后放入工程目录中。或者直接使用pip 安装:
pip install mtcnn
要求OpenCV>=4.1 Keras>=2.0.0
先面试测试mtcnn的一段代码:
from mtcnn import MTCNN
import cv2
test_img = cv2.imread("imgs/img.png")
detector = MTCNN()
result=detector.detect_faces(test_img)
print(result[0]['box'])
for item in result:
x,y,width,height = item['box'