首页 > 编程语言 >Python deepface:让你的代码轻松地实现人脸识别功能

Python deepface:让你的代码轻松地实现人脸识别功能

时间:2024-08-12 14:16:40浏览次数:10  
标签:人脸识别 deepface Python cv2 人脸 result png DeepFace

楔子

在 GitHub 上面发现了一个非常有趣的库,叫 deepface,简直是人间宝藏。这个库主要是做人脸识别和面部属性分析的,它集合了目前全球最顶尖的开源人脸识别算法,使用卷积神经网络(CNN)对图像进行特征提取,以实现高精度的人脸识别。实验表明,人类在面部识别任务上的准确率为 97.53%,而这些模型已经达到并超过了该准确率水平。

而该库提供非常丰富的功能,比如:

  • 人脸检测:deepface 可以在图像中检测出人脸的位置,为后续的人脸识别任务提供基础。
  • 人脸对齐:为了提高识别准确性,deepface 会将检测到的人脸进行对齐操作,消除姿态、光照和表情等因素对识别结果的影响。
  • 特征提取:deepface 使用卷积神经网络(CNN)对齐后的人脸图像进行特征提取,将人脸转换为高维特征向量。
  • 人脸识别:通过比较特征向量之间的相似度,deepface 可以识别出图像中的人脸是否属于同一个人。
  • 人脸验证:deepface 可以用于人脸验证任务,即判断给定的两张人脸图像是否属于同一个人。
  • 人脸搜索:deepface 可以在大型人脸数据库中搜索特定人物,通过比较特征向量找到与目标人物最相似的人脸。
  • 人脸聚类:deepface 可以对人脸进行聚类分析,将相似的人脸分组在一起,以便进行进一步的分析和处理。
  • 人脸属性识别:deepface 还可以识别人脸的一些属性,如性别、年龄、表情等。年龄模型得到 ±4.65 MAE;性别模型可达 97.44% 的准确率、96.29% 的准确率和 95.05% 的召回率。
  • 人脸跟踪:deepface 可以在视频序列中跟踪人脸,实现实时的人脸识别和分析。
  • 人脸年龄分析:deepface 可以估计图像中的人脸年纪。
  • 人脸表情识别:deepface 可以估计图像中的人脸表情。
  • 人种识别:deepface 可以识别出图像中的人脸属于什么人种。
  • 性别分析:deepface 可以识别出图像中的人脸是什么性别。

下面我们就来实际测试一个该库,看看它的效果如何?不过使用之前需要安装,直接 pip install deepface 即可。在安装的时候,会安装一些依赖,比如 OpenCV-Python、Tensorflow 等等,这些库比较大,所以要保证网络通畅,否则耗时会比较长。

对比两张图片上的人脸是否是同一个人

假设我们有两张图片,想判断两张图片上人是否为同一人,要怎么做呢?

当前有两个文件,分别是 yui1.png 和 yui2.png,来验证一下它们是否为同一个人。

from pprint import pprint
# deep 库的所有功能都在 deep.DeepFace 子模块下面
from deepface import DeepFace

# 传入两张图片即可进行对比
result = DeepFace.verify("yui1.png", "yui2.png")
pprint(result)

现代人脸识别流程包括 5 个常见阶段:检测、对齐、归一化、表示和验证。deepface 会在后台处理好一切,我们不需要深入了解其背后的所有过程,只需要用一行代码即可调用它的验证、查找或分析函数。

然后是 DeepFace.verify 函数,它负责对两张图片上的人进行比对,判断是否为同一个人。该函数接收如下参数:

img1_path 和 img2_path:就是两张图片的路径,当然除了路径,还可以是 numpy 数组或 base64 字符串。verify 函数会将图像上的人脸部分表示为向量,然后计算相似度。如果其中一张图片出现了多张脸,比如 img1_path 里面有一张脸,但 img2_path 里面有三张脸,那么每一张脸都会进行比对,找到最相似的那一个。

model_name:deepface 已经集成了大量顶尖的人脸模型用于训练,比如:

