deepface是一个Python轻量级人脸识别和人脸属性分析(年龄、性别、情感和种族)框架,提供非常简单的接口就可以实现各种人脸识别算法的应用。deepface官方仓库为deepface。deepface提供了多种模型,模型下载地址为deepface_models

安装方式: pip install deepface -i https://pypi.tuna.tsinghua.edu.cn/simple

deepface主要提供以下人脸识别算法,具体对应接口为:

  • DeepFace.verify:人脸验证
  • DeepFace.find:人脸识别
  • DeepFace.analyze:人脸属性分析
  • DeepFace.detectFace:人脸检测
  • DeepFace.represent:人脸特征提取
  • DeepFace.stream:人脸实时分析

总体而言,这个项目的人脸识别模型识别效果还行,但是离工程应用还是有一定的距离,不过还是非常推荐学习该库内部代码。

某些网站会判定本文人脸图片违规,这是网站识别算法自身问题。

本文所有算法展示效果和代码见:

github: Python-Study-Notes

此外可以看一看另外一个人脸识别库,功能更加齐全:[深度学习] Python人脸识别库face_recognition使用教程

0 数据准备

# deep库的导入就一行代码
from deepface import DeepFace
import matplotlib.pyplot as plt
from PIL import Image, ImageDraw
import os
import cv2
import numpy as np

所使用的数据集为网络明星图片,共五个明星,每个明星三张人脸,数据集的路径如下:

root
├── images
│ ├── baijingting
│ │ ├── 0000.jpg
│ │ ├── 0001.jpg
│ ├── jiangwei
│ │ ├── 0000.jpg

├── code

数据展示结果如下:

# --- 展示图片
def show_img(imgs: list, img_names: list) -> None:
imgs_count = len(imgs)
for i in range(imgs_count):
ax = plt.subplot(1, imgs_count, i+1)
ax.imshow(imgs[i])
ax.set_title(img_names[i])
ax.set_xticks([])
ax.set_yticks([])
plt.tight_layout(h_pad=3)
plt.show() img_path = "images"
for person_dir in os.listdir(img_path):
imgs = []
img_names = []
for file in os.listdir(os.path.join(img_path, person_dir)):
imgs.append(Image.open(os.path.join(img_path, person_dir, file)))
img_names.append(person_dir + '/' + file)
show_img(imgs, img_names)

)

)

1 人脸验证DeepFace.verify

此函数用于验证图像对是同一个人还是不同的人。函数接口为:

verify(img1_path, img2_path = '', model_name = 'VGG-Face', distance_metric = 'cosine', model = None, enforce_detection = True, detector_backend = 'opencv', align = True, prog_bar = True, normalization = 'base')

输入参数介绍:

img1_path:传递的图像路径、numpy数组(BGR)或based64编码图像
model_name:模型名,支持VGG-Face, Facenet, OpenFace, DeepFace, DeepID, Dlib, ArcFace,Ensemble等
distance_metric:度量标准,支持cosine, euclidean, euclidean_l2
model:构建deepface模型。每次调用verify函数都会重新建立人脸识别模型。可以选择传递预构建的人脸识别模型。如DeepFace.build_model('VGG-Face')构建模型
enforce_detection:如果在图像中检测不到任何人脸,则验证函数将返回异常。将此设置为False将不会出现此异常
detector_backend:人脸识别算法后端,支持retinaface, mtcnn, opencv, ssd,dlib
align:是否人脸对齐
prog_bar:启用或禁用进度条
normalization:人脸归一化的方式

输出结果介绍:

如果img1_path是输入一张人脸就是返回一个字典,如果输入列表则返回一个字典列表。具体参数如下:
verified:是否同一个人
distance:人脸距离,越小越相似
max_threshold_to_verify:判断为同一个人的阈值
model: 所用模型
similarity_metric: 相似性度量标准

各识别模型的精度如下,LFW和YTF都是小型数据集。Human-beings表示人类识别精度。

Model LFW Score YTF Score
Facenet512 99.65% -
SFace 99.60% -
ArcFace 99.41% -
Dlib 99.38 % -
Facenet 99.20% -
VGG-Face 98.78% 97.40%
Human-beings 97.53% -
OpenFace 93.80% -
DeepID - 97.05%

