Python人脸识别库DeepFace使用教程及源码解析

目录

一、DeepFace介绍

1、人脸库设计

2、DeepFace.find

3、DeepFace.verify

4、DeepFace.analyze

5、DeepFace.extract_faces

6、DeepFace.represent

7、DeepFace.stream

二、DeepFace二次开发

1、开发活体检测API

2、模型权重持久化

三、总结


一、DeepFace介绍

DeepFace是一个用于人脸识别和面部属性分析的 Python 库。它是建立在深度学习模型之上,提供了简单易用的接口,用于处理各种面部相关的任务,如验证两张脸是否属于同一人、识别面部表情、检测年龄和性别等。

安装方式:

pip install deepface

DeepFace提供了以下几种人脸识别相关的API:

DeepFace.find:用于人脸库检索

DeepFace.verify:用于两张人脸比较
DeepFace.analyze:用于人脸属性分析
DeepFace.extract_faces:用于人脸目标检测
DeepFace.represent:用于人脸特征提取
DeepFace.stream:用于人脸实时分析

1、人脸库设计

以下是本人设计的人脸库存储结构,在face_database目录下,每个子目录代表某一个人的人脸图片,可以存放正脸、侧脸等不同角度照片,其中info.json存储了该人物的所有信息,比如姓名、手机号、出生年月等等信息,子目录名称是基于唯一标识(例如手机号)通过md5生成的散列值。

work_space
├── face_database
│   ├──682f1d4d333c228f02199c86dd385528
│   │   ├──0000.jpg
│   │   ├──0001.jpg

│   │   ├──info.json
│   ├──992bd729860ab5603d3133bc7108991e
│   │   ├──0000.jpg

│   │   ├──info.json

2、DeepFace.find

DeepFace.find主要用于在一组人脸图像(可以是一个图像数据库)中查找与给定的一张人脸图像相似的人脸。例如,在一个拥有大量员工照片的公司数据库中,使用一张未知身份员工的近照通过DeepFace.find来找到该员工在数据库中的其他照片,进而确定该员工的身份。

DeepFace.find返回一个包含查找结果的list(List[pd.DataFrame]),其中每个元素是Pandas DataFrame类型,DataFrame的每一行都对应着一张在数据库中找到的相似人脸,包含人脸图像的相关信息(如图像路径等)以及和输入人脸的距离,该距离用于衡量找到的人脸与输入人脸的相似程度,距离越近表示越相似。

from deepface import DeepFace# 数据库图像路径列表
database_path = 'face_database'
query_image_path = "query_image.jpg"results = DeepFace.find(image_path,database_path,enforce_detection=False,)[0]for _, row in results.iterrows():print(f"找到的相似人脸路径:{row['identity']},距离:{row['distance']}")

DeepFace.find函数的代码逻辑在DeepFace包的路径下的“modules\recognition.py”文件中,首先对人脸库路径下缓存的pkl文件提取所有人脸图片的特征向量,这些特征包含了面部的轮廓、五官的形状和位置、皮肤纹理等细节信息:

然后通过representation.represent函数对输入图像query_image_path提取特征向量,与人脸库的所有特征向量逐一计算距离,通过阈值target_threshold筛选所有距离小于阈值的人脸库图片,注意最后输出结果是按照距离从小到大升序的,如果只想获取距离最近的结果则提取DataFrame的第一行即可。

3、DeepFace.verify

DeepFace.verify是DeepFace库中的一个函数,主要用于验证两张人脸图像是否属于同一个人。

DeepFace.verify的代码逻辑在“modules\verification.py”文件中,与DeepFace.find类似,也是通过representation.represent函数分别对输入的两张图片提取特征向量,然后通过相应的距离计算函数生成两张图片的距离,距离小于预设阈值,则判定为同一个人。

from deepface import DeepFace# 两张人脸图像的路径,这里假设是本地的图像文件
img1_path = "path/to/image1.jpg"
img2_path = "path/to/image2.jpg"result = deepface.verify(img1_path, img2_path, enforce_detection=False)
if result["verified"]:print("这两张脸属于同一个人。")
else:print("这两张脸不属于同一个人。")print("距离:", result.get("distance"))

