表情识别-情感分析-人脸识别(代码+教程)

news/2024/10/31 5:34:57/

表情识别

面部情绪识别(FER)是指根据面部表情识别和分类人类情绪的过程。通过分析面部特征和模式,机器可以对一个人的情绪状态作出有根据的推断。这个面部识别的子领域高度跨学科,涉及计算机视觉、机器学习和心理学等领域的知识。

inference result example of facial face emotion recognition system for happy and neutral multiple face recognition detection

应用领域

以下是一些关键领域,其中这项技术可能有所帮助:

社交和内容创作平台:

根据情感反馈个性化用户体验。
自适应学习系统根据学习者的情绪状态调整内容,提供更具针对性的建议。

医疗研究:

监测患者是否存在抑郁、焦虑或其他情绪障碍的迹象。
协助治疗师在治疗过程中跟踪患者的进展或反应。
实时监测应激水平。

驾驶员安全机制:

监测驾驶员是否出现疲劳、注意力分散、压力或昏昏欲睡的迹象。

营销和市场研究:

实时分析观众对广告的反应。
根据观众的情绪状态定制广告内容。
产品测试和反馈。

安全和监控:

在拥挤区域检测可疑或异常行为。
分析公共事件中人群的反应,以确保安全。

构建面部情绪识别系统

本节深入探讨构建面部情绪识别系统的复杂性。我们首先探讨一个专门为面部情绪识别设计的数据集,确保我们的模型有稳健的基础。接下来,我们将介绍一种自定义的VGG13模型架构,该架构以其在分类任务中的效率和准确性而闻名,并阐明其与我们情绪识别目标的相关性。

最后,我们花费一些时间在实验结果部分,提供全面的评估,阐明系统的性能指标及其潜在应用。

面部情绪识别数据集(FER +)

FER + 数据集是原始面部表情识别(FER)数据集的一个重要扩展。为了改进原始数据集的局限性,FER + 提供了更精细和细致的面部表情标签。虽然原始FER数据集将面部表情分类为六种基本情绪——快乐、悲伤、愤怒、惊讶、恐惧和厌恶——但FER + 根据这一基础更进一步引入了两个额外的类别:中性和蔑视。

Different expressions from a facial expression recognition dataset.

用于人脸检测的RFB-320

Single Shot Multibox Detector (SSD)模型 在识别情绪之前,需要在输入帧中检测人脸。为此,使用了超轻量级人脸检测模型RFB-320。它是一种针对边缘计算设备进行优化的创新人脸检测模型。该模型采用了改进的感受野块(RFB)模块,在不增加计算负担的情况下有效地捕捉多尺度的上下文信息。它在多样化的WIDER FACE数据集上进行训练,并针对320×240的输入分辨率进行优化,具有出色的效率平衡,计算速度为0.2106 GFLOPs,参数量仅为0.3004百万个。该模型基于PyTorch框架开发,取得了令人称赞的平均精度(mAP)为84.78%,在资源受限环境中成为高效人脸检测的强大解决方案。在此实现中,RFB-320 SSD模型以Caffe格式使用。

ssd single shot multibox detector model architecture

自定义的VGG13模型架构

情绪识别分类模型采用了定制的VGG13架构,专为64×64灰度图像设计。它使用具有最大池化和dropout的卷积层将图像分类为八个情绪类别,以防止过拟合。该架构开始于两个具有64个卷积核的卷积层,然后是最大池化和25%的dropout。额外的卷积层捕捉复杂的特征,两个具有1024个节点的密集层聚合信息,然后是50%的dropout。一个softmax输出层预测情绪类别。

customized vgg13 model architecture for facial emotion recognition that classifies images into eight emotion classes using convolutional and max pooling layers.

让我们编写一些代码来实现这个系统。

首先,需要初始化一些重要的参数。


image_mean = np.array([127, 127, 127])
image_std = 128.0
iou_threshold = 0.3
center_variance = 0.1
size_variance = 0.2
min_boxes = [[10.0, 16.0, 24.0], [32.0, 48.0], [64.0, 96.0], [128.0, 192.0, 256.0]
]
strides = [8.0, 16.0, 32.0, 64.0]
threshold = 0.5

