介绍
facenet-pytorch库里面包含了两个重要功能:人脸检测和人脸识别,其中人脸检测部分使用mtcnn算法,人脸识别部分使用Facenet算法。利用这个库,可以轻松实现人脸检测和人脸向量映射操作。
依赖安装
pip install torch torchvision torchaudio -i https://pypi.mirrors.ustc.edu.cn/simple/
pip install facenet_pytorch -i https://pypi.mirrors.ustc.edu.cn/simple/
安装完成后
C:\Users\Administrator.cache\torch\checkpoints 路径将会生成
运行代码
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')
print(device)
# 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('1.jpg', mtcnn, resnet) # 已知人物图
# bFaceThin.png lyf2.jpg
faces_emb, img = load_known_faces('1.jpg', mtcnn, resnet) # 待检测人物图
isExistDst = match_faces(faces_emb, known_faces_emb, MatchThreshold) # 人脸匹配
print("设置的人脸特征向量匹配阈值为:", MatchThreshold)
if isExistDst:
boxes, prob, landmarks = mtcnn.detect(img, landmarks=True) # 返回人脸框,概率,5个人脸关键点
print('由于欧氏距离小于匹配阈值,故匹配')
else:
print('由于欧氏距离大于匹配阈值,故不匹配')
结果显示,两张图片中人脸的欧氏距离大于设定的匹配阈值,故不匹配,也就是说两张人脸不是同一个人。
这样的话,我们的代码就能实现简单的人脸识别啦!
下面对常用的方法进行一定的说明
- MTCNN类:创建MTCNN模型,用于人脸的检测
该类的常用初始化参数:
参数 | 意义 |
---|---|
image_size | 输出图像大小,默认160 |
margin | 添加到预测框的margin值,默认为0 |
min_face_size | 最小的搜索人脸的大小,默认为20 |
thresholds | 人脸检测阈值,默认为[0.6, 0.7, 0.7] |
factor | 用于创建图像金字塔的缩放因子,默认为0.709 |
post_process | 是否进行后处理,默认为True |
select_largest | 如果为True,返回检测到人脸中最大的,否则返回概率最大的,默认为True |
selection_method | 用何种方式选择人脸,和上面的参数有点类似,默认为None |
keep_all | 如果为True,所有检测到的人脸都返回,默认为False |
device | 指定设备信息,默认为None |
该类的常用方法:
方法 | 参数 | 作用 | 举例 |
---|---|---|---|
前向传播方法 | 图像、保存路径、是否返回概率值 | 基本的运行流程,但是返回人脸的数组 | mtcnn(img.path.True) |
detect | 图像、是否返回人脸关键点 | 与前向传播类似,但是返回预测框坐标和概率值 | mtcnn.detect(img,False) |
运行结果
F:\softs\python3.9.5\python.exe E:/pythonLearn/videoFaceRecongnition/人脸标记/test_face.py
cpu
人脸对应的特征向量为:
tensor([[ 2.6100e-02, 3.7316e-02, -5.3456e-02, -3.9613e-03, 4.5849e-02,
-2.9891e-02, -3.3390e-02, 1.7524e-02, 2.5169e-02, -3.8078e-03,
2.2210e-02, 1.1796e-02, 2.4897e-03, -4.4492e-02, 3.1836e-02,
4.2941e-02, 6.3914e-02, 8.9246e-02, 2.1192e-02, 7.9531e-02,
5.1919e-02, 2.6038e-02, 1.4765e-02, -3.4487e-02, 1.9160e-03,
-2.1372e-02, 8.1666e-02, -4.0598e-02, -2.2622e-03, 2.9139e-02,
1.7868e-02, 1.8562e-02, 5.0050e-03, 5.8584e-02, 2.7155e-02,
-5.5719e-02, -2.4750e-03, -4.1908e-02, 5.4327e-02, 2.1380e-02,
4.3770e-03, -1.0616e-01, -8.1742e-02, -2.4625e-02, -7.1361e-02,
3.9652e-02, -4.6673e-02, -8.1896e-03, -4.5516e-02, 6.9030e-02,
-1.9769e-02, -8.5650e-02, -4.5211e-02, -7.2584e-03, -3.3707e-02,
-6.4752e-02, 1.2951e-02, -3.9337e-02, 2.8350e-02, -2.5967e-02,
-3.7398e-02, 8.7172e-02, -2.9438e-02, 9.1939e-02, -2.8188e-02,
-7.2035e-02, -1.8008e-02, -8.1089e-02, 8.8959e-03, -5.1844e-02,
-1.9821e-02, -4.8104e-02, -5.3584e-02, 1.8220e-02, 1.7117e-02,
2.1732e-02, -4.8589e-02, -5.2602e-02, 1.9207e-02, -8.7093e-02,
6.2496e-02, -2.7798e-02, -1.6133e-02, -9.3462e-02, 1.4513e-02,
-3.3144e-02, 2.6529e-02, 2.9093e-02, -3.1128e-02, -4.1118e-02,
-7.4153e-02, -1.8401e-02, -9.5622e-03, -4.0357e-04, 3.7374e-02,
-7.1842e-03, -6.107