人脸分析技术已经成为计算机视觉领域最炙手可热的方向之一。无论是手机解锁、美颜相机,还是安防监控、虚拟社交,背后都离不开强大的人脸分析算法支持。在众多开源项目中,InsightFace 凭借其全面性和先进性,成为了该领域的一颗璀璨明珠。

1.项目概览:不只是一个人脸识别库
InsightFace是一个集2D和3D人脸分析于一体的开源工具箱,基于PyTorch和MXNet两大深度学习框架构建。它不仅提供了人脸识别功能,还涵盖了人脸检测、人脸对齐、活体检测等多个核心模块。
项目地址:https://github.com/deepinsight/insightface
该项目最引人注目的特点是其"全栈式"解决方案------从人脸检测到特征提取,再到最终的身份识别或属性分析,InsightFace提供了一整套工业级可用的算法实现。
2.发展历程:从学术研究到工业级工具
InsightFace的发展轨迹与深度学习在人脸领域的演进密不可分:
- 2018年:项目初具雏形,主要聚焦于人脸识别算法。团队发表了《ArcFace: Additive Angular Margin Loss for Deep Face Recognition》这一里程碑式论文,提出了ArcFace损失函数,大幅提升了人脸识别的准确性
- 2019-2020年:项目功能快速扩展,相继集成了RetinaFace人脸检测算法和SCRFD高效检测器。RetinaFace作为一种单阶段检测器,在准确性和速度上取得了完美平衡,被CVPR 2020接收。
- 2021年至今:项目进入成熟期,增加了3D人脸重建、人脸活体检测等前沿功能,并推出了跨平台的C++ SDK------InspireFace,满足了移动端和嵌入式设备的部署需求。
3.准备环境(Linux环境)
这里使用 conda创建虚拟环境:
shell
# 创建虚拟环境
conda create -n insightface python=3.10
conda activate insightface
# 添加国内加速
pip config set global.index-url https://mirrors.huaweicloud.com/repository/pypi/simple/
# 安装PyTorch,我的环境中安装有CUDA 12.4
pip install torch==2.6.0 torchvision==0.21.0 torchaudio==2.6.0 --index-url https://download.pytorch.org/whl/cu124
# 安装额外依赖
pip install opencv-python numpy scikit-learn onnxruntime
# 安装InsightFace
pip install insightface


验证安装:
shell
python
>>>import insightface
>>>print("InsightFace版本:", insightface.__version__)
InsightFace版本: 0.7.3
Ctrl+D退出python交互环境
4.Python项目结构
shell
insightface_demo/
├── models/ # 模型存储目录(自动创建)
│ ├── buffalo_l/ # buffalo_l模型文件
│ └── buffalo_s/ # buffalo_s模型文件
│ └── ...其他缓存文件
├── face_database/ # 人脸图片
│ ├── person1.jpg # 这张图上有6个人,会提取脸部特征值保存到 fack_database.pkl
│ ├── recognition.jpg # 这个图是用来做人脸对比验证的,就是要识别的人脸
│ └── ...
│ └── fack_database.pkl # 特征库序列化文件
├── extract_and_save_feature.py # 提取特征,并保存到特征库
├── recognition.py # 识别
VSCode远程打开项目,并切换 conda 环境:
shell
conda activate insightface

4.1 要提取特征的图片
网上搜索了一张图片,这张图片中三个人脸会全部提取到特征库

4.2 要识别的图片
接下来会对这张图片进行识别,看能否识别出来

