面向佩戴口罩的人脸识别系统

1 系统原型设计

本系统原型设计采用 Axure 完成,后续根据系统实际情况进行更改。主界面计划 设计六个按钮,点击按钮调用不同的子页面。最后一个按钮用于退出程序,点击按钮 就可以退出当前程序。 人脸识别页面的原型设计思路是,当摄像头捕获到目标区域时,将目标区域展示 在右侧方框中,并在下方显示识别的各种信息。按钮分别用来选择摄像头和打开摄像 头。原型设计如图 。

1.1人脸识别界面原型设计

人脸录入的设计思路是,用户首先输入用户名和工号,然后选择摄像头,再打开摄像头,分别点击右下方的录入按钮,将捕获的目标区域显示在右上角的方框中,提 取特征后存入数据库。原型设计如图

1.2人脸录入界面原型设计

信息管理界面的设计思路是,点击搜索按钮,查询已录入的所有人脸图像信息并展示在列表区域。点击批量导入图片按钮导入按指定格式命名的图片,点击批量导入 员工数据按钮,导入 excel 表格。点击新增按钮,新增单条记录。原型设计如图

1.3 信息管理界面原型设计

通信记录界面设计思路是,点击搜索按钮,展示所有已识别人脸信息的学号、姓名、通行时间和照片。支持条件查询,原型设计如图

1.4 通行记录界面原型设计

2 关键技术介绍

2.1 人脸识别技术选择