"VGG-Face"、"OpenFace"、"Facenet"、"Facenet512"、"DeepFace"、"DeepID"
"Dlib"、"ArcFace"、"SFace"、"Emotion"、"Age"、"Gender"、"Race"

喜欢哪个就用哪个,但是模型需要下载,如果 deepface 检测到当前机器上没有指定的模型,那么会自动下载。所以当前第一次执行上面代码的时候,会下载 VGG-Face 模型(大小有好几百 M)。关于这些模型的区别,有兴趣可以自己了解一下,我们直接使用默认的即可。

detector_backend:检测器后端,负责提供人脸识别算法,因为 deepface 所使用的算法是由其它模块提供的,默认是 opencv。但除了 opencv 之外,还有其它选择。

"opencv", "retinaface", "mtcnn", "ssd", "dlib", "mediapipe"

这些人脸检测器之间的区别,还是很重要的,我们来解释一下。

  • "opencv":最轻量级的人脸检测器,使用不基于深度学习技术的 haar-cascade 算法,因此速度很快,但准确率较低。而为了使 OpenCV 正常工作,需要正面图像,如果脸侧了一下或者局部发生遮挡,准确率就会受到影响。此外也不擅长对眼睛的检测,容易导致对齐问题。目前 DeepFace 使用的默认检测器就是 OpenCV。
  • "dlib":该检测器在后台使用 hog 算法,与 OpenCV 类似,它也不是基于深度学习的,但它的检测和对齐分数相对较高。
  • "ssd":单次检测器,它是一种流行的基于深度学习的检测器,但性能可与 OpenCV 相媲美。只是 SSD 不支持面部特征点,并且依赖于 OpenCV 的眼睛检测模块来对齐,因此尽管其检测性能很高,但对准分数仅为平均水平。
  • "mtcnn":基于深度学习的人脸检测器,并带有面部特征点,所以它的检测和对齐得分都很高但是,但速度比 OpenCV,SSD 和 Dlib 慢。另外 MTCNN 是一种多任务级联卷积神经网络的人脸检测算法,能够同时实现人脸检测、关键点定位和人脸对齐等功能。其对于大尺寸人脸的检测效果较好,并且模型规模相对于 RetinaFace 的较小。
  • "retinaface":一种基于卷积神经网络的人脸检测算法,具有高精度的特点,被公认为是最先进的人脸检测算法,但需要很高的计算能力。相比 MTCNN,检测小尺寸人脸的效果更好。

因此如果你希望结果更加精确,那么使用 RetinaFace 或 MTCNN;如果希望检测速度更快,比如清洗一部分没有人脸的照片,那么可以使用 OpenCV 或 SSD。

distance_metric:距离(面部嵌入)度量方法,可以是 cosine、euclidean 或 euclidean_l2。

enforce_detection:如果没有检测到人脸时,是否引发异常,可以将其设置为 False。

align:是否执行面部对齐。

normalization:用于预处理图像的归一化技术。

from pprint import pprint
from deepface import DeepFace

result = DeepFace.verify("yui1.png", "yui2.png")
pprint(result)
"""
{'detector_backend': 'opencv',
 'distance': 0.2437701450344817,
 'facial_areas': {'img1': {'h': 115, 'w': 115, 'x': 73, 'y': 408},
                  'img2': {'h': 327, 'w': 327, 'x': 159, 'y': 38}},
 'model': 'VGG-Face',
 'similarity_metric': 'cosine',
 'threshold': 0.4,
 'time': 1.25,
 'verified': True}
"""

返回的是一个字典,里面有两个重要字段:

  • verified:表示比对结果,即两张图片上的人是否为同一人。
  • facial_areas:由矩形表示的面部区域,x、y 表示矩形的左上顶点的坐标,w 和 h 分别表示矩形的宽度和高度。

我们修改一下代码,将人脸所在的矩形描绘出来。

from deepface import DeepFace
import cv2

result = DeepFace.verify("yui1.png", "yui2.png",
                         detector_backend="mtcnn")

if not result["verified"]:
    print("人脸不一致")
    exit(0)

# 获取人脸位置坐标
rect_img1 = result["facial_areas"]["img1"]
rect_img2 = result["facial_areas"]["img2"]