demo1

# 模型名
models_name = ["VGG-Face", "Facenet", "Facenet512", "OpenFace",
"DeepFace", "DeepID", "ArcFace", "Dlib", "SFace", 'Ensemble'] model_name = models_name[5]
result = DeepFace.verify(img1_path="images/baijingting/0001.jpg",
img2_path="images/pengyuyan/0001.jpg",
model_name=model_name)
# 展示结果,两个人不是同一个人
print(result)
1/1 [==============================] - 0s 170ms/step
1/1 [==============================] - 0s 20ms/step
{'verified': False, 'distance': 0.0751386867894902, 'threshold': 0.015, 'model': 'DeepID', 'detector_backend': 'opencv', 'similarity_metric': 'cosine'}

demo2

models_name = ["VGG-Face", "Facenet", "Facenet512", "OpenFace",
"DeepFace", "DeepID", "ArcFace", "Dlib", "SFace", 'Ensemble']
# 提前加载模型,避免重复加载
model_name = models_name[1]
# 创建模型
model = DeepFace.build_model(model_name)
# 列表中每一个子项表示用于对比的图像
img_paths = [["images/baijingting/0000.jpg", "images/baijingting/0001.jpg"],
["images/baijingting/0000.jpg", "images/zhaoliying/0001.jpg"]]
# 度量标准
metrics = ["cosine", "euclidean", "euclidean_l2"] results = DeepFace.verify(img_paths,
model_name=model_name,
model=model,
distance_metric=metrics[2],
prog_bar=False)
# 展示结果
for result in results.items():
print(result)
1/1 [==============================] - 2s 2s/step
1/1 [==============================] - 0s 52ms/step
1/1 [==============================] - 0s 55ms/step
1/1 [==============================] - 0s 66ms/step
('pair_1', {'verified': True, 'distance': 0.6328494898310356, 'threshold': 0.8, 'model': 'Facenet', 'detector_backend': 'opencv', 'similarity_metric': 'euclidean_l2'})
('pair_2', {'verified': False, 'distance': 1.1700473293978308, 'threshold': 0.8, 'model': 'Facenet', 'detector_backend': 'opencv', 'similarity_metric': 'euclidean_l2'})

2 人脸识别DeepFace.find

此函数用于从数据集中检索当前人脸相似的图片。函数接口为:

find(img_path, db_path, model_name ='VGG-Face', distance_metric = 'cosine', model = None, enforce_detection = True, detector_backend = 'opencv', align = True, prog_bar = True, normalization = 'base', silent=False):

输入参数和verify差不多,主要多了人脸检索库路径地址:

db_path:检索库路径,
silent: 是否静默显示数据,

输出结果介绍:

一个包含相似图像的pandas dataframe数据体,包括图像路径和距离值,
models_name = ["VGG-Face", "Facenet", "Facenet512", "OpenFace",
"DeepFace", "DeepID", "ArcFace", "Dlib", "SFace", 'Ensemble'] # db_path是库文件地址
# 第一次会提取各个图像的特征,并保存到本地pkl文件以供下次直接调用
result = DeepFace.find(img_path="images/baijingting/0000.jpg",
db_path="images", model_name=models_name[1])
1/1 [==============================] - 0s 55ms/step
1/1 [==============================] - 0s 64ms/step
1/1 [==============================] - 0s 63ms/step
1/1 [==============================] - 0s 61ms/step
1/1 [==============================] - 0s 64ms/step
1/1 [==============================] - 0s 58ms/step
1/1 [==============================] - 0s 55ms/step
1/1 [==============================] - 0s 65ms/step
1/1 [==============================] - 0s 59ms/step
1/1 [==============================] - 0s 55ms/step
1/1 [==============================] - 0s 51ms/step
1/1 [==============================] - 0s 52ms/step
1/1 [==============================] - 0s 53ms/step
1/1 [==============================] - 0s 52ms/step
1/1 [==============================] - 0s 55ms/step
Representations stored in images / representations_facenet.pkl file. Please delete this file when you add new identities in your database.
1/1 [==============================] - 0s 56ms/step
find function lasts 3.254298448562622 seconds
# 展示结果,第一个是识别图像本身,后面两个是相似图片
print(result)
                      identity  Facenet_cosine
