摘要:人脸检测是人脸表情识别系统中至关重要的一环,其准确性直接影响到整个系统的性能表现。本文介绍了使用SSD模型和OpenCV进行高效人脸检测的完整代码实现。我们详细介绍了SSD人脸检测器的工作原理,包括如何加载预训练的SSD模型,并对输入图像中的人脸进行检测和定位。提供了详细的代码资源,展示了如何使用OpenCV读取和处理图像,使用SSD模型进行人脸检测,并在检测到的人脸周围绘制边界框。本文结构如下:
文章目录
- 1. 问题描述与方案
- 2. 人脸检测步骤
- 3. 使用SSD进行人脸检测
- 4. 系统界面效果</font>
- 下载链接
- 5. 总结与展望
- 结束语
➷点击跳转至文末所有涉及的完整代码文件下载页☇
最新升级版—人脸表情识别系统v3.0(SSD+MobileNet/Xception,UI界面演示)
1. 问题描述与方案
四年前,我写了一篇关于利用深度学习算法进行表情识别的博客:人脸表情识别系统介绍——上篇(python实现,含UI界面及完整代码),虽然去年前年也都有更新这个系列,不过还是来一版这个的后续。
人类的面部表情是其最直接有效的情绪表达方式,针对表情识别技术的研究被认为是未来人机情感交互的主要发展方向1。美国的心理学家Ekman和Friesen经过大量的实验与测试后,将人类的表情定义为以下六类:生气(Angry)、厌恶(Disgust)、恐惧(Fear)、高兴(Happiness)、悲伤(Sadness)和惊讶(Surprise)。实际情况下为了和无表情有所区分,一般还增加一类:正常(Neutral),共计7种基础表情,如图1所示。在这个人工智能技术成为热门的时代,人脸表情识别已成为其中的一项研究热点,而卷积神经网络、深度信念网络和多层感知器等端对端的算法在人脸面部表情识别领域的运用尤为广泛。
目前,人脸识别( Facial Recognition, FR)精度已经超过人眼,人脸表情识别作为FR技术的一个重要组成部分,在计算机视觉、人机交互和情感计算中有着广泛的研究前景,包括人机交互、情绪分析、智能安全、娱乐、网络教育、智能医疗等。人脸表情识别的主要框架分为三个步骤:图像预处理、人脸检测和表情分类,如图所示。
首先,图像预处理阶段通过调整图片的大小和色彩来减少光照、角度等因素的干扰,为模型提供更准确的输入数据。接着,在人脸检测阶段,我们将利用OpenCV中已经训练好的SSD模型来识别和定位图像中的人脸。最后,在表情分类阶段,我们将采用基于MobileNet的深度学习模型2,这是一种轻量级但高效的卷积神经网络,特别适合在移动设备和资源受限的环境中进行实时的图像处理和分析。
SSD(Single Shot MultiBox Detector)是一种流行的对象检测算法3,以其高效和准确性而闻名。在OpenCV库中,SSD模型已经过预训练,可以直接用于识别和定位图像中的人脸。SSD模型通过一次性检测图像中的多个对象,免除了传统检测方法中需要的复杂步骤和大量的计算资源,使得实时人脸检测成为可能。
在接下来的部分中,我们将深入探讨如何使用OpenCV和SSD模型进行人脸检测,为后续的表情识别定位出ROI的区域。
2. 人脸检测步骤
这部分其实在之前的博客基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的日常场景下的人脸检测系统(深度学习模型+PySide6界面+训练数据集+Python代码)中给出了YOLO系列算法训练人脸检测器的详细介绍,感兴趣的可以看看。
这里我们介绍使用SSD人脸检测器进行人脸检测的步骤。SSD(Single Shot MultiBox Detector)是一种基于深度学习的对象检测方法,它能够在单次前向传递中同时预测对象的边界框和类别概率,因此在速度和准确性上都非常优秀。与传统的基于Haar特征和Adaboost级联分类器的方法不同,SSD直接从原始像素数据中学习特征,无需手动特征提取和滑动窗口,从而大大提高了检测的效率和准确性。
-
预处理输入图像: 对输入的图像进行一系列的预处理操作,包括尺寸缩放、归一化等,以适应SSD模型的输入要求。这些预处理步骤有助于减少模型处理不同图像时的变异性,确保检测结果的一致性。
-
使用SSD模型进行人脸检测: 预处理后的图像被输入到SSD模型中。SSD模型通过一次前向传播,对图像进行分析,并预测图像中每个可能区域的边界框和相应的置信度。每个边界框代表模型预测的人脸位置,而置信度则表示模型对其预测的确信程度。
-
处理检测结果: 模型输出的检测结果包括多个边界框和置信度。由于同一个人脸可能被检测到多次,因此需要对这些检测结果进行后处理。常见的后处理方法包括非极大值抑制(Non-Maximum Suppression, NMS),它通过移除重叠度较高且置信度较低的边界框,保留最佳的检测结果,从而解决重复检测的问题4。
-
标记检测到的人脸: 经过NMS处理后,我们将获得一组精简且准确的人脸边界框。最后,我们在原始图像上绘制这些边界框,并可能附加一些附加信息(如“Face”标签和置信度),以直观地展示检测到的人脸位置。
通过以上步骤,SSD人脸检测器能够高效且准确地在图像中定位人脸。与传统基于Haar特征的级联分类器相比,SSD方法省去了繁琐的特征提取和多尺度扫描过程,直接从数据中自动学习最优特征,大大提高了检测的效率和性能。此外,SSD模型的灵活性和扩展性也使其能够适应各种复杂的检测任务,这里效果还是不错的。
3. 使用SSD进行人脸检测
在这一节中,我们详细介绍如何使用OpenCV结合SSD模型进行人脸检测。SSD模型是一种高效的单阶段检测器,它能够在图像中快速定位对象的位置。在我们的这个项目中,我们使用该模型来检测图像中的人脸。
首先需要加载SSD模型,在OpenCV中,这可以通过使用cv2.dnn.readNetFromCaffe
函数实现,该函数需要两个参数:模型的配置文件(.prototxt)和训练好的权重文件(.caffemodel)。下面是加载模型的代码:
import cv2
# 加载模型的配置文件和已经训练好的模型权重
prototxt_path = "./models/deploy.prototxt"
caffemodel_path = "./models/res10_300x300_ssd_iter_140000.caffemodel"
# 使用OpenCV的dnn模块读取模型
net = cv2.dnn.readNetFromCaffe(prototxt_path, caffemodel_path)
这段代码首先导入了cv2
模块,然后定义了模型的配置文件和权重文件的路径。这两个文件是SSD模型的关键组成部分:.prototxt
文件定义了模型的架构,而.caffemodel
文件包含了模型的权重,这些权重是通过大量数据训练得到的。通过调用cv2.dnn.readNetFromCaffe
函数并传入这两个文件的路径,我们就可以加载训练好的SSD模型,准备进行人脸检测。
接下来,我们将使用加载的模型来处理图像。首先,我们需要从图像文件中读取图像,然后将其转换为模型可接受的格式。以下是对图像进行预处理并通过模型进行检测的代码:
# 读取图像
image = cv2.imread("happy2.png")
# 获取图像的尺寸并创建一个blob
(h, w) = image.shape[:2]
blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0,
(300, 300), (104.0, 177.0, 123.0))
# 将blob设置为网络的输入,并进行前向传播,得到检测结果
net.setInput(blob)
detections = net.forward()
在这段代码中,cv2.imread
用于读取图像。cv2.dnn.blobFromImage
函数对图像进行了一系列预处理操作,包括缩放到300x300像素,归一化,并从每个像素值中减去平均值(在这个例子中是(104.0, 177.0, 123.0)
)。这些步骤是根据模型在训练时使用的预处理步骤确定的。处理后的图像(即blob)被设置为网络的输入,通过调用net.forward()
函数,模型将对图像进行分析并返回检测结果。
得到的detections
包含了检测到的人脸的信息,包括每个人脸的位置和置信度。接下来,我们可以根据这些信息在原图像上绘制边界框,以可视化检测到的人脸。通过以上步骤,我们可以利用OpenCV和预训练的SSD模型有效地进行人脸检测。这个过程不仅快速,而且由于SSD模型的高精度,检测结果也非常有效。
接下来我们将根据检测到的人脸位置,在原图像上绘制边界框,并将处理后的图像显示出来。这一步是人脸检测流程中的重要环节,因为它直观地展示了模型的检测效果。以下是绘制边界框并显示图像的代码:
import numpy as np
# 循环遍历检测结果
for i in range(0, detections.shape[2]):
# 获取与当前检测相关的置信度(即概率)
confidence = detections[0, 0, i, 2]
# 仅处理置信度高于某个阈值的检测结果
if confidence > 0.5:
# 计算边界框的(x, y)坐标
box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
(startX, startY, endX, endY) = box.astype("int")
# 绘制边界框
cv2.rectangle(image, (startX, startY), (endX, endY), (0, 255, 0), 2)
# 构建要显示的标签:Face + 置信度
label = "Face: {:.2f}%".format(confidence * 100)
# 确定文本标签显示的位置(避免文本框超出图像边界)
y = startY - 10 if startY - 10 > 10 else startY + 10
# 在图像上绘制文本标签和背景矩形框
cv2.putText(image, label, (startX, y), cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 255, 0), 2)
# 显示最终的图像
cv2.imshow("Output", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
在这段代码中,我们首先遍历了detections
数组中的所有检测结果。每个检测结果包含了当前人脸检测的置信度和边界框的位置。我们通过confidence = detections[0, 0, i, 2]
获取置信度,并设定一个阈值(在这个例子中是0.5),仅当置信度高于这个阈值时,我们才处理这个检测结果。
对于每个有效的检测结果,我们通过box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
计算边界框的具体位置,并将其转换为整数类型。然后,我们使用cv2.rectangle
函数在原图像上绘制绿色的边界框。为了提供更多信息,我们还在边界框的上方绘制了当前检测的置信度,使用了cv2.putText
函数。
最后,我们使用cv2.imshow
函数显示加了边界框的图像,等待用户按键后关闭所有窗口。通过这些步骤,我们不仅完成了人脸的检测,还能直观地看到每个检测到的人脸及其置信度,从而评估模型的检测效果。代码运行后得到的结果如下图所示:
4. 系统界面效果
后面我们将实现一个人脸表情识别系统,以PySide6作为GUI库,提供了一套直观且友好的用户界面。下面,我将详细介绍各个主要界面的功能和设计。
(1)系统提供了基于SQLite的注册登录管理功能。用户在首次使用时需要通过注册界面进行注册,输入用户名和密码后,系统会将这些信息存储在SQLite数据库中。注册成功后,用户可以通过登录界面输入用户名和密码进行登录。这个设计可以确保系统的安全性,也为后续添加更多个性化功能提供了可能性。
(2)在主界面上,系统提供了支持图片、视频、实时摄像头和批量文件输入的功能。用户可以通过点击相应的按钮,选择要进行表情识别的图片或视频,或者启动摄像头进行实时检测。在进行检测时,系统会实时显示检测结果,并将检测记录存储在表格中。
(3)此外,系统还提供了一键更换pt模型的功能。用户可以通过点击界面上的"更换模型"按钮,选择不同训练好的模型进行检测。与此同时,资源包中附带的数据集也可以用于重新训练模型,以满足用户在不同场景下的检测需求。
(4)为了提供更个性化的使用体验,这里系统支持界面修改,用户可以自定义图标、文字等界面元素。例如,用户可以根据自己的喜好,选择不同风格的图标,也可以修改界面的文字描述。
下载链接
若您想获得博文中涉及的实现完整全部资源文件(包括测试图片、视频,py, UI文件,训练数据集、训练代码、界面代码等),这里已打包上传至博主的面包多平台,见可参考博客与视频,已将所有涉及的文件同时打包到里面,点击即可运行,完整文件截图如下:
完整资源中包含数据集及训练代码,环境配置与界面中文字、图片、logo等的修改方法请见视频,项目完整文件下载请见演示与介绍视频的简介处给出:➷➷➷
演示与介绍视频:https://www.bilibili.com/video/BV1fK421v7Rb/
在文件夹下的资源显示如下,下面的链接中也给出了Python的离线依赖包,读者可在正确安装Anaconda和Pycharm软件后,复制离线依赖包至项目目录下进行安装,另外有详细安装教程:(1)Pycharm软件安装教程;(2)Anaconda软件安装教程;(3)Python环境配置教程;
离线依赖安装教程:https://www.bilibili.com/video/BV1hv421C7g8/
离线依赖库下载链接:https://pan.baidu.com/s/1y6vqa9CtRmC72SQYPh1ZCg?pwd=33z5 (提取码:33z5)
5. 总结与展望
在本篇博客中,我们详细介绍了如何利用OpenCV和SSD(Single Shot MultiBox Detector)模型进行高效的人脸检测,这一步骤对于后续的人脸表情识别很是关键。通过对SSD模型的解读和示例代码的展示,我们演示了从加载预训练模型、图像预处理、到人脸检测和标注的整个流程并给出了代码实现。
未来的工作可能还包括探索其他深度学习模型和算法,如使用更加先进的神经网络架构,或者开发更加精细的图像预处理和增强技术。此外,随着硬件性能的提升和移动设备的普及,将这些高级人脸检测和表情识别技术部署到移动平台上,以实现实时的人机交互,也是一个值得关注的方向吧可能。
结束语
由于博主能力有限,博文中提及的方法即使经过试验,也难免会有疏漏之处。希望您能热心指出其中的错误,以便下次修改时能以一个更完美更严谨的样子,呈现在大家面前。同时如果有更好的实现方法也请您不吝赐教。
Liu W, Anguelov D, Erhan D, et al. SSD: Single shot multibox detector, European Conf[J]. Computer Vision (Springer, Cham, 2016), 21-37. ↩︎
Ekman P, Friesen W V. Constants across cultures in the face and emotion[J]. Journal of personality and social psychology, 1971, 17(2): 124. ↩︎
Howard A G, Zhu M, Chen B, et al. Mobilenets: Efficient convolutional neural networks for mobile vision applications[J]. arXiv preprint arXiv:1704.04861, 2017. ↩︎
Viola P, Jones M J. Robust real-time face detection[J]. International journal of computer vision, 2004, 57: 137-154. ↩︎