# cv2 将图片读取进来之后,会得到一个三维数组
# 第一个维度表示图片的每一行,第二个维度表示图片的每一列,第三个维度就是图片的像素点
im1 = cv2.imread("yui1.png")
im2 = cv2.imread("yui2.png")
# 将人脸所在的矩形绘制出来,调用 cv2.rectangle 函数,该函数接收 5 个参数
# 分别是:原始图像、矩形的左上顶点、矩形的右下顶点、线条颜色、线条粗细
cv2.rectangle(
    im1, (rect_img1["x"], rect_img1["y"]),
    (rect_img1["x"] + rect_img1["w"], rect_img1["y"] + rect_img1["h"]),
    (0, 255, 0),  3
)
cv2.rectangle(
    im2, (rect_img2["x"], rect_img2["y"]),
    (rect_img2["x"] + rect_img2["w"], rect_img2["y"] + rect_img2["h"]),
    (255, 0, 0),  3
)
cv2.imshow("yui1.png", im1)
cv2.imshow("yui2.png", im2)
cv2.waitKey(0)

看一下结果:

你也可以将 detector_backend 换成别的,看看效果。首先换成 retinaface,结果也是正常的,但如果换成 opencv 结果就有问题了。换成 opencv 的话,也是提示人物是同一人,但第一张图片在返回面部所在矩形位置的时候出现了很大的问题,它返回的位置是人物手中的饮料所在的矩形区域。

这就有点离谱了,当然这只是我当前的结果是这样的,总之建议在识别的时候使用 MTCNN 和 Retinaface。

补充:图片的路径不能包含中文,或者说图片的路径必须是 ASCII 字符。

查找一张图片上的人脸所在的位置

现在有一张图片,如果让你绘制出人脸所在的矩形区域,要怎么做呢?

from deepface import DeepFace
import cv2

im = cv2.imread(r"nigehaji.png")

# 除了传递路径,也可以传一个 Numpy 数组
# 因为一张图片可能包含多张人脸,所以返回的是一个列表,列表的每个元素是字典
results = DeepFace.extract_faces(
    im,
    detector_backend="retinaface",
    enforce_detection=False)

# 每个字典里面有如下字段:
# face: 一个 Numpy 数组,对应人脸的部分,大小可以通过 extract_faces 里面的 target_size 指定
#       此外 extract_faces 里面还有一个 grayscale 参数,表示 face 对应的图像是否为灰度图(默认 False)
# facial_area: 脸部所在的矩形区域
# confidence: 准确率,有多大把握确定该位置是人脸
for result in results:
    facial_area = result["facial_area"]
    cv2.rectangle(
        im, (facial_area["x"], facial_area["y"]),
        (facial_area["x"] + facial_area["w"], facial_area["y"] + facial_area["h"]),
        (0, 255, 0),  1
    )

cv2.imshow("nigehaji.png", im)
cv2.waitKey(0)

图片上的人脸能否全部找出来呢?看一下结果。

功能还是比较强的,然后注意第一张图片,里面其实有 3 个人脸,我一开始都没看出来。

判断图片上的人脸是否在现有的数据集中

这也是一个比较常用的功能,比如你是一个公司老总,手下员工无数,但信息、照片都存储在你的系统中。但某天有个在逃犯人被摄像头排到了脸,警察问你这个人是不是你公司的员工,你要怎么做呢?很简单,直接拿这个犯人的照片和手下的员工的照片挨个进行比对即可。针对这个需求,你可以依次读取每个员工的图像,然后调用 DeepFace.verify 函数,但 deepface 提供了一个更简单的函数。

可以调用 DeepFace.find 函数,第一个参数就是图片,第二个参数是目录,里面包含了一系列的图片,会依次进行比对。然后里面的 silent 参数表示是否禁用一些日志记录和进度条,至于其它参数我们都说过了。

然后返回值是一个列表,列表元素是 pandas.DataFrame,里面包含如下字段:VGG-Face_cosine、identity(图片路径)、source_h、source_w、source_x、source_y。

需要注意的是,该函数执行完后,会在图片目录里面生成一个 pkl 文件。如果后续目录里面的图片发生了变化,那么需要先将 pkl 文件删除,然后才能执行,否则报错。

