摘要:本篇博客呈现了一种基于深度学习的人脸表情识别系统,并详细展示了其实现代码。系统采纳了领先的YOLOv8算法,并与YOLOv7、YOLOv6、YOLOv5等早期版本进行了比较,展示了其在图像、视频、实时视频流及批量文件中识别人脸表情的高准确度。文章深入阐释了YOLOv8的工作机制,并配备了相应的Python代码实现、用于模型训练的数据集,以及一个基于PySide6的用户界面。该系统不仅实现了对人脸表情的精准识别和分类,还提供了包括用户认证管理、模型快速切换及界面个性化定制在内的多项功能,为了方便研究人员和深度学习初学者,本文还包含了完整的代码资源和数据集的下载链接。本文结构如下:
文章目录
- 前言
- 1.数据集介绍
- 2. 系统界面效果
- 3. YOLOv8算法原理
- 4. 代码简介
- 4.1 模型预测
- 4.2 模型训练
- 4.3 YOLOv5、YOLOv6、YOLOv7和YOLOv8对比
- 4.4 代码实现
- 5. 人脸表情识别系统实现
- 5.1 系统设计思路
- 5.2 登录与账户管理
- 下载链接
- 6. 总结与展望
- 结束语
➷点击跳转至文末所有涉及的完整代码文件下载页☇
基于YOLOv8/v7/v6/v5的人脸表情识别系统演示与介绍(Python+PySide6界面+训练代码)
前言
人脸表情识别(FER)是机器视觉领域的一个重要分支,它专注于从图像或视频中识别人类的面部表情。近年来,随着深度学习技术的快速发展,FER的研究取得了显著进展。现代FER系统普遍采用卷积神经网络(CNN)和循环神经网络(RNN)等深度学习结构。这些网络能够从大量带标签的面部表情数据中学习复杂的特征表示。例如,CNN在提取面部特征方面表现出色,而RNN则擅长处理序列数据,如视频中的连续表情变化。
高质量的数据集对FER研究至关重要。公开的面部表情数据集,如FER-2013、CK+、和AFEW,提供了大量带有情感标签的面部图像和视频。这些数据集有助于训练和评估FER模型。同时,数据集的多样性和代表性也是当前研究的一个重点,以确保模型在不同人群和场景下的泛化能力。
实时FER系统的开发是当前的一个热点,它对于视频监控、人机交互等应用场景尤为重要。为此,研究者们不仅在算法效率上做出努力,还在模型压缩和优化方面进行了大量工作,以适应不同的硬件和实时处理需求。
在人脸表情识别的研究领域,最近的进展包括了多种先进技术的应用。例如,RAF-DB数据库,由北京邮电大学的PRIS实验室提供,收集了超过300,000张从互联网上采集的面部图像。这些图像被分类为七种表情:惊讶、恐惧、厌恶、愤怒、悲伤、快乐和中性,并包含了详细的标记信息。另外,SENet是一种新的图像识别架构,它通过比较特征通道之间的相关性来增强关键特征,从而提高分类准确性。SE-ResNet结合了SENet和ResNet架构,通过SE块来捕捉每个通道的重要性,从而判断信息的主次,并通过残差块将前一个卷积层的特征信息与下一个层结合,以解决深层网络中的梯度消失问题。1
YOLO是一种基于深度学习的实时对象检测算法,区别于传统的两步检测方法(首先生成候选区域,然后对这些区域进行分类),YOLO将对象检测作为单一的回归问题,直接从图像像素到边界框坐标和类别概率的预测。这种方法显著提高了处理速度,使其适用于实时应用。
近年来,YOLO的几个版本(如YOLOv3和YOLOv4)在人脸表情识别方面取得了显著进展。这些版本通过引入新的网络架构和训练技巧,如批量归一化、残差网络等,提高了识别的准确度和鲁棒性。研究表明,这些改进后的YOLO版本在各种条件下(如不同光照、不同角度的面部图像)都表现出较好的识别效果。
本博客所做的工作是基于YOLOv8算法构建一个人脸表情识别系统,呈现系统界面的效果,深入讲解其算法原理,提供代码实现,并分享系统的开发过程。希望本博客的分享能给予读者一定的启示,推动更多的相关研究。本文的主要贡献如下:
- 采用最先进的YOLOv82算法进行人脸表情识别,并对比YOLOv73、YOLOv64、YOLOv55等算法的结果:尽管已有多项关于人脸表情检测的研究,但这些研究主要使用了早期的深度学习模型,例如CNN和ResNet等。与这些模型相比,YOLOv8算法在多个方面展现出更高的效率和精准度。在本文中,将详细介绍如何运用这一最新的目标检测算法进行人脸表情检测,为相关领域的研究者和从业者提供全新的研究思路和实践手段。
- 利用PySide6实现人脸表情识别系统:在本文中,将探讨如何利用Python的PySide6库开发一个用户界面友好的人脸表情识别系统。该系统使用户能够以更直观、更便捷的方式进行人脸表情检测,有助于促进YOLOv8算法的应用,并推动人脸表情检测技术的实际应用。
- 包含登录管理功能:在系统中,我计划设计一个登录管理功能,用户需完成登录操作后方可使用该系统。这不仅能够提升系统的安全性,还为未来添加更多个性化功能提供了可能性。
- 对YOLOv8模型的深入研究:在运用YOLOv8算法进行人脸表情检测与识别的同时,我将对该算法的性能展开详尽研究,包括对模型精准度、召回率等关键指标的评估,以及对模型在不同环境和条件下表现的分析等。这将有助于更全面地理解YOLOv8算法,并为进一步优化和改进该算法提供了基础。
1.数据集介绍
在探索面部表情识别的广阔领域中,一个精心构建和平衡的数据集对于训练一个准确且公正的机器学习模型至关重要。人脸表情检测数据集的部分截图如下所示,我们的数据集包含了9900张精选图像,这些图像被分为8001张训练图像、900张测试图像和999张验证图像。通过这样的划分,我们确保模型在学习阶段有足够的数据去捕捉不同表情的特征,在验证阶段调整参数以避免过拟合,并在测试阶段公正地评估模型的泛化能力。
许多现代相机和智能手机在拍照时会记录图像的定向信息(例如横向或纵向)在EXIF数据中。但是,在处理图像数据时,许多图像处理工具或库不会自动考虑这些定向信息,导致图像在加载时可能出现方向错误的问题。在预处理中应用自动定向,意味着图像将被根据其EXIF数据中记录的方向自动调整。在深度学习中,通常需要将所有输入图像调整为统一的尺寸。这样做可以确保网络的输入层具有固定的维度。在实际应用中,选择最合适的图像预处理方法取决于具体任务的需求和所使用的深度学习模型的特性。
在预处理阶段,我们采用了自动定向校正,以确保所有图像在空间方向上的一致性,从而减少模型学习过程中的不必要复杂性。此外,所有图像都被统一拉伸到640x640像素的分辨率,这一步骤标准化了输入数据的尺寸,为特征提取提供了均一的基础。在类别标注上,我们进行了精心的调整:总共有4个类别经过重新映射,以及2个类别被移除,从而提高了类别之间的区分度,并确保模型能够集中学习那些具有足够样本的表情。值得注意的是,我们的数据集并没有应用任何形式的增强处理,旨在评估模型在处理未经增强的原始图像时的性能。这种方法虽然可能会降低模型对新颖环境的适应能力,但也为我们提供了观察模型在基础条件下的纯净性能的机会。
下图条显示了数据集中不同类的实例分布,包括Anger(愤怒)、Contempt(轻蔑)、Disgust(厌恶)、Fear(恐惧)、Happy(快乐)、Neutral(中立)、Sad(悲伤)和Surprise(惊讶)。通过分布图我们可以看出,这些情绪类别在数据集中分布相对均衡,这种均衡性是通过精心设计和数据筛选实现的。均匀的类别分布对于防止算法偏见和确保模型不会偏向于过度代表的类别是至关重要的。可以看到,每个表情类别的实例数量差异不大,有利于模型的训练。
从目标检测的角度来看,我们的数据集的边界框分布图表明,大多数人脸都集中在图像的中心区域。这一发现提示我们,尽管面部通常位于图像中心,但在未来的数据收集和增强阶段中,增加对图像边缘区域的关注也是必要的,以提高模型在各种不同拍摄条件下的适应性和准确性。边界框的宽度和高度分布相对集中,表明大多数面部图像在形状和尺寸上保持一致。这样的一致性对于确保模型能够有效地从不同个体的表情中提取关键特征是有益的。博主使用的类别代码如下:
Chinese_name = {"Anger": "愤怒", "Contempt": "轻蔑", "Disgust": "厌恶", "Fear": "恐惧", "Happy": "快乐",
"Neutral": "中性", "Sad": "悲伤", "Surprise": "惊讶"}
模型训练时需要特别注意样本不均衡问题,并采取策略如数据增强或权重调整来处理它。此外,由于大多数对象位于图像中心,模型不需要特别处理图像边缘的情况。最后,由于对象尺寸的高度一致性,模型不需要对极端尺寸的对象进行过多的泛化处理。
2. 系统界面效果
系统以PySide6作为GUI库,提供了一套直观且友好的用户界面。下面,我将详细介绍各个主要界面的功能和设计。
(1)系统提供了基于SQLite的注册登录管理功能。用户在首次使用时需要通过注册界面进行注册,输入用户名和密码后,系统会将这些信息存储在SQLite数据库中。注册成功后,用户可以通过登录界面输入用户名和密码进行登录。这个设计可以确保系统的安全性,也为后续添加更多个性化功能提供了可能性。
(2)在主界面上,系统提供了支持图片、视频、实时摄像头和批量文件输入的功能。用户可以通过点击相应的按钮,选择要进行人脸表情检测的图片或视频,或者启动摄像头进行实时检测。在进行人脸表情检测时,系统会实时显示检测结果,并将检测记录存储在数据库中。
(3)此外,系统还提供了一键更换YOLOv8/v5模型的功能。用户可以通过点击界面上的"更换模型"按钮,选择不同的YOLOv8模型进行检测。与此同时,系统附带的数据集也可以用于重新训练模型,以满足用户在不同场景下的检测需求。
(4)为了提供更个性化的使用体验,这里系统支持界面修改,用户可以自定义图标、文字等界面元素。例如,用户可以根据自己的喜好,选择不同风格的图标,也可以修改界面的文字描述。
3. YOLOv8算法原理
Ultralytics公司于2023年初发布YOLOv8模型,相较于2020年发布的YOLOv5模型,YOLOv8模型将C3模块(CSP Bottleneck with 3 convolutions)改进成C2f模块(CSP Bottleneck with 2 convolutions),C3模块和C2f模块结构如下图(a)所示。图中CBS(Convolutions Bn SiLU)模块由基础卷积(Conv)、批量归一化(BN)和激活函数(SiLU)组成。C2f模块采用了多分支流设计,为模型提供了更丰富的梯度信息,强化了模型的特征提取能力,提高网络的学习效率。
YOLOv8模型仍然采用anchor free方法,降低检测过程中正样本框数量,并提升处理速度。此外,模型结合了GFL(generalized focal loss)损失计算策略,将Detect模块由YOLOv5中的耦合头改进成解耦头,如上图(b)所示。解耦头将分类任务和回归任务分开进行,避免了两个任务之间的干扰,理论上能够提高模型的训练效率。传统的YOLO系列算法的耦合头输出三类信息,而YOLOv8模型中的解耦头仅输出分类和回归信息。分类信息的输出通道数等于类别数,输出的内容综合了分类信息和置信度信息。回归信息的输出通道数等于4 reg_max(Regression maximum),输出内容为回归框在最大回归范围上的概率分布。
YOLOv8采用了动态标签匹配策略,增加了正样本框选择的灵活度。在损失计算方面,YOLOv8除了计算分类和回归损失外,还引入了DFL(distribution focal loss)损失。DFL损失利用交叉熵的思想,通过将预测框回归至标签框的上下整数范围内,优化模型训练。
4. 代码简介
在本节中,我们将详细介绍如何使用YOLOv8进行人脸表情检测的代码实现。代码主要分为两部分:模型预测和模型训练。
4.1 模型预测
在模型预测部分,首先导入了OpenCV库和YOLO模型。OpenCV库是一个开源的计算机视觉和机器学习软件库,包含了众多的视觉处理函数,使用它来读取和处理图像。YOLO模型则是要用到的目标检测模型。
import cv2
from ultralytics import YOLO
接着,加载自行训练好的YOLO模型。这个模型是在大量的图像上预训练得到的,可以直接用于目标检测任务。
model.load_model(abs_path("weights/emotion-yolov8n.pt", path_type="current"))
然后,使用OpenCV读取了一个图像文件,这个图像文件作为要进行目标检测的图像输入。
img_path = abs_path("test_media/test.png")
image = cv_imread(img_path)
在读取了图像文件之后,就可以使用加载的模型对图像进行预测了。下图为预测结果。
pred, superimposed_img = model.predict(pre_img)
4.2 模型训练
这里我们开始训练和测试自己的数据集,在cmd终端或pycharm中运行run_train_model.py进行训练,以下是训练过程中的结果截图。YOLOv8的损失函数是其性能的关键部分,它指导模型学习如何准确地检测和分类对象。YOLOv8损失函数通常由以下几部分组成:
坐标损失(Bounding Box Loss):这部分损失确保预测的边界框准确地覆盖目标对象。它通常使用均方误差(Mean Squared Error, MSE)来计算预测框和真实框之间的差异。公式表示为:
L c o o r d = ∑ i = 0 S 2 ∑ j = 0 B 1 i j o b j [ ( x i − x ^ i ) 2 + ( y i − y ^ i ) 2 ] L_{coord} = \sum_{i=0}^{S^2} \sum_{j=0}^{B} 1_{ij}^{obj} [(x_i - \hat{x}_i)^2 + (y_i - \hat{y}_i)^2] Lcoord=i=0∑S2j=0∑B1ijobj[(xi−x^i)2+(yi−y^i)2]
置信度损失(Confidence Loss):这部分损失计算模型预测的边界框中存在对象的置信度与实际情况之间的差异。它通常使用交叉熵损失(Cross-Entropy Loss)来计算。
L c o n f = ∑ i = 0 S 2 ∑ j = 0 B 1 i j o b j log ( σ ( C i ) ) + 1 i j n o o b j log ( 1 − σ ( C i ) ) L_{conf} = \sum_{i=0}^{S^2} \sum_{j=0}^{B} 1_{ij}^{obj} \log(\sigma(C_i)) + 1_{ij}^{noobj} \log(1 - \sigma(C_i)) Lconf=i=0∑S2j=0∑B1ijobjlog(σ(Ci))+1ijnoobjlog(1−σ(Ci))
分类损失(Classification Loss):这部分损失计算预测的类别与真实类别之间的差异。对于多类别分类问题,通常使用交叉熵损失。
L c l a s s = − ∑ i = 0 S 2 1 i o b j ∑ c ∈ c l a s s e s p i ( c ) log ( p ^ i ( c ) ) L_{class} = -\sum_{i=0}^{S^2} 1_{i}^{obj} \sum_{c \in classes} p_i(c) \log(\hat{p}_i(c)) Lclass=−i=0∑S21iobjc∈classes∑pi(c)log(p^i(c))
整体损失函数是这三个部分的加权和,可以表示为:
L = λ c o o r d L c o o r d + λ c o n f L c o n f + λ c l a s s L c l a s s L = \lambda_{coord} L_{coord} + \lambda_{conf} L_{conf} + \lambda_{class} L_{class} L=λcoordLcoord+λconfLconf+λclassLclass
以下表格详细介绍了YOLOv8模型训练中使用的一些重要超参数及其设置:
超参数 | 设置 | 说明 |
---|---|---|
学习率(lr0 ) | 0.01 | 决定了模型权重调整的步长大小,在训练初期有助于快速收敛。 |
学习率衰减(lrf ) | 0.01 | 控制训练过程中学习率的降低速度,有助于模型在训练后期细致调整。 |
动量(momentum ) | 0.937 | 加速模型在正确方向上的学习,并减少震荡,加快收敛速度。 |
权重衰减(weight_decay ) | 0.0005 | 防止过拟合,通过在损失函数中添加正则项减少模型复杂度。 |
热身训练周期(warmup_epochs ) | 3.0 | 初始几个周期内以较低的学习率开始训练,逐渐增加到预定学习率。 |
批量大小(batch ) | 16 | 每次迭代训练中输入模型的样本数,影响GPU内存使用和模型性能。 |
输入图像大小(imgsz ) | 640 | 模型接受的输入图像的尺寸,影响模型的识别能力和计算负担。 |
在模型训练部分,首先导入YOLO模型,并加载了预训练的YOLOv8模型。
from ultralytics import YOLO
model = YOLO('./weights/yolov8s.pt', task='detect')
接着开始训练模型。其中指定了训练数据的配置文件路径,使用GPU进行训练,使用2个工作进程加载数据,输入图像的大小为640x640,训练100个epoch,每个批次的大小为8,训练任务的名称为’train_emotion’。
results2 = model.train(
data=data_path,
device='0',
workers=workers,
imgsz=640,
epochs=120,
batch=batch,
name='train_v8_' + data_name
)
在深入研究YOLOv8模型的性能时,训练和验证损失的趋势以及模型的精确度和召回率提供了关键指标。在模型的训练过程中,损失函数的降低是我们监测模型学习进步的主要指标。观察到的训练边框损失(train/box_loss)呈现出一致的下降趋势,最终稳定在一个较低的水平,这表明模型在定位目标方面的能力得到了显著提升。对于分类损失(train/cls_loss),我们同样看到了一个下降的趋势,这意味着模型在区分不同类别方面的能力随着训练的进行在不断增强。。
在验证阶段,我们期望损失趋势与训练损失相似,因为这反映了模型在未见数据上的泛化能力。验证边框损失(val/box_loss)和分类损失(val/cls_loss)均显示出初始波动之后的下降趋势,尽管波动幅度相对较大,这是由于模型在处理验证集上不同于训练集的数据分布时的自然调整。边框损失的波动可能指出模型在某些时期对于定位任务的适应性出现了挑战,而分类损失的波动则可能反映了类别间的不平衡或是某些类别的辨识难度较高。
在性能指标方面,精确度(metrics/precision(B))的提升表明模型在预测正类别时越来越准确,而召回率(metrics/recall(B))的波动则表明模型在不断尝试平衡漏检与误检之间的关系。理想情况下,我们希望看到精确度和召回率都能稳定地提升,但在实际应用中,二者往往需要通过调整阈值来进行权衡。平均精确度均值(mAP)是一个综合性能指标,它考虑了检测阈值的变化。在我们的情况下,mAP@0.5(metrics/mAP@0.5(B))和mAP@0.5:0.95(metrics/mAP@0.5:0.95(B))都随训练周期增加而稳步提升,这表明模型的整体性能在逐步提高。尤其是mAP@0.5:0.95的上升趋势表明模型在更严格的评估条件下表现良好,这是模型细粒度识别能力提高的一个良好迹象。
下图为博主训练人脸表情检测的F1曲线图。F1分数也是一个关键指标,它综合考虑了模型的精确度和召回率,为我们提供了一个衡量模型性能的单一指标。从提供的F1-Confidence曲线图中,我们可以看到不同情绪类别的F1分数随置信度阈值的变化情况。整体上,曲线图揭示了模型对于不同情绪识别任务的性能,其中’Happy’和’Fear’的F1分数较高,显示出模型对这些表情的识别相对较好。相反,'Anger’和’Disgust’的F1分数较低,指出模型在这些类别上的识别性能有待提高。
以F1-curve为例,可以看到我们的模型在验证集上的均值平均准确率为0.191。从图表中可以观察到,随着置信度阈值的增加,大多数类别的F1分数先是上升然后逐渐下降。F1分数在某个点达到峰值,这表示了模型对于一个特定置信度阈值下的最佳综合性能。这个峰值对于选择模型操作点是非常重要的,因为它影响模型在实际应用中的表现。例如,图中显示所有类别的F1分数在置信度约为0.191时达到了0.48的峰值。这个数值可以被视为模型性能的一个基准,我们可以通过调整置信度阈值来优化模型的整体性能。
此外,不同的情绪类别之间F1分数的差异可能与训练数据的质量、类别间困难度的不同或是模型对特定特征的学习能力有关。例如,'Happy’和’Surprise’表情可能具有更明显的区分特征,如大的眼睛张开或明显的微笑,这使得模型更容易识别。而’Anger’和’Disgust’可能由于表情细微或与其他情绪相混淆而难以正确识别。一方面,我们可以通过收集更多的’Anger’和’Disgust’表情的数据或是提供更多的特征学习机会来增强模型在这些较弱的类别上的性能。另一方面,通过调整置信度阈值,我们可以优化模型的整体表现。在实际应用中,我们可能需要在保持高召回率(即尽量少错过表情)和高精确度(即尽量减少错误识别)之间找到一个平衡点。
4.3 YOLOv5、YOLOv6、YOLOv7和YOLOv8对比
(1)实验设计:
本实验旨在评估和比较YOLOv5、YOLOv6、YOLOv7和YOLOv8几种模型在人脸表情目标检测任务上的性能。为了实现这一目标,博主分别使用使用相同的数据集训练和测试了这四个模型,从而可以进行直接的性能比较。该数据集包含人脸表情的图像。本文将比较分析四种模型,旨在揭示每种模型的优缺点,探讨它们在工业环境中实际应用的场景选择。
模型 | 图像大小 (像素) | mAPval 50-95 | CPU ONNX 速度 (毫秒) | A100 TensorRT 速度 (毫秒) | 参数数量 (百万) | FLOPs (十亿) |
---|---|---|---|---|---|---|
YOLOv5nu | 640 | 34.3 | 73.6 | 1.06 | 2.6 | 7.7 |
YOLOv8n | 640 | 37.3 | 80.4 | 0.99 | 3.2 | 8.7 |
YOLOv6N | 640 | 37.5 | - | - | 4.7 | 11.4 |
YOLOv7-tiny | 640 | 37.4 | - | - | 6.01 | 13.1 |
(2)度量指标:
- F1-Score:F1-Score是精确率(Precision)和召回率(Recall)的调和平均值。精确率是指模型正确识别的正例与所有识别为正例的案例之比,而召回率是指模型正确识别的正例与所有实际正例之比。F1-Score对于不平衡的数据集或者需要同时考虑精确率和召回率的任务特别重要。
- mAP(Mean Average Precision):mAP是衡量模型在多个类别上平均检测准确度的指标。它计算了模型在所有类别上的平均精度,是目标检测领域中常用的性能度量。
名称 | YOLOv5nu | YOLOv6n | YOLOv7-tiny | YOLOv8n |
---|---|---|---|---|
mAP | 0.493 | 0.493 | 0.492 | 0.497 |
F1-Score | 0.48 | 0.48 | 0.48 | 0.48 |
(3)实验结果分析:
YOLO 版本(v5n、v6、v7、v8n)的 mAP 分数非常非常接近,分别为( 0.493、0.493、0.492 和 0.497),表明模型的整体检测能力相同。YOLOv8n 的 mAP 为 0.497,略优于其他版本。虽然四个版本在F1-Score上表现相似,但YOLOv8n在mAP上略有优势,这表明它在对象检测任务中的整体性能略优于其他版本
从条形图中可以看出:在mAP方面,这四个模型的表现非常接近。YOLOv8n稍微领先,其mAP分数为0.497,而其它三个模型的mAP均为0.493或0.492。这表明在表情检测任务中,这些模型的准确性差异不大。对于F1-Score,所有模型均达到了0.48的分数,表明它们在精确度和召回率之间取得了相似的平衡。
值得注意的是,这里mAP值普遍不是很高,博主认为原因有三个:(1)表情识别本身是一件很有挑战的任务,使用的数据集复杂并包含大量难以区分的表情,例如,细微的表情差异、不同的光照条件、不同的姿态和遮挡等都可能影响模型的性能;(2)数据集中标注的质量对模型训练至关重要,不准确或不一致的标注会导致模型学习错误的特征,进而影响检测性能。(3)通用目标检测的架构可能限制了表情识别的检测,YOLO系列模型虽然在速度和实时检测方面表现出色,但在处理一些细节方面可能不如其他一些专门针对表情检测优化的模型。此外,YOLO模型通常需要大量数据来实现更好的泛化,如果训练数据不足,可能会导致性能下降,目前我们的数据量其实并不算很多。
4.4 代码实现
在这一节中,我们将详细介绍如何使用YOLOv8实现摄像头画面中人脸表情识别的代码实现。这个实现主要包括创建主窗口、处理每一帧图像、加载模型、开始处理媒体流等步骤。
在实时人脸表情识别系统中,结合YOLOv8模型和一系列开源库,如OpenCV、QtFusion和PySide6等,来实现主窗口的展示、摄像头帧的处理以及人脸表情的检测和标注等功能。
(1)导入必要的模块和配置
首先,需要引入一些必要的库,包括图像处理库OpenCV、图形界面库QtFusion和PySide6,以及物体检测模型库YOLOv8Model等。
import random # 用于生成随机颜色
import sys # 用于访问Python解释器相关的功能
import time # 用于记录操作所需的时间
from QtFusion.config import QF_Config
import cv2 # OpenCV库,用于图像处理
from QtFusion.widgets import QMainWindow # 用于创建GUI窗口
from QtFusion.utils import cv_imread, drawRectBox # 辅助函数,用于图像读取和绘制
from PySide6 import QtWidgets, QtCore # 构建图形用户界面
from QtFusion.path import abs_path
from YOLOv8Model import YOLOv8Detector # YOLOv8模型,用于目标检测
QF_Config.set_verbose(False)
这一部分主要负责导入各种模块。random用于随机颜色生成,sys和time分别用于系统操作和时间处理。cv2是图像处理的核心,而QtFusion和PySide6则用于构建用户界面。YOLOv8Detector是进行目标检测的关键类。
(2)定义类别和模型
在这里,cls_name定义了要识别的人脸表情类型。colors为每种类型生成随机颜色,用于检测结果的可视化。model是我们的YOLOv8检测器,用于加载并运行目标检测模型。
cls_name = ["愤怒", "轻蔑", "厌恶", "恐惧", "快乐", "中性", "悲伤", "惊讶"] # 定义类名列表
colors = [[random.randint(0, 255) for _ in range(3)] for _ in range(len(cls_name))] # 为每个目标类别生成一个随机颜色
model = YOLOv8Detector() # 创建YOLOv8Detector对象
model.load_model(abs_path("weights/emotion-yolov8n.pt", path_type="current")) # 加载预训练的YOLOv8模型
(3)创建主窗口
MainWindow类继承自QMainWindow,用于创建GUI窗口。在构造函数中,我们设置窗口大小并创建一个标签来显示图像。keyPressEvent方法允许用户通过按下“Q”键来关闭窗口。
class MainWindow(QMainWindow): # 自定义主窗口类
def __init__(self): # 构造函数
super().__init__() # 调用父类构造函数
self.resize(850, 500) # 设置窗口大小
self.label = QtWidgets.QLabel(self) # 创建标签用于显示图像
self.label.setGeometry(0, 0, 850, 500) # 设置标签位置和大小
def keyPressEvent(self, event): # 键盘事件处理
if event.key() == QtCore.Qt.Key.Key_Q: # 按下Q键时
self.close() # 关闭窗口
(4)主程序流程
在主程序中,我们首先初始化Qt应用和主窗口。接着,读取并处理图像,使用YOLOv8模型进行目标检测,并在检测到的目标周围绘制边界框和标签。最后,图像被显示在GUI窗口中。
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv) # 初始化Qt应用
window = MainWindow() # 创建主窗口实例
img_path = abs_path(("test_media/test.png") # 定义图像路径
image = cv_imread(img_path) # 读取图像
image = cv2.resize(image, (850, 500)) # 调整图像大小以适应窗口
pre_img = model.preprocess(image) # 图像预处理
t1 = time.time() # 记录开始时间
pred, superimposed_img = model.predict(pre_img) # 进行目标检测
t2 = time.time() # 记录结束时间
print("推理时间: %.2f" % (t2 - t1)) # 打印推理时间
det = pred[0] # 获取检测结果
if det is not None and len(det):
det_info = model.postprocess(pred) # 后处理
for info in det_info: # 遍历检测到的每个对象
name, bbox, conf, cls_id = info['class_name'], info['bbox'], info['score'], info['class_id']
label = '%s %.0f%%' % (name, conf * 100) # 生成标签
image = drawRectBox(image, bbox, alpha=0.2, addText=label, color=colors[cls_id]) # 绘制边界框和标签
window.dispImage(window.label, image) # 在窗口中显示图像
window.show() # 显示窗口
sys.exit(app.exec()) # 启动事件循环
在此,"emotion-yolov8n.pt"是经过大量人脸表情图像训练得到的模型权重文件,而model.names则包含了模型中人脸表情类别的名称。这就是实现实时人脸表情识别系统的完整代码,整个过程包括了数据预处理、YOLOv8模型预测、结果后处理和可视化等步骤,结构清晰,逻辑简洁。通过这样的方式,可以实现对摄像头捕获的画面进行实时的人脸表情识别和标注。
5. 人脸表情识别系统实现
在实现一款实时人脸表情检测与识别系统时,采用面向对象的设计思路,依赖Python语言和多种开源库如Pyside6、QtFusion、Pytorch等。其中,重要的MainWindow类是系统的主体,负责提供用户界面来控制输入源、进行人脸表情检测与识别,并展示检测结果。以下将详细介绍其设计思路、架构设计以及整个流程。
5.1 系统设计思路
MainWindow类的主要目标是提供一个用户友好的交互式人脸表情检测与识别系统。为了实现这个目标,采取了将界面、媒体处理和模型集成在一起的设计思路。通过对象组合的方式,将不同的处理器和模型组织在一起,让每个功能模块都能独立进行,同时,还利用信号和槽机制来进行模块间的交互和数据传递。
(1)架构设计
在MainWindow类的架构设计中,采用了处理层、界面层、控制层的设计模式。这个系统的设计充分考虑了用户体验和系统性能,通过合理的架构设计和技术选型,实现了一个高效且易于使用的人脸表情检测与识别系统。
- 处理层(Processing Layer):处理层是系统的核心,它包含了如下关键组件:YOLOv8Detector,这个类是系统的主要检测器,负责调用YOLOv8模型进行实时人脸表情识别;YOLOv5/v6/v7 Model,这些类提供了其他版本的YOLO模型,以供系统选择使用,增加了系统的灵活性和多样性;图像预处理,在图像送入模型前,需要进行一系列的预处理步骤,以确保模型能够接收到格式正确、质量优化的图像数据;NMS(非极大值抑制)等类,用于处理模型输出,消除重复的检测框,确保每个目标只有一个最优的检测结果;frame_process,该函数或方法处理视频流中的每一帧图像,实现连续的表情检测。
- 界面层(UI Layer):界面层负责与用户直接交互,其主要组件如下:Ui_MainWindow,由Qt Designer工具生成,定义了所有的用户界面元素和布局;Qss美化,使用Qt StyleSheet(Qss)对界面进行美化,提升用户界面的视觉效果;setupUi,初始化用户界面,将所有定义的UI组件放置到MainWindow窗口中;clearUI,在需要的情况下清除或重置用户界面,例如在用户请求新的分析时;控件创建:动态创建用户交互控件,如按钮、滑动条等;QWindowCtrls,包含窗口控制相关的功能,如窗口最小化、关闭等。
- 控制层(Control Layer):控制层作为界面层和处理层之间的桥梁,协调两者的交互,包括:MainWindow槽函数,处理用户的输入事件,如按钮点击、菜单选择等,并触发相应的处理流程;MediaHandler,处理媒体相关的操作,例如加载视频文件、控制视频播放等;ImageHandler,处理图像相关的操作,例如加载图片、图像缩放、显示检测结果等;slot_init,初始化槽函数,确保界面元素与后端逻辑正确连接;toggle_function,开关特定功能,如启用或禁用某些界面元素,或切换处理流程的状态。
(2)系统流程
以下是人脸表情识别系统的工作流程详细介绍,这里博主绘制了一张系统逻辑的流程图供大家参考:
-
用户启动应用程序后,系统会创建MainWindow类的实例。这个实例负责初始化整个应用的界面和相关参数,为用户提供操作的起点。
-
应用程序提供了一个直观的界面,用户可以通过这个界面选择输入源。输入源可以是摄像头实时捕捉的图像、视频文件或是静态图片。
-
一旦用户确定了输入源,系统就会调用相关的媒体处理器和方法来处理输入数据。这可能涉及到摄像头的配置、视频文件的读取或图像文件的加载。
-
当媒体输入源准备就绪后,系统进入连续帧处理的循环,具体流程如下:
- 预处理阶段:系统对每一帧图像执行预处理,这可能包括图像的缩放、色彩空间转换和归一化等步骤,以满足YOLO模型的输入要求。
- 检测与识别阶段:预处理后的图像将被送入YOLOv8模型进行人脸表情的检测和识别。模型会输出人脸位置以及相应的表情类别。
- 界面更新阶段:随着检测结果的产生,界面将实时更新,展示检测框、标注表情类别,并在界面的表格或条形图中展示检测统计数据。
- 交互操作:用户可以通过界面提供的按钮执行多种操作,例如保存检测结果、查询作者和版本信息,以及通过下拉菜单筛选和分析特定的检测结果。
- 媒体控制:用户还可以控制媒体的播放状态,如启动或停止摄像头捕捉、视频播放或图像分析。
5.2 登录与账户管理
本系统还配备了一个基于PySide6和SQLite数据库的用户登录界面,提供了账户注册、密码修改、头像设置、账户注销和重新登录等功能。这些功能为每个用户创建了一个独立的空间,用户可以在其中保存和管理自己的检测结果和设置。
通过用户界面,用户可以轻松完成账户的注册和登录操作,然后进入主界面进行人脸表情检测。用户还可以在登录界面进行密码修改、头像设置和账户注销等操作。这些功能为用户提供了便利的个性化服务,让用户能够更好地使用人脸表情识别系统。
通过以上的设计和实现,人脸表情检测系统具备了导入各类深度学习模型,实现多物体识别和检测的能力。主界面中实时显示包括检测框、类别及置信度等信息;支持图片、视频、实时摄像头和批量文件输入,能实时识别并记录。还设计了用户登录界面,提供账户注册、密码修改、头像设置、账户注销和重新登录等功能,满足用户在实时目标检测场景下的需求。
下载链接
若您想获得博文中涉及的实现完整全部资源文件(包括测试图片、视频,py, UI文件,训练数据集、训练代码、界面代码等),这里已打包上传至博主的面包多平台,见可参考博客与视频,已将所有涉及的文件同时打包到里面,点击即可运行,完整文件截图如下:
完整资源中包含数据集及训练代码,环境配置与界面中文字、图片、logo等的修改方法请见视频,项目完整文件下载请见演示与介绍视频的简介处给出:➷➷➷
演示与介绍视频:https://www.bilibili.com/video/BV18m411S7V8/
在文件夹下的资源显示如下,下面的链接中也给出了Python的离线依赖包,读者可在正确安装Anaconda和Pycharm软件后,复制离线依赖包至项目目录下进行安装,另外有详细安装教程:(1)Pycharm软件安装教程;(2)Anaconda软件安装教程;(3)Python环境配置教程;
离线依赖安装教程:https://www.bilibili.com/video/BV1hv421C7g8/
离线依赖库下载链接:https://pan.baidu.com/s/1y6vqa9CtRmC72SQYPh1ZCg?pwd=33z5 (提取码:33z5)
6. 总结与展望
在本博客中,我们详细介绍了一个基于YOLOv8模型的人脸表情识别系统,还实验了YOLOv7、YOLOv6、YOLOv5等模型。系统以模块化的方式设计,充分采用了合理的架构设计,带来良好的可维护性和可扩展性。其用户界面友好,能够提供实时的人脸表情检测和识别结果展示,同时支持用户账户管理,以便于保存和管理检测结果和设置。
该系统支持摄像头、视频、图像和批量文件等多种输入源,能够满足用户在不同场景下的需求。在后面可以添加更多预训练模型,增加检测和识别的种类;优化用户界面,增强个性化设置;并积极聆听用户反馈,以期不断改进系统,以更好地满足用户的需求。
结束语
由于博主能力有限,博文中提及的方法即使经过试验,也难免会有疏漏之处。希望您能热心指出其中的错误,以便下次修改时能以一个更完美更严谨的样子,呈现在大家面前。同时如果有更好的实现方法也请您不吝赐教。
Huang, ZY., Chiang, CC., Chen, JH. et al. A study on computer vision for facial emotion recognition. Sci Rep 13, 8425 (2023). https://doi.org/10.1038/s41598-023-35446-4 ↩︎
Talaat F M, ZainEldin H. An improved fire detection approach based on YOLO-v8 for smart cities[J]. Neural Computing and Applications, 2023, 35(28): 20939-20954. ↩︎
Wang C Y, Bochkovskiy A, Liao H Y M. YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time object detectors[C]//Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition. 2023: 7464-7475. ↩︎
Li C, Li L, Jiang H, et al. YOLOv6: A single-stage object detection framework for industrial applications[J]. arXiv preprint arXiv:2209.02976, 2022. ↩︎
Wu W, Liu H, Li L, et al. Application of local fully Convolutional Neural Network combined with YOLO v5 algorithm in small target detection of remote sensing image[J]. PloS one, 2021, 16(10): e0259283. ↩︎