基于 Python 和 Dlib 的人脸相似度对比实现
本文介绍了基于 Python 和 Dlib 库实现人脸相似度对比的技术方案。通过加载预训练的人脸关键点检测器和特征提取模型,将人脸图像转换为 128 维特征向量。利用欧几里得距离计算测试图片与训练集图片特征向量的差异,从而判断相似度。内容涵盖环境配置、代码实现细节、原理分析及性能优化建议,适用于基础人脸识别功能的开发参考。

本文介绍了基于 Python 和 Dlib 库实现人脸相似度对比的技术方案。通过加载预训练的人脸关键点检测器和特征提取模型,将人脸图像转换为 128 维特征向量。利用欧几里得距离计算测试图片与训练集图片特征向量的差异,从而判断相似度。内容涵盖环境配置、代码实现细节、原理分析及性能优化建议,适用于基础人脸识别功能的开发参考。

人脸识别是人工智能领域的重要应用之一。通过提取人脸的特征向量,我们可以计算两张图片中人脸的相似度。本文将介绍如何使用 Python 和 Dlib 库实现一个简易版的人脸相似度对比程序。
在开始之前,请确保已安装以下依赖:
Python 3.x:建议使用 3.6 及以上版本。
C++ 编译器:Dlib 需要编译,Windows 用户建议安装 Visual Studio Build Tools,Linux/Mac 用户需安装 g++ 或 clang。
第三方库:
pip install dlib opencv-python scikit-image numpy glob
模型文件:
shape_predictor_68_face_landmarks.dat:用于检测人脸关键点(眼睛、嘴巴等)。dlib_face_recognition_resnet_model_v1.dat:用于生成人脸特征值(128 维)。模型文件可从 Dlib 官方 GitHub 仓库下载,并放置于项目根目录。
首先使用 Haar 级联分类器或 HOG 特征结合线性 SVM 来定位图像中的人脸区域。随后利用形状预测器(Shape Predictor)检测出人脸上的 68 个关键点坐标。
Dlib 提供了一个预训练的 ResNet 网络,能够将人脸图像映射为一个 128 维的浮点数向量(Descriptor)。这个向量包含了人脸的独特特征信息。对于同一个人的不同照片,其生成的特征向量距离应该非常近;而对于不同的人,距离则较远。
通常使用欧几里得距离(L2 Norm)来衡量两个特征向量之间的差异。公式如下:
$$\text{Distance} = \sqrt{\sum_{i=1}^{128} (x_i - y_i)^2}$$
距离越小,表示两张图片中的人脸越相似。在实际应用中,一般认为距离小于 0.6 为同一人,大于 0.6 为不同人(阈值可根据具体场景调整)。
import os
import dlib
import glob
import numpy as np
from skimage import io
# 配置路径
predictor_path = "shape_predictor_68_face_landmarks.dat"
face_rec_model_path = "dlib_face_recognition_resnet_model_v1.dat"
faces_folder_path = 'train_images' # 训练集文件夹
def load_models():
"""加载 Dlib 模型"""
detector = dlib.get_frontal_face_detector()
sp = dlib.shape_predictor(predictor_path)
facerec = dlib.face_recognition_model_v1(face_rec_model_path)
return detector, sp, facerec
我们需要预先将已知人物的图片进行特征提取,并存入列表。这一步相当于让模型'记住'这些人的样子。
def extract_features(detector, sp, facerec, folder_path):
candidate = [] # 存放训练集人物名字
descriptors = [] # 存放训练集人物特征列表
if not os.path.exists(folder_path):
print(f"警告:文件夹 {folder_path} 不存在")
return candidate, descriptors
for f in glob.glob(os.path.join(folder_path, "*.jpg")):
print("正在处理:{}".format(f))
try:
img = io.imread(f)
# 获取文件名作为 ID
name = os.path.basename(f).split('.')[0]
candidate.append(name)
# 人脸检测
dets = detector(img, 1)
for k, d in enumerate(dets):
shape = sp(img, d)
# 提取特征
face_descriptor = facerec.compute_face_descriptor(img, shape)
v = np.array(face_descriptor)
descriptors.append(v)
except Exception as e:
print(f"处理图片 {f} 时出错:{e}")
print('识别训练完毕!')
return candidate, descriptors
输入一张新图片,计算其特征值,并与训练集中的所有特征值计算距离,返回最接近的结果。
def compare_faces(detector, sp, facerec, test_img_path, candidates, descriptors):
try:
img = io.imread(test_img_path)
dets = detector(img, 1)
except Exception as e:
print('输入路径有误或图片无法读取:', e)
return None
dist = []
for k, d in enumerate(dets):
shape = sp(img, d)
face_descriptor = facerec.compute_face_descriptor(img, shape)
d_test = np.array(face_descriptor)
# 计算与训练集中每个人的距离
for i, desc in enumerate(descriptors):
dist_ = np.linalg.norm(desc - d_test)
dist.append((candidates[i], dist_))
# 按距离排序,找出最相似的
dist.sort(key=lambda x: x[1])
print("--- 相似度分析结果 ---")
for name, distance in dist[:5]: # 打印前 5 个最相似的
print(f"{name}: {distance:.4f}")
return dist[0][0] if dist else None
if __name__ == "__main__":
# 1. 加载模型
detector, sp, facerec = load_models()
# 2. 提取训练集特征
candidates, descriptors = extract_features(detector, sp, facerec, faces_folder_path)
if len(candidates) > 0:
# 3. 测试对比
# 注意:实际使用时请替换为真实测试图片路径
test_path = r"test_images\test6.jpg"
result = compare_faces(detector, sp, facerec, test_path, candidates, descriptors)
if result:
print(f"识别到的人物最有可能是:{result}")
else:
print("未找到有效的训练数据")
运行上述代码后,程序会输出测试图片与训练集中每个人物的距离值。距离值越小,代表相似度越高。
例如,如果测试图片中的人物与训练集中的'黎明'距离最小(如 0.4),而与'刘亦菲'距离较大(如 0.9),则系统判定该图片更接近'黎明'。
需要注意的是,单张人脸检测可能受光照、角度影响。如果一张图片中包含多个人脸,代码中的循环会分别计算每个检测到的人脸与训练集的匹配度,最终取全局最优解。
如果报错 FileNotFoundError,请确认 .dat 文件是否在当前目录下。Dlib 官方提供了多个版本的模型,推荐使用 resnet 版本以获得更高的精度。
不同的应用场景对精度的要求不同。如果是门禁系统,建议设置更严格的阈值(如 < 0.5);如果是相册分类,可以适当放宽(如 < 0.7)。
Dlib 在 Windows 上编译较为复杂,建议使用 Docker 容器化部署或在 Linux 环境下运行,以减少环境配置问题。
本文详细介绍了使用 Python 和 Dlib 库实现人脸相似度对比的全过程。从环境搭建、模型加载、特征提取到距离计算,涵盖了核心逻辑与工程实践。通过本方案,可以快速构建基础的人脸识别功能,并为后续集成到更复杂的 AI 系统中打下基础。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online