使用 FER 库构建实时情绪检测系统

情绪识别技术在现代社会中变得越来越重要,它在人机交互、智能监控、教育评估等多个领域都有广泛应用。本文将介绍如何使用 FER (Facial Expression Recognition) 库构建一个实时情绪检测系统,通过摄像头实时捕捉和分析人脸情绪。

FER 库简介

FER 是一个基于深度神经网络实现的人脸表情识别库,它封装成了 PyPI 包,方便 Python 开发者集成。该库能够检测并识别七种基本情绪:愤怒、厌恶、恐惧、快乐、悲伤、惊讶和中性。

FER 库的主要特点包括:

  1. 易于使用:提供了简洁的 API,只需几行代码即可实现面部表情识别
  2. 高精度:基于深度学习技术,能够提供较为准确的表情识别结果
  3. 多平台支持:支持多种面部检测方法,可根据需求选择最适合的方法
  4. 视频处理:除了静态图像,还支持视频流的表情识别,适用于实时应用场景

环境准备

在开始之前,我们需要安装必要的依赖项。FER 库需要 Python 3.6 或更高版本,以及 OpenCV 和 TensorFlow。

1
2
3
4
5
6
7
8
# 安装 FER 库
pip install fer

# 安装必要的依赖(OpenCV 和 TensorFlow)
pip install tensorflow>=1.7 opencv-contrib-python==3.3.0.9

# 如果需要处理视频文件,还需要安装 ffmpeg 和 moviepy
pip install ffmpeg moviepy

基础用法

让我们先从一个简单的图像情绪识别示例开始:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from fer import FER
import cv2

# 读取图像
img = cv2.imread("person.jpg")

# 创建检测器实例
detector = FER()

# 检测情绪
results = detector.detect_emotions(img)
print(results)

# 输出示例:
# [{'box': [277, 90, 48, 63], 'emotions': {'angry': 0.02, 'disgust': 0.0, 'fear': 0.05, 'happy': 0.16, 'neutral': 0.09, 'sad': 0.27, 'surprise': 0.41}}]

# 获取最主要的情绪
emotion, score = detector.top_emotion(img)
print(f"主要情绪:{emotion}, 置信度:{score}")

实时情绪检测系统

现在让我们构建一个实时情绪检测系统,通过摄像头捕获视频流并实时分析人脸情绪。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import cv2
from fer import FER

def real_time_emotion_detection():
# 初始化摄像头
cap = cv2.VideoCapture(0)

# 创建情绪检测器,使用 MTCNN 提高检测精度
detector = FER(mtcnn=True)

print("实时情绪检测系统已启动,按 'q' 键退出")

while True:
# 读取摄像头帧
ret, frame = cap.read()

if not ret:
break

# 检测情绪
results = detector.detect_emotions(frame)

# 在图像上绘制检测结果
for result in results:
# 获取边界框坐标
x, y, w, h = result["box"]

# 获取情绪数据
emotions = result["emotions"]

# 找到置信度最高的情绪
dominant_emotion = max(emotions, key=emotions.get)
confidence = emotions[dominant_emotion]

# 绘制边界框
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)

# 在边界框上方显示情绪和置信度
text = f"{dominant_emotion}: {confidence:.2f}"
cv2.putText(frame, text, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX,
0.9, (0, 255, 0), 2)

# 显示结果
cv2.imshow('实时情绪检测', frame)

# 按 'q' 键退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break

# 释放资源
cap.release()
cv2.destroyAllWindows()

# 运行实时情绪检测系统
if __name__ == "__main__":
real_time_emotion_detection()

增强版情绪检测系统

为了提供更好的用户体验,我们可以创建一个增强版的情绪检测系统,它不仅显示实时情绪,还会统计一段时间内的情绪分布。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import cv2
import numpy as np
from fer import FER
from collections import deque
import matplotlib.pyplot as plt

class EnhancedEmotionDetector:
def __init__(self, max_history=100):
self.cap = cv2.VideoCapture(0)
self.detector = FER(mtcnn=True)
self.emotion_history = deque(maxlen=max_history)
self.emotions_list = ['angry', 'disgust', 'fear', 'happy', 'neutral', 'sad', 'surprise']