判断图片上人物的年龄、情绪等

deepface 还有一个很强的功能,就是它可以推测出人物的年龄、情绪以及人种等等。

from deepface import DeepFace
import cv2

im = cv2.imread(r"C:\Users\86185\Desktop\moon\nigehaji.png")

results = DeepFace.analyze(
    im,
    detector_backend="mtcnn",
    enforce_detection=False)

返回值是一个列表,列表里面是字典,每个字典对应一个人物的相关属性。

{ 'age': 28,  # 年龄
  'dominant_emotion': 'surprise',  # 表示人脸的主要情绪
  'dominant_gender': 'Woman',  # 人脸的主要性别
  'dominant_race': 'asian',  # 人脸的主要种族
  # 情绪有多种可能,所以 emotion 表示每种情绪的概率,而概率最高的会用 dominant_emotion 单独保存
  'emotion': {'angry': 0.005373688327381387,
              'disgust': 3.8977976402065906e-08,
              'fear': 20.51267772912979,
              'happy': 0.006043683970347047,
              'neutral': 4.0025247471930925e-05,
              'sad': 8.856896016595783e-06,
              'surprise': 79.47585582733154},
  # 每种性别的概率,概率最高会用 dominant_gender 单独保存
  'gender': {'Man': 2.714412286877632, 'Woman': 97.2855806350708},
  # 每个人种的概念,概率最高的会用 dominant_race 单独保存
  'race': {'asian': 63.200453710583076,
           'black': 0.10846455762324081,
           'indian': 0.21811715695960265,
           'latino hispanic': 3.3837137898036116,
           'middle eastern': 2.7975549726220947,
           'white': 30.291696208220493},
  # 位置
  'region': {'h': 47, 'w': 37, 'x': 143, 'y': 262}}

然后我们测试一下:

from deepface import DeepFace
import cv2

im = cv2.imread(r"nigehaji.png")
# 图片有点小,为了有显示文字的空间,这里放大两倍
# 从这里也能看出,即便图片放大了,对识别依旧没有什么影响
im = cv2.resize(im, (1280, 960))

results = DeepFace.analyze(
    im,
    detector_backend="mtcnn",
    enforce_detection=False)

for result in results:
    age = result["age"]
    emotion = result["dominant_emotion"]
    gender = result["dominant_gender"]
    race = result["dominant_race"]
    region = result["region"]

    # 绘制人脸矩形
    cv2.rectangle(
        im, (region["x"], region["y"]),
        (region["x"] + region["w"], region["y"] + region["h"]),
        (255, 0, 0), 1
    )
    # 绘制文字,该函数接收 9 个参数
    # 参数一: 原始图像;参数二: 绘制的文字内容;参数三: 在什么位置开始绘制
    # 参数四: 字体;参数五: 文字大小,等于字体的基础大小乘上传入的值,比如传入 1.5 表示放大 1.5 倍
    # 参数六: 文字颜色;参数七: 文字的线条粗细;
    # 参数八: 线条类型,可取值为 cv2.LINE_4、cv2.LINE_8 分别表示 8 邻接连接线、4 邻接连接线
    #        但是更推荐使用 cv2.LINE_AA,它是反锯齿连接线,背后采用了高斯滤波
    cv2.putText(im,
                f"age: {age}, emotion: {emotion}, gender: {gender}, race: {race}",
                (region["x"] - 135, region["y"]),
                cv2.FONT_HERSHEY_SIMPLEX,
                0.6,
                (161, 16, 203),
                1,
                cv2.LINE_AA)

cv2.imshow("...", im)
cv2.waitKey(0)

总的来说,识别效果还是不错的。然后 analyze 函数默认会分析年龄、性别、情绪、人种,如果你不想分析这么多,也可以通过参数指定。

def analyze(
    img_path,
    actions=("emotion", "age", "gender", "race"),
    enforce_detection=True,
    detector_backend="opencv",
    align=True,
    silent=False,
):

比如你只想分析年龄和情绪,那么就指定 actions 为 ("age", "emotion") 即可。

小结