本系统在搭建 PySide2 界面之前,采用多种人脸检测技术进行测试,主要介绍 OpenCV Dlib YOLOv5 、目标追踪四种技术,以及他们之间的综合使用。
2.1.1 OpenCV
OpenCV 是一个跨平台计算机视觉和机器学习软件库,可以运行在 Linux Windows Android Mac OS 操作系统上,轻量级而且高效,实现了图像处理和计 算机视觉方面的很多通用算法。本系统开始设计时采用 OpenCV 进行人脸识别 OpenCV 有自己训练好的库,调用 OpenCV haarcascade_frontalface_default.xml 文件, 可以检测人脸。但是经过实际验证,识别效果较差,部分人脸无法识别。 在人脸是否佩戴口罩的检测中,采用 OpenCV 自训练软件来训练戴口罩的人脸检 测模型来进行佩戴口罩的人脸检测。首先获取带口罩的图片以及未戴口罩的人脸图片 3000 张,把戴口罩的照片看作正样本,未戴口罩的图片看作负样本,正负样本比 例为 1:3 。由于 OpenCV 不太准确,而且噪音样本影响非常大,因此将正负样本分别 采用人脸识别器进行分类 [10] 并获取人脸位置,将图片灰度化处理后进行剪裁。由于 OpenCV 的误识别,需要手工删除剪裁完后的图片中非人脸的图片。将修正完的正样 本采用 OpenCV 自带的 opencv_createsamples.exe 进行训练,这是 OpenCV 自带的一 个工具,封装了 haar 特征 [11] 提取 LBP HOG 特征分类器。但是新版本的 OpenCV 中找不到这个工具,需要在以往的版本中重新下载或者降低 OpenCV 版本。训练过程 中出现了很多次中断,最终以 6 个小时左右的时长训练完毕。将训练完后的结果放入 程序进行调试,发现结果比较差,很多非人脸区域也被识别了,因此放弃这种做法。
2.1.2 Dlib
Dlib 是一个机器学习的开源工具包,用于机器人、嵌入式设备、移动电话和大 性能计算环境。由于原生的 Python 不支持安装 Dlib whl, 因此需要先下载 Dlib 安装 包,然后再安装。 Dlib 基于 HOG Histogram of Oriented Gradients 实现人脸检测,利 Dlib get_frontal_face_detector (正向人脸检测器)进行人脸检测,提取人脸外部 矩形框,利用训练好的 shape_predictor 人脸 68 点特征检测器,进行人脸面部轮廓特 征提取 Dlib 库识别人脸比 OpenCV 更为精确,但是在测试时发现不能检测到佩戴口 罩的人脸。前期为了检测佩戴口罩的人脸区域,采用 OpenCV 来识别人脸区域,返回 人脸坐标,并转化为 Dlib 类型的坐标。但是这样做就会导致无法识别人脸是否佩戴 口罩,处理比较麻烦,而且精确度不高。所以后期改用 YOLO 算法进行目标检测。
2.1.3 YOLOv5
YOLO 算法是目前比较火的目标检测算法,可以用于做安全帽检测、车牌识别 等,效果都是挺好的。目前 YOLO 算法已经发展到 YOLOv5 系列。 YOLOv5 的整体 模型和 YOLOv4 相比差别小,主要特点是灵活度比 YOLOv4 更高。 YOLOv4 典型 结构是 cspdarknet53+panet+spp+yyolov3head 。整个 YOLOv5 简单来讲就是通过应用 类似 EfficientNet channel layer 控制因子来灵活配置不同复杂度的模型,并且在 正负样本定义阶段采用了跨领域的网络匹配策略,从而得到更多的正样本 anchor ,加 速收敛。本系统采用最新的 YOLOv5 算法,进行人脸检测。 首先选取佩戴口罩的人脸照片和不佩戴口罩的人脸照片共 2000 张,采用 labelimg 标注工具进行人脸佩戴口罩和不配戴口罩区域标记。标记完会生成 txt 文件,将 txt 文件转化为 YOLO 算法可以识别的 xml 文件。然后将生成的结果按 8:2 划分为训练集 和测试集。修改 YOLOv5 源代码中关键部分进行训练,训练时长大约 12 小时。训练 完后用 YOLOv5 原生代码进行测试,可以看到测试结果不错。最后将测试代码封装 成一个 detect 函数,函数返回识别结果、识别概率和人脸区域坐标位置。在人脸识别 算法中调用封装好的代码替换 Dlib 原有的人脸目标区域检测算法。 detect 函数返回人脸坐标为 (x,y,w,h) ,与 OpenCV 返回结果类型相同,而 Dlib 识别人脸坐标为 (x 1 ,y 1 ,x 2 ,y 2 ) 因此需要将 detect 返回结果进行处理。将处理后的结果传入 Dlib 人脸 landmark 特征 点 检 测 器 shape_predictor 进 行 人 脸 68 个 特 征 点 标 记 , 标 记 完 后 用 face_recognition_model_v1 提取人脸 128 维的特征矢量,进行人脸对比。
2.1.4 目标追踪算法
由于对于当前帧进行人脸检测需要约 0.03s ,对于检测出的人脸,提取特征描述子需要约 0.158s ,对于当前帧中的所有人脸,都要和已知人脸数据库进行遍历对比, 需要约 0.003s ,整个过程需要约 0.19s ,再加上设备性能的原因会造成很大的卡顿, 基本看不到流畅性,帧率在 5 左右。为了解决这个问题采用目标追踪算法 [14] 进行优化。 目标追踪算法 [15] 的步骤 : 首先对于初始帧,通过检测算法,获得一系列目标的坐 标位置;然后对目标创建 ID ;在视频流中的后续帧,寻找帧之间目标对象的关系, 将帧之间的目标关联起来。 目标追踪可以让我们对于每一个追踪的目标指定一个唯一的 ID, 所以我们可以对 视频中的跟踪物体进行计数,应用于计算人数的场景质心追踪算法 Centriod Tracking, 依赖于在视频流的连续帧中,比较已知目标与新出现目标之间质心的欧式距离。整体 的处理逻辑流程如下,希望能够只在第一帧 / 初始帧进行检测识别,并试图将第 N+1 帧中的目标,与第 N 帧的目标关联起来,这样对于后续帧,不再需要进行识别,只 需要进行检测就可以得到目标的 ID 了。
1 )对于某一帧找到特征框并计算质心,得到质心坐标( x,y )。
2 )计算新旧目标特征框质心的欧式距离 对于视频流中的后续帧,我们利用 检测算法来计算特征框,但是我们不会再去给每一个检测到的物体添加新的 ID 或者 标记什么的(只做检测,不做识别),而是希望将新的目标能够和旧目标联系起来。
3 )更新已知目标的质心坐标。质心追踪算法的前提是:对于一个给定目标, 将会在连续几帧中都出现,而且在第 N 帧和 N+1 帧中的质心欧氏距离,要小于不 同目标之间的欧式距离;因此我们在视频流的连续帧之间,根据欧氏距离最小原则, 将这些帧中特征框的质心联系起来,可以得到一个目标 X 在这些连续帧中的变化联 系,就达到了我们目标追踪的目的。
4 )注册新目标 当新增一个目标时候,可以给这个新目标一个目标 ID, 然后储存这个目标特征框的质心位置,从步骤 2 开始,对于视频流中的每一帧进行计算欧式 距离,并更新坐标
5 )注销旧目标 一个目标在后续帧中可能会消失,对于消失的目标,注销旧目标。