返回的结果示例如下:

{'verified': True, 'distance': 0.5409709948424768, 'threshold': 0.68, 'model': 'VGG-Face','detector_backend': 'opencv', 'similarity_metric': 'cosine','facial_areas': {'img1': {'x': 0, 'y': 5, 'w': 182, 'h': 221, 'left_eye': (127, 82), 'right_eye': (40, 90)},'img2': {'x': 0, 'y': 0, 'w': 683, 'h': 755, 'left_eye': (493, 244), 'right_eye': (170, 266)}},'time': 1.49}

verified表明输入的两张人脸是否被判定为属于同一个人。

distance表示两张人脸特征向量之间的距离度量值。

threshold是判定两张人脸是否属于同一人的阈值。

model代表用于提取人脸特征的深度学习模型名称,可选:VGG-Face, Facenet, Facenet512, OpenFace, DeepFace, DeepID, Dlib, ArcFace, SFace and GhostFaceNet。

detector_backend表示用于检测图像中人脸位置的方法,可选:Options: 'opencv', 'retinaface', 'mtcnn', 'ssd', 'dlib', 'mediapipe', 'yolov8', 'centerface' or 'skip'。

similarity_metric指定用于计算两张人脸特征向量之间相似度的度量方法。

facial_areas包含了输入的两张人脸图像(分别标记为img1和img2)中人脸的位置信息以及眼睛的位置信息。

time表示整个过程所花费的时间。

4、DeepFace.analyze

DeepFace.analyze能够对输入的人脸图像进行多维度的分析,包括表情识别、年龄估计、性别识别、种族识别等。这在很多领域都有广泛的应用,例如在市场调研中,通过分析消费者的表情来判断对产品的喜好程度;在安防监控中,对人员的年龄、性别等信息进行初步判断。

表情、性别、种族的识别实际上是二分类或多分类任务,年龄识别则是一个回归任务。

from deepface import DeepFaceimg_path = "path/to/face_image.jpg"
analysis_result = DeepFace.analyze(img_path, enforce_detection=False)
print("表情:", analysis_result.get("dominant_emotion"))
print("年龄:", analysis_result.get("age"))
print("性别:", analysis_result.get("dominant_gender"))
print("种族:", analysis_result.get("dominant_race"))

返回的结果示例如下:

[{'emotion': {'angry': 0.7418791274356322, 'disgust': 5.340072880214408e-05, 'fear': 89.25175602744555, 'happy': 0.01589643601781866, 'sad': 0.0007775448929871182, 'surprise': 9.989639967062471, 'neutral': 1.7639903034977293e-06}, 'dominant_emotion': 'fear', 'region': {'x': 0, 'y': 5, 'w': 182, 'h': 221, 'left_eye': (127, 82), 'right_eye': (40, 90)}, 'face_confidence': 0.94, 'age': 28, 'gender': {'Woman': 0.02528490440454334, 'Man': 99.9747097492218}, 'dominant_gender': 'Man', 'race': {'asian': 79.76993322372437, 'indian': 2.4958742782473564, 'black': 0.7977190427482128, 'white': 7.959078252315521, 'middle eastern': 1.5946529805660248, 'latino hispanic': 7.382745295763016}, 'dominant_race': 'asian'}]

DeepFace.analyze的代码逻辑在“modules\demography.py”文件中,通过加载action对应的模型,再由predict方法对输入的np.ndarray类型图像进行推理。例如,表情识别的模型加载及推理代码在“modules\demography\Emotion.py”文件中,基于tensorflow或keras构建一个3层卷积+3层全连接层的模型,通过softmax函数进行7分类。

5、DeepFace.extract_faces

DeepFace.extract_faces主要用于在给定的图像中检测人脸的位置和提取人脸区域,能够帮助后续的人脸分析(如表情分析、身份验证等)准确地定位到人脸所在的区域。例如,在一张包含多个人的合影中,该函数可以找出每个人脸的具体位置和边界。

