人脸识别-dlib
本文要做一个人脸比对功能,输入两张图片,输出是否同一人,用到了dlib模块。
dlib是一个可以做人脸检测和识别的第三方模块,官方给出预训练模型在亚洲人脸的识别率不是很理想,我们需要在自己的数据集上重新训练,提高准确率。
- 安装使用dlib模块
- 安装图片标注工具imglab
- 制作自己的数据集
- 训练人脸检测模型
- 人脸比对
- 人脸检测和比对源码下载
一、安装dlib模块
环境:win10,pip
1、下载“dlib-19.8.1-cp36-cp36m-win_amd64.whl”
百度云链接链接: https://pan.baidu.com/s/1yTQ_404E_CbQUF4KDxTIYA
提取码:orgh
2、打开命令行并进入到whl文件所在目录
运行pip install dlib-19.8.1-cp36-cp36m-win_amd64.whl
3、引入dlib模块
找到dlib安装路径,找到dlib.pyd文件,直接复制到项目里,就可以正常引用和调用里面的方法
二、安装图片标注工具imglab
1、编译imglab
官方提供了imglab工具用于制作人脸识别的数据集,遗憾的是官方提供的是源码,需要我们自己编译 。这里提供一个编译好的exe文件下载,能用可以直接跳到数据集制作部分。
链接: https://pan.baidu.com/s/1jNArBPkW0S4ifgP_pHbmnA
提取码:w2re
1)在github下载dlib的源码,进入到imglab所在目录,可以看到源码,需要我们自己编译。
在imglab下新建build文件夹。
2)安装vs2019
https://visualstudio.microsoft.com/zh-hans/vs/visualstudio.microsoft.com
3)安装cmake
安装好后打开cmake-gui.exe
Configure配置完成后,cmake显示如下信息,此时点击【Generate】按钮,生成exe文件
打开build文件夹,可以发现生成了imglab.exe文件
三、制作自己的数据集
1)新建文件夹images并添加图片
2)复制imglab.exe到images文件夹下
3)打开命令行,进入到images文件夹下,输入imglab -c mydataset.xml ./,按回车,在当前目录生成mydataset.xml文件。
4)命令行输入imglab mydataset.xml,按回车,打开imglab程序窗口。
5)如果想要训练的模型检测出来的人脸可以提取出人脸特征,供后面的人脸识别对接,那么标记图片的时候需要按照特定方式来标记,标记方式有两种,一种是68个特征点的标记方式,另一种是5个特征点的标记方式,特征标记顺序如下图:
注意,特征点的顺序必须如下图所示,顺序不能错,不然可以正常训练,但是训练出来的模型提取不了特征向量。
68个特征点位置
5个特征点位置
步骤:
- 按住ctrl+加鼠标滚轮,调整图片人脸是合适大小
- 松开ctrl,按住shift键,框出人脸位置,刚画出来的框是红色
- 松开shift,双击框的线条选中框,选中的框颜色变蓝
- 按住shift,按照标记点位置画出人脸标记
标记完成的图片如下:
四、训练人脸检测模型
官方预训练的模型对亚洲人脸的识别度不好,所以如果你有自己的数据集,可以训练自己的模型来改善这个问题。
人脸识别需要两个模型,一个是人脸检测模型,一个是人脸特征提取模型。官方的说法是:人脸特征提取模型是使用几百万张图片训练出来的,如果你有几千张图片,训练的模型不会对准确率有太大提高,所以应该训练人脸检测模型,提高在特定数据集上的准确度。
- 将images文件夹复制到项目里
- 运行train_shape_predictor.py 文件,传入参数./images。
- 训练完成,生成模型文件【predictor.dat】,进行测试,结果如下:
五、人脸比对
实现功能:输入两张图片,判断是否同一人。
人脸比对使用了两个预训练的模型:
- 人脸检测:shape_predictor_68_face_landmarks.dat
- 特征点提取:dlib_face_recognition_resnet_model_v1.dat
其中的人脸检测模型可以换成我们自己训练的模型predictor.dat
from skimage import io
import numpy as np
import dlib
def getVector(picPath):
print("Processing file: {}".format(picPath))
detector = dlib.get_frontal_face_detector()
model1_path = 'shape_predictor_68_face_landmarks.dat'
model2_path = 'dlib_face_recognition_resnet_model_v1.dat'
sp = dlib.shape_predictor(model1_path)
facerec = dlib.face_recognition_model_v1(model2_path)
img = io.imread(picPath)
dets = detector(img, 1)
print("Number of faces detected: {}".format(len(dets)))
for k, d in enumerate(dets):
shape = sp(img, d)
face_descriptor = facerec.compute_face_descriptor(img, shape)
return np.array(face_descriptor,dtype=float)
def comparePic(pic1,pic2):
vector1 = getVector(pic1)
vector2 = getVector(pic2)
op1 = np.sqrt(np.sum(np.square(vector1 - vector2)))
print("欧氏距离:{}".format(op1))
return op1
if __name__ == '__main__':
score = comparePic('images/Aaron_Eckhart_0001.jpg','images/Aaron_Guiel_0001.jpg')
if score < 0.6:
print('同一人')
else:
print('不是一个人')
六、人脸检测和比对源码下载
链接: https://pan.baidu.com/s/1X0gBamWDz8cEjm_h1QwmKQ
提取码:y7uy
编辑于 2020-03-13
smj-sunny: 原文链接:https://zhuanlan.zhihu.com/p/683612528
weixin_44607996: 希望得到作者大大的回复,谢谢~
weixin_44607996: 您好,这篇文章对我帮助很大,后期可能会引用,所以我想知道这是哪篇文章里面的?
怎样才能回到过去: 你是真抽象啊,直接照搬别人的内容还打原创
白露灬欺霜: 讲的太好了哥,请问可以发布在github上不?还有计算的公式都是乱码,实在不行截个图?