image_mean: 在RGB通道上进行图像归一化的均值。
image_std: 图像归一化的标准差。
iou_threshold: 确定边界框匹配的交并比(IoU)度量的阈值。
center_variance: 预测的边界框中心坐标的缩放因子。
size_variance: 预测的边界框尺寸的缩放因子。
min_boxes: 不同尺寸对象的最小边界框尺寸。
strides: 根据图像大小控制特征图的尺度。
threshold: 目标检测的置信度阈值。


def define_img_size(image_size):shrinkage_list = []feature_map_w_h_list = []for size in image_size:feature_map = [int(ceil(size / stride)) for stride in strides]feature_map_w_h_list.append(feature_map)for i in range(0, len(image_size)):shrinkage_list.append(strides)priors = generate_priors(feature_map_w_h_list, shrinkage_list, image_size, min_boxes)return priors

上述的 define_img_size 函数旨在为目标检测任务生成先验边界框(priors)。该函数以 image_size 参数作为输入,根据提供的图像尺寸和一组预定义的步长值计算特征图的尺寸。这些特征图的尺寸反映了卷积神经网络(CNN)层对不同输入图像尺度的期望输出尺寸。实质上,SSD中的先验边界框提供了一种高效的方法,可以在网络的单次前向传递中同时预测多个边界框及其关联的类别得分,从而实现实时目标检测。

def FER_live_cam():emotion_dict = {0: 'neutral', 1: 'happiness', 2: 'surprise', 3: 'sadness',4: 'anger', 5: 'disgust', 6: 'fear'}# cap = cv2.VideoCapture('video1.mp4')cap = cv2.VideoCapture(0)frame_width = int(cap.get(3))frame_height = int(cap.get(4))size = (frame_width, frame_height)result = cv2.VideoWriter('result.avi', cv2.VideoWriter_fourcc(*'MJPG'),10, size)# Read ONNX modelmodel = 'onnx_model.onnx'model = cv2.dnn.readNetFromONNX('emotion-ferplus-8.onnx')# Read the Caffe face detector.model_path = 'RFB-320/RFB-320.caffemodel'proto_path = 'RFB-320/RFB-320.prototxt'net = dnn.readNetFromCaffe(proto_path, model_path)input_size = [320, 240]width = input_size[0]height = input_size[1]priors = define_img_size(input_size)while cap.isOpened():ret, frame = cap.read()if ret:img_ori = frame#print("frame size: ", frame.shape)rect = cv2.resize(img_ori, (width, height))rect = cv2.cvtColor(rect, cv2.COLOR_BGR2RGB)net.setInput(dnn.blobFromImage(rect, 1 / image_std, (width, height), 127))start_time = time.time()boxes, scores = net.forward(["boxes", "scores"])boxes = np.expand_dims(np.reshape(boxes, (-1, 4)), axis=0)scores = np.expand_dims(np.reshape(scores, (-1, 2)), axis=0)boxes = convert_locations_to_boxes(boxes, priors, center_variance, size_variance)boxes = center_form_to_corner_form(boxes)boxes, labels, probs = predict(img_ori.shape[1], img_ori.shape[0], scores, boxes, threshold)gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)for (x1, y1, x2, y2) in boxes:w = x2 - x1h = y2 - y1cv2.rectangle(frame, (x1,y1), (x2, y2), (255,0,0), 2)resize_frame = cv2.resize(gray[y1:y1 + h, x1:x1 + w], (64, 64))resize_frame = resize_frame.reshape(1, 1, 64, 64)model.setInput(resize_frame)output = model.forward()end_time = time.time()fps = 1 / (end_time - start_time)print(f"FPS: {fps:.1f}")pred = emotion_dict[list(output[0]).index(max(output[0]))]cv2.rectangle(img_ori, (x1, y1), (x2, y2), (0, 255, 0), 2,lineType=cv2.LINE_AA)cv2.putText(frame, pred, (x1, y1), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2,lineType=cv2.LINE_AA)result.write(frame)cv2.imshow('frame', frame)if cv2.waitKey(1) & 0xFF == ord('q'):breakelse:breakcap.release()result.release()cv2.destroyAllWindows()

FER_live_cam() 函数对视频帧进行实时的面部情绪识别。首先,它设置了一个字典 emotion_dict,将数字情绪类别索引映射到可读的情绪标签。视频源被初始化,尽管也可以使用网络摄像头输入。该函数还初始化了一个输出视频写入器,用于保存带有情绪注释的处理过的帧。主要的情绪预测模型以ONNX格式保存,在使用OpenCV DNN的 readNetFromONNX 方法读取并与以Caffe格式保存的RFB-30 SSD人脸检测模型一起加载。在逐帧处理视频时,人脸检测模型通过边界框识别出人脸。

