最近在做人脸识别黑盒攻击算法,首先要构建一个人脸识别算法,目前用的比较多的就是这几个了:FaceNet、CosFace、SphereFace、ArcFace,因为不是专门研究人脸识别,就想到有没有一种最简单的方式来做,精度和速度、简洁度都能达标的,自然没什么比opencv-python更合适的了。
安装opencv-python 4.5.4即可,非常简单
pip install opencv-python==4.5.4.58
实现: 人脸检测 + 对齐 + 提取特征 + 匹配
OpenCV4.5.4发布中包含了一个新的人脸识别算法支持,算法来自北邮邓伟洪教授团队贡献,SFace模型大小为37MB,属于轻量级的人脸识别模型,输出特征维度是128维。
参考了贾志刚老师的公众号文章:OpenCV4.5.4人脸识别详解与代码演示
该代码是用C++写的,改写成python略有不同,具体请参考下面的代码。
需要下载的文件:
检测模型: yunet.onnx
识别模型:face_recognizer_fast.onnx
下载地址请参考:https://download.csdn.net/download/qq_36563273/56347506
# -*- coding:utf-8 -*-
# 开发人员 : csu·攀-_-||
# 开发时间 : 2021/11/22 9:51
# 文件名称 : faceTest.py
# 开发工具 : PyCharm
# 功能描述 : OpenCV 4.5.4 人脸识别应用
import cv2
import time
# 定义输入和变量
img1 = cv2.imread('face_img/012.jpg')
img2 = cv2.imread('face_img/013.jpg')
new_shape = (300, 300) # 统一缩放为 300*300
cos_thresh = 0.363 # cos阈值,距离越大越接近
L2_thresh = 1.128 # L2阈值,距离越小越接近
img1 = cv2.resize(img1, new_shape)
img2 = cv2.resize(img2, new_shape)
start = time.time()
# 初始化模型:
faceDetector = cv2.FaceDetectorYN.create('face_model/yunet.onnx', '', new_shape)
faceRecognizer = cv2.FaceRecognizerSF.create('face_model/face_recognizer_fast.onnx', '')
# 检测、对齐、提取特征:
# detect输出的是一个二维元祖,其中第二维是一个二维数组: n*15,n为人脸数,
# 15为人脸的xywh和5个关键点(右眼瞳孔、左眼、鼻尖、右嘴角、左嘴角)的xy坐标及置信度
faces1 = faceDetector.detect(img1)
aligned_face1 = faceRecognizer.alignCrop(img1, faces1[1][0]) # 对齐后的图片
feature1 = faceRecognizer.feature(aligned_face1); # 128维特征
faces2 = faceDetector.detect(img2)
aligned_face2 = faceRecognizer.alignCrop(img2, faces2[1][0])
feature2 = faceRecognizer.feature(aligned_face2);
cv2.imwrite('face_img/aligned1.jpg',aligned_face1)
cv2.imwrite('face_img/aligned2.jpg',aligned_face2)
# 人脸匹配值打分:
cos_score = faceRecognizer.match(feature1, feature2, 0)
L2_score = faceRecognizer.match(feature1, feature2, 1)
# 输出结果:
print('cos_score: ', cos_score)
print('L2_score: ', L2_score)
if cos_score > cos_thresh:
print('the same face')
else:
print('the diffrent face')
if L2_score < L2_thresh:
print('the same face')
else:
print('the diffrent face')
end = time.time()
print('all last time:{:.2f} ms'.format(1000*(end - start)))
找了两组比较有难度的人脸来做实验,第一组为汤姆克鲁斯不同时期、表情和角度的照片,第二组为和汤姆克鲁斯比较相似的一名男星。从结果来看,SF人脸识别模型能够比较好的识别出来同一个人脸和不同人脸,效果还是不错的。
本文参考了贾志刚老师的介绍文章,将C++代码改写成了python,基于opencv-python 4.5.4搭建一个最简单但效果还不错的人脸识别系统,后续可以通过加入界面和人脸注册功能扩展成一个完整的程序。
由于水平有限,写得不到位的地方敬请批评指正,觉得有所帮助的不妨点个赞~~拥抱开源,共同成长