def run(self):
print("增强版情绪检测系统已启动,按 'q' 键退出")

while True:
ret, frame = self.cap.read()

if not ret:
break

# 检测情绪
results = self.detector.detect_emotions(frame)

# 处理检测结果
for result in results:
x, y, w, h = result["box"]
emotions = result["emotions"]

# 找到主导情绪
dominant_emotion = max(emotions, key=emotions.get)
confidence = emotions[dominant_emotion]

# 添加到历史记录
self.emotion_history.append(dominant_emotion)

# 绘制边界框和情绪信息
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
text = f"{dominant_emotion}: {confidence:.2f}"
cv2.putText(frame, text, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX,
0.9, (0, 255, 0), 2)

# 显示统计信息
if len(self.emotion_history) > 0:
self.display_statistics(frame)

cv2.imshow('增强版情绪检测系统', frame)

if cv2.waitKey(1) & 0xFF == ord('q'):
break

self.cleanup()

def display_statistics(self, frame):
if len(self.emotion_history) == 0:
return

# 计算情绪分布
emotion_counts = {emotion: 0 for emotion in self.emotions_list}
for emotion in self.emotion_history:
emotion_counts[emotion] += 1

total = len(self.emotion_history)
dominant_overall = max(emotion_counts, key=emotion_counts.get)

# 在图像上显示统计信息
cv2.putText(frame, f"主导情绪:{dominant_overall}", (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)
cv2.putText(frame, f"检测次数:{total}", (10, 60),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)

def cleanup(self):
self.cap.release()
cv2.destroyAllWindows()

# 运行增强版情绪检测系统
if __name__ == "__main__":
detector = EnhancedEmotionDetector()
detector.run()

视频文件情绪分析

除了实时摄像头检测,FER 库还支持对视频文件进行情绪分析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from fer import Video
from fer import FER

def analyze_video_emotions(video_filename):
# 创建视频分析器
video = Video(video_filename)

# 创建情绪检测器
detector = FER(mtcnn=True)

# 分析视频
raw_data = video.analyze(detector, display=True)

# 转换为 pandas DataFrame 便于分析
df = video.to_pandas(raw_data)

# 保存结果到 CSV 文件
df.to_csv("emotion_analysis.csv", index=False)

return df

# 使用示例
# df = analyze_video_emotions("sample_video.mp4")

应用场景

实时情绪检测系统在多个领域都有广泛的应用前景:

1. 人机交互

通过实时识别用户的面部表情,调整应用程序的行为或提供个性化反馈。

2. 市场营销

了解顾客对商品或广告的真实反应,优化营销策略。

3. 智能驾驶

监控驾驶员的疲劳和情绪状态,提高驾驶安全性。

4. 娱乐产业

创造更具沉浸感的互动体验,根据用户表情调整游戏或影视内容。

注意事项和局限性

尽管 FER 库提供了便捷的情绪识别功能,但在实际应用中仍需注意以下几点:

  1. 准确率限制:默认模型在 FER2013 数据集上的准确率约为 65%,对某些人群(如亚洲面孔、儿童)可能存在偏差。

  2. 光照和环境影响:在光线不足或变化剧烈的环境中,识别准确率会下降。

  3. 遮挡问题:当人脸被口罩、手等物体遮挡时,可能无法正确识别。

  4. 隐私考虑:在实际部署时需要考虑用户隐私保护问题。

总结

通过 FER 库,我们可以快速构建功能强大的实时情绪检测系统。该库提供了简单易用的 API,使得开发者能够专注于业务逻辑而不是底层实现细节。

虽然默认模型有一定的局限性,但对于原型开发和一般应用场景已经足够。如果需要更高的准确率,可以考虑使用自定义数据集重新训练模型。

情绪识别技术正处于快速发展阶段,随着深度学习技术的进步,未来的系统将更加准确和可靠。通过本文介绍的方法,你可以快速搭建自己的情绪检测系统,并在此基础上进行进一步的优化和扩展。


使用 FER 库构建实时情绪检测系统
https://bubao.github.io/posts/8ae7e6fb.html
作者
一念
发布于
2025年12月7日
许可协议