0 images\baijingting/0000.jpg -2.220446e-16
1 images\baijingting/0001.jpg 2.002492e-01
2 images\baijingting/0002.jpg 2.328966e-01

3 人脸属性分析DeepFace.analyze

此函数用于分析当前人脸的面部属性,包括年龄,性别,面部表情(包括愤怒、恐惧、正常、悲伤、厌恶、快乐和惊讶),种族(包括亚洲人、白人、中东人、印度人、拉丁裔和黑人)。函数接口为:

analyze(img_path, actions = ('emotion', 'age', 'gender', 'race') , models = None, enforce_detection = True, detector_backend = 'opencv', prog_bar = True)

输入参数和verify差不多,主要多了属性设置actions:

actions:识别属性,包括age, gender, emotion, race

输出结果介绍:

如果img_path是输入一张人脸就是返回一个字典,如果输入列表则返回一个字典列表。具体参数如下:
region:人脸坐标,wywh格式
age:年龄
gender:性别
dominant_emotion: 主导情绪,也就是情绪识别结果
emotion:各个情绪度量值,值越大表示越倾向
dominant_race:种族结果
race:各个种族度量值
# 输入检测图像,这里只识别情绪,因为其他模型实在太大了,下载下来要很久。
result = DeepFace.analyze(img_path = "images/jiangwen/0000.jpg", actions = ['emotion'])
print(result)
1/1 [==============================] - 0s 113ms/step
{'emotion': {'angry': 2.147514166495057e-06, 'disgust': 3.124029827739067e-14, 'fear': 1.990160924947304e-06, 'happy': 99.9697208404541, 'sad': 1.9864262412738753e-05, 'surprise': 0.01537421194370836, 'neutral': 0.014887277211528271}, 'dominant_emotion': 'happy', 'region': {'x': 198, 'y': 34, 'w': 185, 'h': 185}}

数据可视化看看结果

im = Image.open( "images/jiangwen/0000.jpg")
# 坐标位置
x,y,w,h = result['region']['x'],result['region']['y'],result['region']['w'],result['region']['h']
draw = ImageDraw.Draw(im)
# 画框
draw.rectangle((x,y,x+w,y+h), outline="red", width=3)
print("表情:{}".format(result["dominant_emotion"]))
show_img([im],["jiangwen"])
表情:happy

4 人脸检测DeepFace.detectFace

此函数用于检测人脸,如果图像中有多个人脸只会返回一个,函数接口为:

detectFace(img_path, target_size = (224, 224), detector_backend = 'opencv', enforce_detection = True, align = True)

输入参数和verify差不多,主要多了可以设置返回图像的尺寸的参数target_size,输出返回一张RGB的numpy数组图像

result = DeepFace.detectFace(img_path = "images/zhangziyi/0000.jpg",align = True)
print(result.shape)
show_img([result],["zhangziyi"])
(224, 224, 3)

# 不进行人脸对齐
result = DeepFace.detectFace(img_path = "images/zhangziyi/0000.jpg",align = False)
print(result.shape)
show_img([result],["zhangziyi"])
(224, 224, 3)

5 人脸特征提取DeepFace.represent

该函数用于将面部图像表示为特征向量,函数接口为:

represent(img_path, model_name = 'VGG-Face', model = None, enforce_detection = True, detector_backend = 'opencv', align = True, normalization = 'base')

输入参数和verify差不多。输出返回图像特征多维向量,特征向量的维度根据模型而变化。

models_name = ["VGG-Face", "Facenet", "Facenet512", "OpenFace",
"DeepFace", "DeepID", "ArcFace", "Dlib", "SFace", 'Ensemble'] result = DeepFace.represent(img_path="images/baijingting/0000.jpg", model_name=models_name[1])
print("特征维度为:{}".format(len(result)))
1/1 [==============================] - 0s 61ms/step
特征维度为:128