from deepface import DeepFaceimg_path = "path/to/face_image.jpg"
result = DeepFace.extract_faces(img_path)
print(result)

返回的结果示例如下:

[{'face': array([[[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.],
        ...,
        [0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]]]),

'facial_area': {'x': 0, 'y': 5, 'w': 182, 'h': 221, 'left_eye': (127, 82), 'right_eye': (40, 90)},

'confidence': 0.94}]

face为图像中人脸部分的np.ndarray。

facial_area为图像中人脸的矩形框位置及左右眼位置。

confidence为人脸目标检测的置信度。

DeepFace.extract_faces的代码逻辑在“modules\detection.py”文件中,包含图像预处理、人脸目标检测与处理等逻辑。

6、DeepFace.represent

DeepFace.represent主要用于提取人脸图像的特征表示,通过使用预训练的深度学习模型将人脸图像转换为一个高维的特征向量。这个特征向量可以表示人脸的独特特征,例如面部的轮廓、眼睛、鼻子、嘴巴等的位置和形状信息,以及更细微的面部纹理和结构信息。对于不同的深度学习模型,提取的特征向量维度和表达能力会有所不同。

from deepface import DeepFaceimg_path = "path/to/face_image.jpg"
result = DeepFace.represent(img_path)
print(result)

返回的结果示例如下:

[{'embedding': [0.0, 0.0, …… ,  0.0],

'facial_area': {'x': 0, 'y': 5, 'w': 182, 'h': 221, 'left_eye': (127, 82), 'right_eye': (40, 90)},

'face_confidence': 0.94}]


embedding为4096维的向量。

7、DeepFace.stream

DeepFace.stream主要用于实现实时的人脸识别功能,该函数可以处理视频流(例如来自电脑自带摄像头)中的人脸信息,并进行实时的人脸识别操作。能够持续地从视频源中读取帧,检测帧中的人脸,并将其与已知的人脸数据库进行比对。

from deepface import DeepFace# 使用 DeepFace.stream 进行实时人脸识别,使用笔记本自带摄像头
DeepFace.stream(db_path="face_database")

该函数不返回任何结果,但是运行该函数会打开一个窗口,显示笔记本摄像头的拍摄画面并进行实时分析,例如在人脸库中进行检索,分析年龄(25)、性别(Man)、表情识别(fear):

二、DeepFace二次开发

1、开发活体检测API

在DeepFace中,可以在verify、analyze、find、represent、stream、extract_faces设置anti_spoofing为True,即可对输入图像进行活体检测,使用的算法是MiniFASNet:

但有个问题是,DeepFace源码在anti_spoofing设为True、并且检测为假时,会抛出异常:

但我想在实际使用中不抛异常而是获得活体检测的分类结果和类别对应分数,再进行下一步的业务逻辑处理。

于是,我在DeepFace.py文件中新增了一个detect_spoofing函数:

在“modules\demography.py”文件中新增detect_spoofing函数:

然后调用DeepFace.detect_spoofing方法即可返回活体检测二分类的类别(True or False)以及分数。

2、模型权重持久化

由于DeepFace并未提供模型权重输入方式,而是通过输入的model_name每次运行时加载对应模型的权重,一个是会略微拖慢代码运行速度,另一个是如果我想加载自己训练的模型就只能去修改代码底层的模型路径了,有点不方便。

例如,DeepFace提供的目标检测模型有yolov8,但我想用我自己训练的yolov11。

于是我把加载模型的代码放到了外部逻辑里:

在DeepFace底层代码中逐层修改,添加model参数,并在对应的加载模型处进行修改,例如人脸分析DeepFace.analyze:

修改后,测得DeepFace.find、DeepFace.analyze等API运行速度平均加快6%,算是小幅增速。

三、总结

DeepFace是基于TensorFlow、Keras的人脸识别库,集成了多种人脸目标检测、人脸识别、人脸分析等算法,可通过修改model_name轻松切换不同模型,也可以使用自己训练的模型集成到DeepFace框架中,快速地搭建起一个小型的、具有一定准确率的人脸识别与分析应用。