3系统设计与实现

3.1 功能模块设计

由需求分析可知,面向移动测温的人脸识别系统主要由以下模块构成:登录注册、人脸识别、人脸录入、信息管理和通行记录。其结构图如图
3.1.1 登录注册模块设计与流程
由需求分析可知,登录注册模块主要是为使用本系统的管理员服务。管理员可以 使用已有的账号密码进行登录,登录成功后进入主页。输入用户名或密码错误,点击 登录按钮后弹框提示“用户名 / 密码错误“”。输入用户名或密码为空,点击登录按钮 后弹框提示“用户名 / 密码为空,请重新输入”。输入用户名不合法,会提示“用户名 输入不合法,请重新输入“”。如果用户名 / 密码首尾存在空格,会去除空格后再进行 判断。
如果用户没有账号,点击注册按钮进行注册。如果注册时输入的账号不合法,提示“请输入合法账号”。如果设置密码不符合规则,提示“密码必须包含字母、数字 和特殊字符”。如果注册时输入的用户名或者密码或者确认密码为空,弹框提示 用户 / 密码不能为空 。如果输入密码和确认密码不一致,弹框提示 两次输入密码不一 。如果该账号已存在,弹框提示 该账号已存在,请重新注册 。注册成功弹框提 恭喜您注册成功 ,然后进入主界面。流程如图 所示。
3.1.2 人脸识别模块设计与流程
管理员登录成功后,首先选择摄像头编号, 0 位内置摄像头,其他是外置摄像头选择完后点击选择摄像头按钮,然后点击开始识别按钮,进行人脸识别。如果未选择 摄像头,则开始识别按钮无法点击。该设置防止用户误操作。识别成功展示各种识别 信息,如姓名、是否佩戴口罩、当前人脸数、帧率。姓名默认展示为 unknow ,当识 别的人脸在数据库中存在时,则更新姓名为识别结果。如果目标检测结果不佩戴口罩, 展示为 xxx-nomask 。如果目标检测结果为佩戴口罩,展示为 xxx-mask 。识别结束后 点击结束识别按钮停止人脸识别,此时开始识别按钮置为禁用。人脸识别流程如图 所示。
3.1.3 信息录入模块设计与流程
点击信息录入按钮进入信息录入页面,首先选择摄像头,根据 log 框提示信息点击开始录入按钮打开摄像头,分别点击录入佩戴口罩人脸图片按钮和录入不佩戴口罩 人脸图片按钮,录入人脸信息,录入完毕关闭摄像头。操作按钮必须按顺序点击,否 则按钮处于禁用状态。点击录入佩戴口罩人脸图片按钮或者录入不佩戴口罩人脸图片 按钮时,如果未输入相关信息或者相关信息输入不合法,会弹窗提示重新输入。输入 和操作都合法后,录入的人脸图像会显示在右上角的信息图片区域。后台处理人脸数 据存入数据库。信息录入模块流程如图 所示。
3.1.4 人员管理模块设计与流程
该模块点击查询按钮展示所有已录入员工信息员工的员工号、姓名、佩戴口罩照片和不佩戴口罩照片。选择某一行,点击删除按钮,删除该条记录。点击批量导入图 片按钮,选择存放按指定格式命名的文件夹,批量导入图片。点击批量导入 excel 格按钮,选择存放员工号的姓名的 excel ,导入数据。点击新增按钮,弹出新增窗口, 按要求输入各种信息,点击确认,开始新增。
3.1.5 记录管理模块设计与流程
该模块点击查询按钮查询所有通行记录,展示识别结果、通行时间、截取的人脸图片。可以输入指定人员的姓名,然后点击查询按钮,根据姓名查询指定人员的通行 记录。