当然提取特征可以自己计算距离,设置阈值。示例如下。

# 计算l2距离
def l2_distance(input1: np.ndarray, input2: np.ndarray) -> float:
# 手动计算 np.sqrt(np.sum((result1- result2)**2))
return np.linalg.norm(input1-input2) # 计算l1距离
def l1_distance(input1: np.ndarray, input2: np.ndarray) -> float:
# 手动计算 np.sum(abs(input1-input2))
return np.linalg.norm(input1-input2, ord=1) # 计算余弦距离
def IP_distance(input1: np.ndarray, input2: np.ndarray) -> float:
return 1 - np.dot(input1, input2)/np.linalg.norm(input1)/np.linalg.norm(input2)
models_name = ["VGG-Face", "Facenet", "Facenet512", "OpenFace",
"DeepFace", "DeepID", "ArcFace", "Dlib", "SFace", 'Ensemble'] # 提前加载模型,避免重复加载
model_name = models_name[1]
# 创建模型
model = DeepFace.build_model(model_name) # res1和res3为同一个人
res1 = DeepFace.represent(
img_path="images/baijingting/0000.jpg", model_name=models_name[1], model=model)
res2 = DeepFace.represent(
img_path="images/zhangziyi/0000.jpg", model_name=models_name[1], model=model)
res3 = DeepFace.represent(
img_path="images/baijingting/0001.jpg", model_name=models_name[1], model=model) # 转换为numpy类型
res1 = np.array(res1)
res2 = np.array(res2)
res3 = np.array(res3) print("res1与res2的余弦距离为:{}".format(IP_distance(res1,res2)))
print("res1与res3的余弦距离为:{}".format(IP_distance(res1,res3)))
print("res1与res2的l2距离为:{}".format(l2_distance(res1,res2)))
print("res1与res3的l2距离为:{}".format(l2_distance(res1,res3)))
print("res1与res2的l1距离为:{}".format(l1_distance(res1,res2)))
print("res1与res3的l1距离为:{}".format(l1_distance(res1,res3)))
1/1 [==============================] - 0s 54ms/step
1/1 [==============================] - 0s 62ms/step
1/1 [==============================] - 0s 52ms/step
res1与res2的余弦距离为:0.6868675298615137
res1与res3的余弦距离为:0.2002492383897012
res1与res2的l2距离为:12.135816884638682
res1与res3的l2距离为:6.657409646028565
res1与res2的l1距离为:110.3180431430228
res1与res3的l1距离为:58.20380371063948

6 参考