DeepFace优化方向:可以从集成更多的图像预处理方法、提升神经网络提取人脸特征的能力、提升推理速度以便用于实时检测视频流。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/68009.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java多线程的面试面试题及答案解析

什么是进程?什么是线程?有什么区别? 进程是系统资源分配的基本单位,拥有独立的地址空间。线程是 CPU 调度和分派的基本单位,是比进程更小的独立执行的单位,共享所在进程的内存空间等资源。一个进程可以包含…

三分钟简单了解一些HTML的标签和语法_02

1.a标签演示 点击然后跳转 代码加入title 2.图片链接 3.锚点链接 点击就会跳转的当前位置 4.a标签小知识补充 该实例会跳转到顶,锚点链接则会跳转到相应的锚点 5. 结果:直接跳转到该页面的锚点处 6. 在 HTML 中&#xff0c;<tr>标签表示表格中的行&#xff08;TableRow&…

多选multiple下拉框el-select回显问题(只显示后端返回id)

首先保证v-model的值对应options数据源里面的id <el-form-item prop"subclass" label"分类" ><el-select v-model"formData.subclass" multiple placeholder"请选择" clearable :disabled"!!formData.id"><e…

2025年数学建模美赛:A题分析(1)Testing Time: The Constant Wear On Stairs

2025年数学建模美赛 A题分析&#xff08;1&#xff09;Testing Time: The Constant Wear On Stairs 2025年数学建模美赛 A题分析&#xff08;2&#xff09;楼梯磨损分析模型 2025年数学建模美赛 A题分析&#xff08;3&#xff09;楼梯使用方向偏好模型 2025年数学建模美赛 A题分…

Qt——引用第三方SDK lib库的使用方法

【系列专栏】:博主结合工作实践输出的,解决实际问题的专栏,朋友们看过来! 《项目案例分享》 《极客DIY开源分享》 《嵌入式通用开发实战》 《C++语言开发基础总结》 《从0到1学习嵌入式Linux开发》 《QT开发实战》 《Android开发实战》 《实用硬件方案设计》 《结构建模设…

Java 反射与动态代理:实践中的应用与陷阱

Java 反射与动态代理&#xff1a;实践中的应用与陷阱 在现代Java应用中&#xff0c;反射和动态代理提供了强大的灵活性&#xff0c;但它们也带来了性能和复杂度上的挑战。本文将深入探讨这些技术在实际项目中的应用&#xff0c;分析它们可能导致的陷阱&#xff0c;并提供详细的…

Linux(Centos 7.6)命令详解:wc

1.命令作用 打印文件的行数、单词数、字节数&#xff0c;如果指定了多个文件&#xff0c;还会打印以上三种数据的总和(Print newline, word, and byte counts for each FILE, and a total line if more than one FILE is specified) 2.命令语法 Usage: wc [OPTION]... [FIL…

skynet 源码阅读 -- 核心概念服务 skynet_context

本文从 Skynet 源码层面深入解读 服务&#xff08;Service&#xff09; 的创建流程。从最基础的概念出发&#xff0c;逐步深入 skynet_context_new 函数、相关数据结构&#xff08;skynet_context, skynet_module, message_queue 等&#xff09;&#xff0c;并通过流程图、结构…

超分辨率体积重建实现术前前列腺MRI和大病理切片组织病理学图像的3D配准

摘要: 磁共振成像(MRI)在前列腺癌诊断和治疗中的应用正在迅速增加。然而,在MRI上识别癌症的存在和范围仍然具有挑战性,导致即使是专家放射科医生在检测结果上也存在高度变异性。提高MRI上的癌症检测能力对于减少这种变异性并最大化MRI的临床效用至关重要。迄今为止,这种改…

TypeScript 基础使用和相关问题