3.2 数据库设计

面向移动测温的人脸识别系统只有两类用户,登录系统的用户和扫脸用户。因此不存在身份权限问题。管理员用户只需在使用该系统时进行登录,然后开始其他操作。 扫脸用户需要提前将人脸图片和相关信息提交给管理员,管理员再将相关信息录入人 脸数据库,扫脸用户在扫脸时候就可以识别人脸了,可以选择佩戴口罩或者不佩戴口 罩识别。数据表主要包括管理员表、员工表、人脸信息表、图片路径表和通行记录表, 表名依次为: administrator user feature pic record
1 )管理员表,主要用于存储使用系统的管理员的登录账号和密码。如表 所示。
administrator
2 )员工表,主要用于记录已经录入系统的相关人员的学号和姓名信息。如表所示。
 user
3 )人脸信息表,主要用记录已经录入系统的人脸的 128D 人脸特征,包括佩戴口罩的人脸特征,不佩戴口罩的人脸特征,以及二者的镜像文件的特征。如表 所示。
feature

4 )图片路径表,用于存储已录入人脸图片的存储位置,用于后期展示图片或者删除。如表 所示。
pic
5 )通行记录表,主要用于记录识别的人脸通行记录。如表 所示。
record

3.3 系统的实现

3.3.1 系统架构
1 )前端设计
本系统采用 PySide2 进行前端界面设计和美化。 PySide2 是一个 Python 模块,提供对 Qt5 框架的访问。与 PyQt 相比, PySide2 是开源的,使用不受限制,与 Qt C++ 相比, PySide2 可以大大减少代码量。基于以上有点, PySide2 适合团队规模不大, 项目需要快速推进,需要开发精美界面的场合。同时采用 Qt Designer 工具进行界面 设计,生成 ui 界面,后续只需加载 ui 文件,在需要的地方添加界面代码,真正做到 界面与代码分离,降低耦合性。
2 )数据库
本系统使用 MySQL 数据库。使用 pymysql 进行连接,开始尝试过用 QMYSQL进行连接,但是存在很多问题,比如版本问题和不兼容问题,试了很多博主推荐的方 法都没有解决,最终采用了最原始的方法。
3.3.2 功能模块实现
1 )登录注册模块实现
登录和注册模块隐藏 PySide2 原有的边框,和退出、最大化、最小化按钮,设置窗口大小为 800*450 ,且打开后窗口固定在屏幕中央不可拖动。在主窗口自定义最小 化和退出按钮。点击注册按钮跳转的注册页面,注册页面添加返回功能,点击返回按 钮回到登录界面。
设置窗口样式关键代码实现如下:
self.ui.resize(800, 450)
# 设置窗口不可拖动
self.ui.setFixedSize(self.ui.width(), self.ui.height())
# 设置窗口只显示关闭按钮
self.ui.setWindowFlags(Qt.WindowCloseButtonHint)
self.ui.setWindowFlags(Qt.FramelessWindowHint)
设置按钮功能代码如下:
self.ui.close_btn.clicked.connect(QApplication.quit)
self.ui.min_btn.clicked.connect(self.min_window)
self.ui.back_btn.clicked.connect(self.back_login)
def min_window(self):
self.ui.showMinimized()
# 注册页面返回功能
def back_login(self):
self.ui.hide()
SI.loginWin.ui.show()
登陆界面实现用户名校验,输入合法用户名、密码直接回车可以登录,点击登录按钮也可以登录。点击右上角搜索按钮,程序页面最小化,点击退出按钮退出程序。 登陆界面程序运行效果如图 所示。
注册页面实现账号、密码校验,输入合法用户名、合理密码、确认密码后点击注册按钮注册成功后进入主界面,不成功则重新注册。点击右上角收缩按钮最小化页面, 点击退出按钮退出程序。点击左上角返回按钮,返回到登录界面。界面大小固定且居 中,不可拖动。注册界面程序运行效果如图 所示。
2 )人脸识别实现
主界面采用 QMidArea 多区域设计。人脸识别是其中一个页面,点击人脸识别按钮,进入人脸识别页面,点击选择摄像头按钮,选择可用摄像头按钮选择摄像头,然 后点击开始识别按钮,如果未选择可用摄像头,则开始识别按钮禁用。在人脸识别这 一板块,涉及人脸区域目标检测和算法优化。人脸区域目标检测采用 YOLOv5 算法,
返回坐标区域和识别结果。关键代码如下:
for *xyxy, conf, cls in reversed(det):
xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4))).view(-1).tolist()
xywh = [round(x) for x in xywh]
xywh = [xywh[0] - xywh[2] // 2, xywh[1] - xywh[3] // 2, xywh[2], xywh[3]]
cls = names[int(cls)]
conf = float(conf)
detections.append({'class': cls, 'conf': conf, 'position': xywh}) 
在人脸识别优化上,采用目标检测算法进行优化,优化完后的帧率可以达到 15以上,视频流畅度可以满足,主要代码如下:
# 如果当前帧和上一帧人脸数未发生变化
if (self.current_face_cnt == self.last_face_cnt) and (self.reclassify_cnt != self.reclassify_interval):
……
else:
if self.current_face_cnt == 0:
self.current_frame_face_name_list = []
self.current_feature = []
else: 
人脸识别的过程,根据检测出的人脸区域,标定人脸 68 个特征点,然后提取 128D 人来特征,遍历人脸特征库,返回二者之间的欧氏距离,如果欧式距离小于一定的阈 值,就可以认为识别的人脸是同一张人脸,本系统采取的阈值是 0.5 ,在训练样本最 够大的情况下,阈值可以继续调整。
# 检测人脸 可以检测多个人脸 返回检测结果和人脸坐标(x,y,w,h)
detections = fa.detect(img_rd)
print("人脸数:", len(detections))
faces = []
mask_or_not = []
for i in detections:
pos = i['position']
# 将坐标转化为 Dlib 类型(左上,右下)
face = Dlib.rectangle(pos[0], pos[1], pos[0] + pos[2], pos[1] + pos[3])
faces.append(face)
mask_or_not.append(i['class'])
…
def return_face_recognition_result(img, face):
shape = predictor(img, face)
# 返回 128D 特征
featureX = face_reco_model.compute_face_descriptor(img, shape)
current_feature = []
for i in range(len(featureX)):
current_feature.append(featureX[i])
print(">>>当前人脸 128D 特征提取完成>>>", current_feature)
return current_feature 
人脸识别界面点击主程序界面的人脸识别按钮,进入该界面。界面中间区域用 于展示摄像头画面,右上角小区域用于展示人脸捕获图像,下面展示人脸识别信息。 程序运行效果如图 所示。
当不佩戴口罩的人脸区域出现时,摄像头区域框出人脸范围,并在左上角标注识别姓名和 no-mask 的标志。右侧展示当前人脸和姓名、是否佩戴口罩、人脸数、帧率 等信息。程序运行效果如图 所示。
 
当佩戴口罩的人脸区域出现时,摄像头区域框出人脸范围,区域右上角展示姓名和 mask ,右侧展示各种信息,包括姓名、 mask 、人脸数、帧率。程序运行效果如图 所示。
3 ) 信息录入实现
人脸信息录入模块与识别模块相似,都是利用 YOLOv5 目标检测算法进行人脸区域标定,据检测出的人脸区域,标定人脸 68 个特征点,然后提取 128 维人脸特征,
同时将截取的图片镜像处理,一共得到同一个人佩戴口罩和不佩戴口罩以及镜像文件 四种特征值,存入数据库。关键代码如下:
# 不管用户图片是否已经录入都可以重新插入,人脸识别要想准确就要多多益善
img = self.image
img_mirror = cv2.flip(img, 1) # 镜像文件
# 识别人脸区域,并 class,cfs,position 分类,概率,位置
detections = fa.detect(img)
# 将人脸位置转化为列表
face = [detections[0]['position'][0], detections[0]['position'][1],
detections[0]['position'][0] + detections[0]['position'][2],
detections[0]['position'][1] + detections[0]['position'][3]]
# 将人脸坐标列表转化为 Dlib 类型
rect = sa.to_Dlib_rectangle(face)
# 返回人脸特征点
fe = sa.return_face_recognition_result(img, rect) # 源文件的人脸特征点
fe_mirror = sa.return_face_recognition_result(img_mirror, rect_mirror) # 镜像文件的人脸特征点 