检测到的人脸在输入情绪识别模型之前经过预处理,包括调整大小和转换为灰度图像。通过从模型的输出分数中选择最大值确定识别出的情绪,并使用 emotion_dict 将其映射到标签。然后,在检测到的人脸周围添加矩形框和情绪标签,将帧保存到输出视频文件中,并实时显示。用户可以通过按下 ‘q’ 键停止视频显示。一旦视频处理完成或中断,资源如视频捕获和写入器将被释放,并关闭任何打开的窗口。值得注意的是,该函数引用了一些在其作用域内未定义的变量和辅助函数,这表明它们是整个代码库的一部分。

推理结果

inference result example of facial face emotion recognition system for happy face

inference result example of facial face emotion recognition system for angry face
框和情绪标签,将帧保存到输出视频文件中,并实时显示。用户可以通过按下 ‘q’ 键停止视频显示。一旦视频处理完成或中断,资源如视频捕获和写入器将被释放,并关闭任何打开的窗口。值得注意的是,该函数引用了一些在其作用域内未定义的变量和辅助函数,这表明它们是整个代码库的一部分。

写在最后

论文辅导,代码获取,作业辅助等联系我扣扣1309399183

http://www.ppmy.cn/news/1102719.html

相关文章

前端选择器:掌握未来Web开发的关键技术

引言 随着Web技术的不断发展,前端选择器已经成为现代Web开发中不可或缺的一部分。它们允许开发者以更加灵活和高效的方式操作DOM(文档对象模型),从而实现复杂的交互效果。在本文中,我们将深入探讨前端选择器的各种类型…

Java输入-a,-b,geek,-c,888,-d,[hello,world]字符之后,如何将[hello,world]这个不分开

Java输入-a,-b,geek,-c,888,-d,[hello,world]字符之后,如何将[hello,world]这个不分开? 你可以使用命令行参数解析库来处理Java输入中的各个参数。在这种情况下,你可以使用Apache Commons CLI库来解析命令行参数。以下是一个示例代码片段&am…

Linux 中的 chown 命令及示例

操作系统中的不同用户拥有所有权和权限,以确保文件的安全并限制谁可以修改文件的内容。在Linux中,有不同的用户使用系统: Root用户: 它是超级用户,可以访问我们系统中的所有目录和文件,并且可以执行任何操作。需要注意的重要一点是,只有 root 用户可以更改不属于他们的…

严选算法模型质量保障

在算法模型整个生命周期**(算法模型生命周期:初始训练数据 --> 模型训练 --> 模型评估 --> 模型预估 --> 训练数据)**中,任何环节的问题引入都可能导致算法模型质量问题。所以我们在做模型质量保障的过程中&#xff0…

【算法与数据结构】98、LeetCode验证二叉搜索树

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;注意不要落入下面你的陷阱&#xff0c;笔者本来想左节点键值<中间节点键值<右节点键值即可&…

《向量数据库指南》——向量数据库的底层原理是什么?

向量数据库的底层实现原理可以根据具体的数据库系统和索引方法而有所不同。不同的向量数据库可能使用不同的数据结构和算法来支持高效的向量存储和相似性搜索。以下是一些常见的底层实现原理和概念: 1、向量存储: 数据结构:向量数据库通常使用数据结构来存储向量数据。这些数…

Day61:代码随想录结束打卡~

大体感受 为期60的算法训练营结束了&#xff0c;这钱其实挺值的&#xff0c;人就是这样&#xff0c;一旦你有点付出才会懂得珍惜。 最大的收获就是见识到了人有决心有多可怕&#xff0c;这60天如果让我自己刷&#xff0c;其实根本坚持不了几天&#xff0c;但是现在证明我确实坚…

【Docker】Linux下Docker 部署一个SpringBoot项目的完整流程(通俗易懂,简单上手!!)

目录 首先在Linux系统下安装 Docker 和 Docker Compose 1、安装Docker 2、将当前用户添加到 Docker 用户组 3、安装 Docker Compose 4、验证安装 部署SpringBoot项目 1、安装 Docker 和 Docker Compose 2、编写 Dockerfile 3、构建 Docker 镜像 4、启动容器 5、查看容…