tsconfig.json 配置文件 {"compilerOptions": {"target": "esnext","jsx": "preserve","jsxImportSource": "vue","lib": ["esnext", "dom"],"useDefineForClassF…

leetcode-分割等和子集

本题涉及到的是01背包问题&#xff0c;我将从两种解决背包问题的思路写出题解 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集&#xff0c;使得两个子集的元素和相等。 示例 1&#xff1a; 输入&#xff1a;nums [1,5,11,5] 输出&#…

企业级流程架构设计思路-基于价值链的流程架构

获取更多企业流程资料 纸上得来终觉浅&#xff0c;绝知此事要躬行 一.企业流程分级规则定义 1.流程分类分级的总体原则 2.完整的流程体系需要体现出流程的分类分级 03.通用的流程分级方法 04.流程分级的标准 二.企业流程架构设计原则 1.流程架构设计原则 流程框架是流程体…

利用 SoybeanAdmin 实现前后端分离的企业级管理系统

引言 随着前后端分离架构的普及&#xff0c;越来越多的企业级应用开始采用这种方式来开发。前后端分离不仅提升了开发效率&#xff0c;还让前端和后端开发可以并行进行&#xff0c;减少了相互之间的耦合度。SoybeanAdmin 是一款基于 Spring Boot 和 MyBatis-Plus 的后台管理系…

智能风控 数据分析 groupby、apply、reset_index组合拳

目录 groupby——分组 本例 apply——对每个分组应用一个函数 等价用法 reset_index——重置索引 使用前​编辑 注意事项 groupby必须配合聚合函数、 关于agglist 一些groupby试验 1. groupby对象之后。sum&#xff08;一个列名&#xff09; 2. groupby对象…

尚硅谷大数据数仓项目superset db upgrade报错解决(2025.1.23解决)

尚硅谷大数据数仓项目superset db upgrade报错解决&#xff08;2025.1.23解决&#xff09;和 superset安装MySQL报错解决 解决方法&#xff08;2025.1.23解决&#xff09; 0.卸载之前安装好的Superset -- 退出当前环境 conda deactivate-- 卸载Superset conda remove -n sup…

linux-mysql在centos7安装和基础配置

1.安装mysql数据库 1.使用官网安装 1.检查是否存在mysql的分支mariadb [rootlocalhost ~]# rpm -qa |grep mariadb mariadb-libs-5.5.64-1.el7.x86_64 [rootlocalhost ~]# 2.卸载这个分支包 [rootlocalhost ~]# rpm -qa | grep mariadb mariadb-libs-5.5.64-1.el7.x86_64 …

YOLOv5训练自己的数据及rknn部署

YOLOv5训练自己的数据及rknn部署 一、下载源码二、准备自己的数据集2.1 标注图像2.2 数据集结构 三、配置YOLOv5训练3.1 修改配置文件3.2 模型选择 四、训练五、测试六、部署6.1 pt转onnx6.2 onnx转rknn 七、常见错误7.1 训练过程中的错误7.1.1 cuda: out of memory7.1.2 train…

移动端VR处理器和传统显卡的不同

骁龙 XR 系列芯片 更多地依赖 AI 技术 来优化渲染过程&#xff0c;而传统的 GPU 渲染 则倾向于在低画质下运行以减少负载。这种设计是为了在有限的硬件资源下&#xff08;如移动端 XR 设备&#xff09;实现高性能和低功耗的平衡。以下是具体的分析&#xff1a; 1. AI 驱动的渲染…

IoTDB结合Mybatis使用示例(增删查改自定义sql等)

IoTDB时序库是当前越来越流行以及基于其优势各大厂商越来越易接受的国产开源时序数据库&#xff0c;针对IoTDB的内容不做过多介绍&#xff0c;在使用该时序库时&#xff0c;往往有一定入门门槛&#xff0c;不同于关系型数据库或文档型数据库那般方便维护和接入开发&#xff0c;…

Git 小白入门教程

&#x1f3af; 这篇文章详细介绍了版本控制的重要性&#xff0c;特别是通过Git实现的分布式版本控制相对于SVN集中式控制的优势。文章首先解释了版本控制的基本概念&#xff0c;强调了在文档或项目多版本迭代中备份与恢复任意版本的能力。接着&#xff0c;重点阐述了Git的历史背…