人脸录入界面中间区域用于展示当前摄像头捕获的画面,右侧输入用户 ID 和用户名,当点击采集佩戴口罩照片或者采集不配戴口罩照片的按钮时,采集到的人脸图 片展示到右上角的小区域中。Log 区域用展示各种操作信息。程序运行效果如图 所示。

4 )人员管理实现
人员管理包括增、删、查三个二级模块,增加模块又包括批量导入图片,批量导入 excel 表格,新增一个人的信息。导入图片需要现将图片按照指定格式命名后,放 在一个文件夹里面,然后选择这个文件夹导入图片。关键代码如下:
filePath = QFileDialog.getExistingDirectory(self.ui, "选择图片路径")
if not filePath:
return
# 设置项目根目录
SI.projectPath = filePath
fileList = []
for root, dirs, files in os.walk(filePath):
fileList = files 

新增单条记录是创建了一个新的 ui 界面,然后设置输入用户名,工号编辑框,点击按钮选择照片,点击保存开始导入,点击取消退出新增。删除功能,选择所要删除的行,然后点击删除按钮就可以删除一行信息。关键代码如下:

# 删除某一行的数据
row_select = self.ui.all_user_table.selectedItems() 
查询功能,可以根据用户名和工号进行查询,如果什么都不输入点击查询按钮,
默认展示所有的录入数据。程序运行效果如图 所示。
单条数据新增的页面,输入用户名和学号,分别点击不佩戴口罩照片和佩戴口罩照片选择图片录入,点击保存按钮录入成功,点击取消按钮退出当前页面。学号做了 长度和纯数字校验,防止用户将学号和姓名的位置输入错误。程序运行效果如图 所示。
5 )通行记录管理实现
通行记录模块会展示所有的通行记录信息,通行记录不支持删除,因为需要根据记录找到对应的人。可以根据用户名查询指定姓名的人的通行记录。该模块也可以充 当公司考勤功能,应为会记录识别时间。页面效果如图 所示。

源码链接面向佩戴口罩的人脸识别系统

  • 21
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值