提示:本文旨在设计并实现一个人脸识别系统。基于YOLOv5+Arcface+Liveness Detection+PyQt5的人脸检测与识别系统
前言
本文旨在设计并实现一个人脸识别系统。最近在做一个人脸识别系统的项目,懒得敲代码想找个现成的,结果就是一言难尽。。。大部分的文章里只有检测部分,缺少识别部分。干脆自己写一个吧。
参考代码:
yolov5官方源码:https://github.com/ultralytics/yolov5
arcFace源码: https://github.com/ronghuaiyang/arcface-pytorch
silentFace静默活体检测:https://github.com/smisthzhu/Silent-Face-Anti-Spoofing
一、检测部分
人脸检测部分就用YOLOv5,因为懒得训练模型,找的现成的best.pt。作用就是从一张图中找出人脸区域,主要有以下几个步骤:
1.使用YOLOv5模型检测图像/视频中的人脸位置;
2.通过non_max_suppression函数进行非极大值抑制,筛选出最佳的人脸检测框;
3.将检测到的人脸区域从原图中裁剪出来;
4.将检测到的人脸resize到128×128大小,转换为灰度图像,进行水平翻转增强;
5.数据归一化处理。
二、识别部分
这部分包括几个方面:
1.检测到的人脸裁剪图传给识别网络,即Arcface,由Arcface提取人脸特征,然后对原始图像和水平翻转图像分别提取特征,将两个特征拼接起来形成最终的人脸特征表示;
2.计算待识别人脸特征与数据库中所有人脸特征的余弦相似度
通过阈值(0.44)判断是否为同一个人,输出最匹配的人名标签;
3.当开启open_rf选项时,使用AntiSpoofPredict模型进行活体检测,将人脸resize到80×80作为输入,判断人脸是真实的(real)还是伪造的(fake)。
三、识别部分
关键代码如下:
for *xyxy, conf, cls in det: # x1 y1 x2 y2 cls class
face_img = im0[int(xyxy[1]):int(xyxy[3]),int(xyxy[0]):int(xyxy[2])] # 裁剪侦测到的人脸部分
face_img = cv2.resize(face_img,(128, 128)) # 缩放至128*128
face_img = cv2.cvtColor(face_img,cv2.COLOR_BGR2GRAY)
face_img = np.dstack((face_img, np.fliplr(face_img)))
face_img = face_img.transpose((2, 0, 1))
face_img = face_img[:, np.newaxis, :, :]
face_img = face_img.astype(np.float32, copy=False)
face_img -= 127.5
face_img /= 127.5
face_data = torch.from_numpy(face_img)
face_data = face_data.to(torch.device("cuda"))
# 获取特征
_output = arcface_model(face_data)
_output = _output.data.cpu().numpy()
fe_1 = _output[0]
fe_2 = _output[1]
_feature = np.hstack((fe_1, fe_2))
# label = '%s %.2f' % (names[int(cls)], conf)
label = "none"
list = os.listdir(dir)
max_f = 0
t = 0
# 比较数据库中每一张图片的余弦相似度
for i, each in enumerate(list):
t = cosin_metric(features[each],_feature)
# print(each, t)
if t>max_f:
max_f = t
max_n = each
# print(max_n,max_f)
if (max_f>0.5):
label = max_n[:-4]
plot_one_box(xyxy, im0, label=label, color=colors[int(cls)], line_thickness=3)
四、系统界面
人脸识别的整个流程是:检测→裁剪→预处理→特征提取→特征比对→活体检测(可选)→结果显示。系统效果如下。