[深度学习] Python人脸识别库Deepface使用教程的更多相关文章

  1. [深度学习] Python人脸识别库face_recognition使用教程

    Python人脸识别库face_recognition使用教程 face_recognition号称是世界上最简单的开源人脸识别库,可以通过Python或命令行识别和操作人脸.face_recogni ...

  2. 基于深度学习的人脸识别系统(Caffe+OpenCV+Dlib)【一】如何配置caffe属性表

    前言 基于深度学习的人脸识别系统,一共用到了5个开源库:OpenCV(计算机视觉库).Caffe(深度学习库).Dlib(机器学习库).libfacedetection(人脸检测库).cudnn(gp ...

  3. 基于深度学习的人脸识别系统(Caffe+OpenCV+Dlib)【三】VGG网络进行特征提取

    前言 基于深度学习的人脸识别系统,一共用到了5个开源库:OpenCV(计算机视觉库).Caffe(深度学习库).Dlib(机器学习库).libfacedetection(人脸检测库).cudnn(gp ...

  4. 基于深度学习的人脸识别系统(Caffe+OpenCV+Dlib)【二】人脸预处理

    前言 基于深度学习的人脸识别系统,一共用到了5个开源库:OpenCV(计算机视觉库).Caffe(深度学习库).Dlib(机器学习库).libfacedetection(人脸检测库).cudnn(gp ...

  5. 基于深度学习的人脸识别系统系列(Caffe+OpenCV+Dlib)——【四】使用CUBLAS加速计算人脸向量的余弦距离

    前言 基于深度学习的人脸识别系统,一共用到了5个开源库:OpenCV(计算机视觉库).Caffe(深度学习库).Dlib(机器学习库).libfacedetection(人脸检测库).cudnn(gp ...

  6. 基于深度学习的人脸识别系统Win10 环境安装与配置(python+opencv+tensorflow)

    一.需要下载的软件.环境及文件 (由于之前见识短浅,对Anaconda这个工具不了解,所以需要对安装过程做出改变:就是Python3.7.2的下载安装是可选的,因为Anaconda已经为我们解决Pyt ...

  7. Python的开源人脸识别库:离线识别率高达99.38%

    Python的开源人脸识别库:离线识别率高达99.38%   github源码:https://github.com/ageitgey/face_recognition#face-recognitio ...

  8. Python的开源人脸识别库:离线识别率高达99.38%(附源码)

    Python的开源人脸识别库:离线识别率高达99.38%(附源码) 转https://cloud.tencent.com/developer/article/1359073   11.11 智慧上云 ...

  9. [深度学习工具]·极简安装Dlib人脸识别库

    [深度学习工具]·极简安装Dlib人脸识别库 Dlib介绍 Dlib是一个现代化的C ++工具箱,其中包含用于在C ++中创建复杂软件以解决实际问题的机器学习算法和工具.它广泛应用于工业界和学术界,包 ...

随机推荐

  1. 关于click和onclick的区别

    click()和onclick()的区别: 1.onclick是绑定事件,告诉浏览器在鼠标点击时候要做什么 click本身是方法作用是触发onclick事件,只要执行了元素的click()方法,就会触 ...

  2. 齐博x2模型里边钩子的创建与使用

    在模型里边的钩子创建与使用方法跟在控制器里边的钩子创建及使用方法是有所区别的在模型里边创建的钩子,你可以理解为执行一个函数,是无法调用模型里边的类的方法及属性的.比如系统文件\application\ ...

  3. 使用 Windows Core Audio APs 进行 Loopback Recording 并生成 WAV 文件

    参考文档 COM Coding Practices Audio File Format Specifications Core Audio APIs Loopback Recording #inclu ...

  4. <四>1:全面掌握Const的用法

    const怎么理解? const修饰的变量不能够在作为左值!!初始化完成后,值不能被修改!! C 和C++中const 的区别? 在C程序中 test.c const int a; 只定义,不做初始化 ...

  5. 说说 Redis 事务

    更多技术文章,请关注我的个人博客 www.immaxfang.com 和小公众号 Max的学习札记. Redis 事务简介 Redis 只是提供了简单的事务功能.其本质是一组命令的集合,事务支持一次执 ...

  6. 十六、资源控制器之DaemonSet

    资源控制器之DaemonSet DaemonSet 确保全部(或者一些) Node上运行一个 Pod 的副本,当有 Node 加入集群时,也会为他们新增一个 Pod,当有 Node 从集群移除时,这些 ...

  7. SystemParametersInfo函数说明

    SystemParametersinfo 返回值:如果函数调用成功,返回值非零:如果函数调用失败,那么返回值为零.若想获取更多错误信息,请调用GetLastError函数. SystemParamet ...

  8. Java 19 新功能介绍

    点赞再看,动力无限. 微信搜「程序猿阿朗 」. 本文 Github.com/niumoo/JavaNotes 和 未读代码博客 已经收录,有很多知识点和系列文章. Java 19 在2022 年 9 ...

  9. 关于.Net和Java的看法-一个小实习生经历

    目录 背景 带着疑惑 生活中的迷茫 开始实训 实习 再看java 总结 背景 笔者是一个专科院校的一名普通学生,目前就职于某三线城市的WEB方面.Net开发实习生,在找实习期间和就业期间的一些看法,发 ...

  10. Codeforces Round #817 (Div. 4)

    CF传送门 因为洛谷题库未更新,所以给出的题面都是CF的. 现场打真是太卡了(梯子挂了,codeforc.es也崩了),所以五六分钟才打开题目 \(qwq\) A. Spell Check 萌萌题,把 ...