新书速览|PyTorch深度学习与企业级项目实战-优快云博客
一套基本的人脸识别系统主要包含三部分:检测器、识别器和分类器,流程架构如图11-3所示:
图11-5
检测器负责检测图片中的人脸,再将检测出来的人脸感兴趣区域(Region of Interests,ROI)导入识别器中,识别器输出结果为一组特征向量。再通过分类器对特征向量进行分类匹配,最终得出人脸结果。
识别器采用FaceNet,一个有一定历史的源自谷歌的人脸识别系统,如图11-6所示:
图11-6
FaceNet只负责提取128维的人脸特征向量,通过对比输入人脸向量与数据库中人脸向量的欧式距离来确定人脸的相似性。通常可以通过实验拟定合适的距离阈值直接判断出人脸类别。谷歌人脸识别算法发表于CVPR 2015,利用相同人脸在不同角度等姿态的照片下有高内聚性,不同人脸有低耦合性,在LFW数据集上准确度达到99.63%。
通过神经网络将人脸映射到欧式空间的特征向量上,实质上不同图片的人脸特征距离较大,而通过相同个体的人脸距离总是小于不同个体的人脸。测试时只需要计算人脸特征,然后计算距离,使用阈值即可判定两幅人脸照片是否属于相同的个体。人脸识别的关键在于如何通过神经网络生成一个“好”的特征。特征的“好”体现在两点:(1)同一个人的人脸特征要尽可能相似;(2)不同人的人脸之间的特征要尽可能不同。
本项目使用FaceNet进行识别,执行pip install facenet-pytorch命令即可安装并使用它。项目代码如下:
############face_demo.py#############################
import cv2
import torch
from facenet_pytorch import MTCNN, InceptionResnetV1
# 获得人脸特征向量
def load_known_faces(dstImgPath, mtcnn, resnet):
aligned = []
knownImg = cv2.imread(dstImgPath) # 读取图片
face = mtcnn(knownImg) # 使用mtcnn检测人脸,返回人脸数组
if face is not None:
aligned.append(face[0])
aligned = torch.stack(aligned).to(device)
with torch.no_grad():
known_faces_emb = resnet(aligned).detach().cpu()
# 使用ResNet模型获取人脸对应的特征向量
print("\n人脸对应的特征向量为:\n", known_faces_emb)
return known_faces_emb, knownImg
# 计算人脸特征向量间的欧氏距离,设置阈值,判断是否为同一张人脸
def match_faces(faces_emb, known_faces_emb, threshold):
isExistDst = False
distance = (known_faces_emb[0] - faces_emb[0]).norm().item()
print("\n两张人脸的欧式距离为:%.2f" % distance)
if (distance < threshold):
isExistDst = True
return isExistDst
if __name__ == '__main__':
# help(MTCNN)
# help(InceptionResnetV1)
# 获取设备
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
# mtcnn模型加载设置网络参数,进行人脸检测
mtcnn = MTCNN(min_face_size=12, thresholds=[0.2, 0.2, 0.3],
keep_all=True, device=device)
# InceptionResnetV1模型加载用于获取人脸特征向量
resnet = InceptionResnetV1(pretrained='vggface2').eval().to(device)
MatchThreshold = 0.8 # 人脸特征向量匹配阈值设置
known_faces_emb, _ = load_known_faces('zc1.jpg', mtcnn, resnet) # 已知人物图
faces_emb, img = load_known_faces('zc2.jpg', mtcnn, resnet) # 待检测人物图
isExistDst = match_faces(faces_emb, known_faces_emb, MatchThreshold) # 人脸匹配
print("设置的人脸特征向量匹配阈值为:", MatchThreshold)
if isExistDst:
boxes, prob, landmarks = mtcnn.detect(img, landmarks=True)
print('由于欧氏距离小于匹配阈值,故匹配')
else:
print('由于欧氏距离大于匹配阈值,故不匹配')
第一次运行时系统需要下载预训练的VGGFace模型,时间会比较久,耐心等待,下载好之后程序便可以运行。# InceptionResnetV1提供了两个预训练模型,分别在VGGFace数据集和CASIA数据集上训练。如果不手动下载预训练模型,可能速度会很慢,可以从作者提供的源代码文件链接中下载,然后放到C:\Users\你的用户名\.cache\torch\checkpoints这个文件夹下面,如图11-7所示。
图11-7
代码运行结果如下:
人脸对应的特征向量为:
tensor([[ 3.4712e-03, -3.3803e-02, -7.4551e-02, 7.5545e-02, 7.5004e-02,
7.5054e-03, -1.1760e-02, 1.3724e-

最低0.47元/天 解锁文章
1952

被折叠的 条评论
为什么被折叠?