5.加载并初始化模型
不管是提取特征,还是识别,都需要加载模型。所以写了一个函数:
python
from insightface.app import FaceAnalysis
import os
import cv2
import pickle
# 初始化 FaceAnalysis 模型
def init_model():
app = FaceAnalysis(name='buffalo_l',
providers=['CUDAExecutionProvider','CPUExecutionProvider'], # 优先使用GPU
allowed_modules=['detection', 'recognition'],
# 项目根目录作为模型目录,它会自动创建models文件夹
root='.',
) # 只加载检测和识别模块
app.prepare(ctx_id=0, det_thresh=0.5, det_size=(640, 640)) # ctx_id=-1 表示使用 CPU
print(f"模型初始化完成,模型文件路径 {os.path.abspath(app.model_dir)}")
return app
name='buffalo_l': 指定要使用的预训练模型名称为'buffalo_l'。InsightFace 提供了多种不同精度和速度的预训练模型,buffalo_l是其中一个常用的模型。providers=['CUDAExecutionProvider','CPUExecutionProvider']: 指定模型推理时使用的后端执行提供者(Execution Provider)。列表顺序决定了优先级:'CUDAExecutionProvider': 表示优先尝试使用 NVIDIA GPU (通过 CUDA) 进行计算,这通常速度更快。'CPUExecutionProvider': 如果 GPU 不可用或初始化失败,则回退到使用 CPU 进行计算。这种设置确保了代码在没有 GPU 的环境下也能运行。
allowed_modules=['detection', 'recognition']: 明确指定只加载和启用模型中的人脸检测 (detection) 和人脸识别 (recognition) 功能模块。如果模型包还包含其他模块(如属性分析、关键点检测等),它们将不会被加载,这样可以节省内存和启动时间。root='.': 设置模型文件下载和存储的根目录。这里的'.'代表当前工作目录(即脚本所在的目录)。注释提到它会自动创建models文件夹来存放下载的模型文件。app.prepare:对已创建的app实例进行最后的准备和配置,使其可以开始处理图像。ctx_id=0通常表示使用第一个可用的 GPU (对应 CUDA 的 device 0)。det_thresh=0.5: 设置人脸检测的置信度阈值为 0.5。这意味着只有当模型认为某个区域是人脸的概率大于等于 50% 时,才会将其作为一个检测结果输出。调整这个值可以平衡检出率和误报率:值越高,要求越严格,可能漏检但误报少;值越低,可能多检但误报也多。det_size=(640, 640): 设置输入到人脸检测模型的标准图像尺寸为 640x640 像素。在进行人脸检测之前,输入图像会被缩放到这个尺寸。较大的尺寸通常能提高小人脸的检测精度,但也增加了计算量。
6.提取特征向量并保存
这段代码会对输入的 image_path图片提取所有检测到的人脸特征向量,这些向量会保存到文件中,每个向量对应一个文件。
python
from insightface.app import FaceAnalysis
import os
import cv2
import pickle
# 提取人脸特征并保存
def extract_and_save_feature(app, image_path, save_path):
# 读取图像
img = cv2.imread(image_path)
if img is None:
print(f"无法读取图像: {image_path}")
return
# 检测人脸并提取特征
faces = app.get(img)
if len(faces) == 0:
print(f"在图像中未检测到人脸: {image_path}")
return
print(f"在图像中检测到 {len(faces)} 个人脸")
# 处理所有检测到的人脸
for i, face in enumerate(faces):
feature = face.normed_embedding
# 生成唯一的文件名
pkl_path = os.path.join(save_path, f"face_{i}.pkl")
with open(pkl_path, 'wb') as f:
pickle.dump(feature, f)
print(f"人脸 {i+1} 特征已保存到: {pkl_path}")
print(f"人脸位置: {face.bbox}")
app: 这是之前通过init_model()函数初始化好的FaceAnalysis模型实例。它包含了加载好的检测和识别模型。image_path: 字符串类型,表示要处理的原始图像文件的路径。save_path: 字符串类型,表示用于保存提取出的人脸特征向量文件(.pkl文件)的目标目录路径。cv2.imread(image_path): 调用 OpenCV 的imread函数尝试加载图像。如果成功,它会返回一个 NumPy 数组(通常是 BGR 格式)app.get(img): 这是FaceAnalysis类的核心方法。它接收图像数组img作为输入,在图像中查找所有人脸,对每个检测到的人脸进行对齐、归一化等预处理,并提取其特征向量(嵌入向量 embedding)。该方法返回一个包含所有检测到的人脸信息的列表(或类似结构),列表中的每个元素(如face)都包含了该人脸的边界框 (bbox)、特征向量 (embedding或normed_embedding) 等信息。feature = face.normed_embedding这是insightface库中Face对象的一个属性。它通常是一个经过 L2 归一化处理后的特征向量(NumPy 数组)。归一化有助于后续计算特征向量之间的距离(如余弦相似度)来进行人脸识别比较。
7.测试
下面对特征向量提取和人脸识别进行测试:
7.1特征向量提取
python
if __name__ == "__main__":
# 初始化模型
app = init_model()
source_path = 'face_database/person1.png'
database_path = 'face_database/pkl'
# 提取特征并保存
extract_and_save_feature(app,source_path,database_path)
输出:
latex
模型初始化完成,模型文件路径 /home/qy/insightface_demo/models/buffalo_l
在图像中检测到 3 个人脸
人脸 1 特征已保存到: face_database/pkl/face_0.pkl
人脸位置: [106.5861 138.86467 378.7415 496.2842 ]
人脸 2 特征已保存到: face_database/pkl/face_1.pkl
人脸位置: [670.03564 390.0709 939.014 739.1257 ]
人脸 3 特征已保存到: face_database/pkl/face_2.pkl
人脸位置: [319.9558 545.59515 591.38965 883.96356]
7.2 人脸识别
python
if __name__ == '__main__':
# 初始化模型
app = init_model()
compare_faces(app,"face_database/recognition.png","face_database/pkl")
输出:
latex
模型初始化完成,模型文件路径 /home/qy/insightface_demo/models/buffalo_l
在图像中检测到 1 张人脸
特征库中共有 3 张人脸特征
============================================================
处理人脸 1:
人脸位置: [339.06497 103.46757 658.17676 490.30322]
最佳匹配: face_2.pkl
最高相似度: 0.4947
判定结果: 匹配成功(相似度 > 0.4)
============================================================
8.总结
本节只是简单使用 InsightFace 实现一个人脸检测和识别 demo。这个 demo 提供了两个主要功能:提取人脸特征并保存,以及人脸比对。你可以根据自己的需求进一步扩展和优化这个 demo,例如添加 GUI 界面、支持批量处理、集成到其他应用中。
InsightFace 是一个功能强大的人脸分析工具包,除了人脸检测和识别外,还支持人脸属性分析、人脸关键点检测等功能。