基于 Dlib + PyQt5 的人脸识别考勤系统 v2.0

基于 Dlib + PyQt5 的人脸识别考勤系统 v2.0

本文介绍一个基于 Dlib 深度学习模型与 PyQt5 图形界面框架构建的人脸识别考勤系统。系统集成了人脸检测、特征提取、身份识别、人脸录入与数据库管理三大核心功能,支持图片、视频和实时摄像头三种输入方式,并提供直观的可视化操作界面。


一、项目概述

1.1 系统功能

本系统围绕人脸识别的完整流程,设计了三大功能模块:

功能模块 说明
识别 对图片/视频/摄像头画面中的人脸进行实时检测与身份匹配,记录识别结果
录入 通过摄像头或本地图片采集人脸,提取 128 维特征向量并写入特征库
管理 查看已录入人脸信息,支持更新特征库与删除人脸数据

1.2 技术栈

  • 编程语言:Python
  • GUI 框架:PyQt5
  • 人脸检测:Dlib(HOG + 68 关键点定位)
  • 特征提取:Dlib ResNet(128 维人脸描述子)
  • 图像处理:OpenCV、PIL
  • 数据存储:CSV 文件(features_all.csv)

二、系统架构

2.1 核心类与数据流

系统主类 Face_MainWindow 继承自 UI 类 Ui_MainWindow,通过信号与槽机制将界面操作与底层逻辑连接。核心数据流如下:

输入源(图片/视频/摄像头)
    ↓
Dlib 人脸检测器 → 获取人脸 ROI 区域
    ↓
68 关键点预测器 → 定位面部特征点
    ↓
ResNet 模型 → 计算 128 维特征向量
    ↓
欧氏距离匹配 → 与特征库比对(阈值 0.4)
    ↓
输出识别结果 → 更新界面显示与记录表格

2.2 关键模型文件

模型文件 用途
shape_predictor_68_face_landmarks.dat 68 点面部关键点预测
dlib_face_recognition_resnet_model_v1.dat 128 维人脸特征提取

三、功能模块详解

3.1 识别模块

识别模块是系统的核心,支持三种输入方式:本地图片、视频文件和实时摄像头。

工作流程

  1. 选择输入源:用户通过"选择图片"、"选择视频"或"打开摄像头"按钮指定输入
  2. 启动识别:点击"开始识别"按钮,系统加载特征库并开始处理
  3. 实时检测:通过 QTimer 定时器以 30ms 间隔逐帧处理画面
  4. 特征匹配:计算当前人脸与数据库中所有人脸的欧氏距离,取最小值进行匹配
  5. 结果展示:在画面上绘制红色矩形框并标注姓名,右侧显示人脸个数、识别距离和当前人脸缩略图
  6. 记录保存:识别结果自动写入下方表格,包含序号、画面标识、人脸姓名、时间和距离

核心代码逻辑

# 计算欧氏距离进行匹配
for i in range(len(self.face_feature_exist)):
    e_distance_tmp = self.euclidean_distance(
        self.current_face_feature[k],
        self.face_feature_exist[i])
    self.current_face_distance.append(e_distance_tmp)

min_dis = min(self.current_face_distance)
if min_dis < 0.4:  # 阈值判断
    self.current_face_name[k] = self.face_name_exist[similar_person_num]

多目标跟踪:当画面中出现多张人脸时,系统采用质心跟踪算法(Centroid Tracker),通过计算前后帧人脸质心距离来维持身份一致性,避免频繁重分类。

界面效果

在这里插入图片描述

如图所示,系统成功识别出画面中的人脸为"李钟硕",红色矩形框标注了人脸位置,识别距离为 0.26(低于 0.4 阈值,匹配成功)。右侧实时显示人脸个数和当前人脸缩略图,下方表格记录每次识别的详细信息。


3.2 录入模块

录入模块用于将新人脸添加到特征数据库中,流程分为三步:新建文件夹 → 取图保存 → 录入特征。

工作流程

  1. 输入人脸名称:在文本框中输入待录入人员的姓名
  2. 新建文件夹:点击"新建文件夹"按钮,在 data/database_faces/ 下创建以人名命名的文件夹
  3. 采集人脸:通过摄像头实时画面或选择本地图片,系统自动检测人脸区域
  4. 取图保存:点击"取图保存"按钮,将检测到的人脸裁剪并保存到对应文件夹
  5. 录入特征:点击"录入人脸特征"按钮,遍历所有已保存照片,提取 128 维特征并计算均值,写入 features_all.csv

核心代码逻辑

# 特征录入:遍历所有照片,提取特征并求均值
for person in person_list:
    features_list = []
    photos_list = os.listdir(self.path_face_dir + "/" + person)
    for photo in photos_list:
        features_128D = self.extract_features(
            self.path_face_dir + "/" + person + "/" + photo)
        features_list.append(features_128D)
    features_mean = np.array(features_list).mean(axis=0)
    writer.writerow([person] + list(features_mean))

界面效果

在这里插入图片描述

如图所示,用户在文本框中输入"朴信惠"后新建了人脸文件夹,通过选择图片检测到人脸区域,点击"取图保存"将人脸裁剪保存,最后点击"录入人脸特征"完成特征写入。右侧面板实时显示新建状态和录入状态。