以上就是该模块的用法,还是很有趣的。如果你对背后的原理感兴趣,那么可以尝试去了解一下。

标签:人脸识别,deepface,Python,cv2,人脸,result,png,DeepFace
From: https://www.cnblogs.com/wan-ming-zhu/p/18354858

相关文章

  • 【python学习】使用 jieba和 rank_bm25进行文本相似度计算
    介绍如何使用jieba分词库和rank_bm25库中的BM25Okapi算法来计算文本相似度。我们将通过一个简单的示例,展示如何实现这一过程。准备句子列表首先,我们准备一个包含多个句子的列表:sentences=["这是一个测试句子","温格高赢得了2023环法冠军","北京奥......
  • 亲测有效!!!python实现抖音直播间评论区最新评论爬取
    ``importtime#事件库,用于硬性等待importthreadingfrombs4importBeautifulSoupfromseleniumimportwebdriver#导入selenium的webdriver模块fromselenium.webdriver.chrome.serviceimportServicelive_dy_url='https://live.douyin.com/36947836004'#直播......
  • Loguru:Python 日志终极解决方案
    日志的重要性日志的作用非常重要,日志可以记录用户的操作、程序的异常,还可以为数据分析提供依据,日志的存在意义就是为了能够在程序在运行过程中记录错误,方便维护和调试,能够快速定位出错的地方,减少维护成本。每个程序员都应该知道,不是为了记录日志而记录日志,日志也不是随意记的。要......
  • 计算机毕业设计必看必学! ! 89344 springboot大学生就业管理系统,原创定制程序, java、
    摘 要信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以攻克的课题。针对大学生就业管理系统等问题,对大学生就业管理系统进行研究分析,然后开发设计出大学生就业管理......
  • 一文告诉你如何用 Python 对图片和视频进行高清修复
    估计大家应该在网上看过很多用AI修复的高清视频,最近我也有相关需求,需要修复几张图片。于是便去GitHub上寻找相关开源项目,结果还真找到一个,效果还很不错,这里特意分享出来给大家。首先将https://github.com/xinntao/Real-ESRGAN.git克隆下来,项目结构如下:然后我们要安装相关......
  • 使用 Python 操作 Stable Diffusion 进行 AI 绘图
    在几年前,AI领域对于普通人来说,还是无法触及的高岭之花。但随着chatGPT的爆火,AI变得越来越大众化,大量的工具让你可以在不具备任何前置知识的情况下使用AI,其中最火热的便是AI绘图了。相信很多人都知道Midjourney这个网站,只要输入相关的文字,便可通过网站背后的AI产出相对......
  • 简单的python web项目的docker-compose.yml 示例
    一个简单的pythonweb项目,包含redis,mysql,nginx,定时业务调度等其中web启动注册了自定义命令flaskcreate-db&&flaskinit-db&&uwsgi/web/uwsgi.iniversion:'3.5'services:db:image:mysqlcontainer_name:yeping_mysqlcommand:--default-......
  • Epson C4校准和Python通讯流程
    第一章简介1.1机器人型号EsonC41.2.目的使用EponC4机械臂,通过python进行指令控制,在通讯之前,进行了原点和工具坐标系的校准1.3.流程C4机械臂的机械原点校准C4机械臂的工具坐标系校准C4机械臂的通讯第二章机械原点校准2.1.原点校准-硬件操作2.1.1.原点校准......
  • python实现文字识别
    在Python中实现文字识别(OCR,OpticalCharacterRecognition)的一种流行方式是使用开源库如Tesseract。Tesseract是一个由HP实验室开发、后来由Google优化的OCR引擎,支持多种操作系统,并且能够识别多种语言的文本。步骤1:安装Tesseract首先,你需要在你的系统上安装Tesseract。......
  • CSP真题答案《202309-01、02》基于Python的实现
    注意:注释在测试CSP时应全部删除!!!第一题:#键盘输入两个数以空格隔开,分别为n,mn,m=map(int,input().split())#根据n值可以循环输入n行值,得到一个列表(操作数)madenum=[list(map(int,input().split()))for_inrange(n)]#根据m值可以循环输入m行值,得到一个列表(初始......