3.3 管理模块

管理模块提供对已录入人脸数据的查看、更新和删除操作。

功能说明

  • 查看数据库:以表格形式展示所有已录入人脸的序号、存储路径、姓名和修改时间
  • 更新特征库:点击"更新"按钮,重新遍历人脸文件夹,重新提取特征并刷新 features_all.csv
  • 删除人脸:在表格中选中目标行,点击"删除"按钮,删除对应文件夹并重新生成特征库

核心代码逻辑

# 删除人脸数据
def delete_doing(self):
    row, col = self.col_row
    r_path = self.tableWidget_mana.item(row, 1).text()
    if os.path.exists(r_path):
        shutil.rmtree(r_path)  # 删除文件夹
        # 重新生成特征库
        with open("./data/features_all.csv", "w", newline="") as csvfile:
            writer = csv.writer(csvfile)
            for person in person_list:
                # 重新提取特征...

界面效果

在这里插入图片描述

如图所示,管理界面顶部显示现有人脸数量(2 人)、修改时间和当前状态。表格中列出了"李钟硕"和"朴信惠"两条人脸记录,包含存储路径和录入时间。用户可通过"更新"按钮刷新特征库,或选中记录后点击"删除"按钮移除人脸数据。


四、关键技术点

4.1 人脸特征提取

系统使用 Dlib 的 ResNet 模型将人脸映射为 128 维特征向量。该模型在大规模人脸数据集上训练,能够将同一人的不同照片映射到特征空间中相近的位置,不同人的照片则相距较远。

def extract_features(self, path_img):
    img_rd = self.cv_imread(path_img)
    faces = self.detector(img_rd, 1)
    if len(faces) != 0:
        shape = self.predictor(img_rd, faces[0])
        face_descriptor = self.face_reco_model.compute_face_descriptor(img_rd, shape)
    else:
        face_descriptor = 0
    return face_descriptor

4.2 欧氏距离匹配

识别时通过计算欧氏距离衡量两张人脸的相似度:

$$d = \sqrt{\sum_{i=1}^{128}(f_{1i} - f_{2i})^2}$$

系统设定阈值为 0.4,距离小于该值则判定为同一人。

4.3 质心跟踪算法

当画面中同时出现多张人脸时,系统采用质心跟踪算法维持身份一致性:

  1. 计算当前帧每个人脸区域的质心坐标
  2. 与上一帧的质心坐标计算距离
  3. 将距离最小的上一帧身份分配给当前人脸
  4. 每隔 20 帧重新进行特征匹配,修正可能的跟踪漂移

4.4 中文字体渲染

由于 OpenCV 的 putText 不支持中文,系统通过 PIL 的 ImageDraw 配合自定义字体 platech.ttf 实现中文标注:

def drawRectBox(self, image, rect, addText):
    cv2.rectangle(image, rect, (0, 0, 255), 2)  # 绘制红色矩形框
    img = Image.fromarray(image)
    draw = ImageDraw.Draw(img)
    draw.text((rect[0]+1, rect[1]-16), addText, (255,255,255), font=self.fontC)
    return np.array(img)

五、项目结构

FaceRecUI/
├── runMain.py                    # 程序入口
├── FaceRecognition.py            # 核心逻辑(主窗口类)
├── FaceRecognition_UI.py         # PyQt5 界面代码
├── FaceRecognition_UI.ui         # Qt Designer 界面文件
├── image1.qrc / image1_rc.py     # 资源文件
├── Font/
│   └── platech.ttf               # 中文字体
── data/
│   ├── data_dlib/                # Dlib 模型文件
│   ├── database_faces/           # 人脸照片数据库
│   └── features_all.csv          # 人脸特征库
├── images_test/                  # 界面图标资源
└── test_img/                     # 测试图片

六、运行环境

依赖安装

pip install PyQt5 opencv-python dlib numpy pandas Pillow

启动方式

python runMain.py

注意事项

  • 首次运行需确保 data/data_dlib/ 目录下存在 Dlib 模型文件
  • 摄像头功能需要电脑连接可用摄像头设备
  • 特征库文件 features_all.csv 在首次录入人脸后自动生成
  • 中文字体文件 platech.ttf 需放置在 Font/ 目录下

七、总结

本项目实现了一个功能完整的人脸识别考勤系统,具备以下特点:

  • 多输入源支持:图片、视频、实时摄像头三种模式自由切换
  • 实时性能:基于 QTimer 的定时刷新机制,实现流畅的实时识别
  • 多目标跟踪:质心跟踪算法保证多人场景下的身份稳定性
  • 可视化管理:录入、识别、管理三大模块界面清晰,操作简便
  • 数据持久化:CSV 文件存储特征数据,便于迁移和备份

系统可进一步扩展的方向包括:引入更深度的神经网络模型提升识别精度、添加考勤统计与导出功能、支持云端人脸数据库同步等。


项目源码基于 Python + Dlib + PyQt5 开发,界面截图展示了识别、录入、管理三大功能模块的实际运行效果。

代码下载路径

有训练代码和训练好的模型以及训练过程,提供数据,提供GUI界面代码
项目完整文件下载请见演示与介绍视频的简介处给出:➷➷➷
https://www.bilibili.com/video/BV1AoHk6DErD/
在这里插入图片描述

导航