情绪识别这玩意儿这几年用得越来越多,算不上多高深,但随手搭一个出来玩玩还挺有意思。这篇就聊聊怎么用 DeepFace 和 OpenCV 快速整一个实时情绪分析的小应用。

能用来干什么
说一些常见的落地场景,不一定都靠谱,但思路可以借鉴:
- 心理健康:长期监控情绪变化,辅助医生做评估,不过准确度这块还得打个问号。
- 用户体验研究:看用户试用产品时的表情,比问卷来得直接。
- 游戏和 VR:根据玩家情绪动态调整难度,沉浸感会强一些。
- 安防监控:在公共场所检测异常情绪,但容易有误报。
- 教育:老师能大致了解学生听课状态,上课走神一眼就能看出来?没那么神。
- 智能助手:设备感知到你不耐烦了,就少说废话。
- 疲劳驾驶:配合其他传感器,情绪也算一个维度。
用了哪些轮子
硬件就是普通摄像头,笔记本自带的就行。
软件方面:
- OpenCV:处理视频流、画框写字。
- DeepFace:封装了人脸分析和情绪预测,省得自己训模型。
- Python 标准库,比如
time算帧率。
代码怎么跑的
逻辑很简单:打开摄像头 → 抓帧 → 算 FPS → 调 DeepFace 分析 → 把结果画到画面上 → 按 q 退出。
初始化
先导库,然后打开默认摄像头。prev_time 记录上一帧时间,fps 是当前帧率,用指数移动平均(alpha 0.9)平滑一下,否则数字跳得没法看。
import cv2
import time
import numpy as np
from deepface import DeepFace
cap = cv2.VideoCapture(0)
prev_time = time.time()
fps = 0
alpha = 0.9
主循环与 FPS
每帧计算时间差,求瞬时 FPS 再平滑。写了个简单的滑动平均,alpha 越大曲线越稳,但响应会慢。
while True:
ret, frame = cap.read()
if not ret:
break
current_time = time.time()
delta_time = current_time - prev_time
prev_time = current_time
if delta_time > 0:
instant_fps = 1.0 / delta_time
fps = alpha * fps + (1 - alpha) * instant_fps
情绪分析
调用 DeepFace.analyze(),只跑情绪 (actions=['emotion']),关闭强制人脸检测(enforce_detection=False)防止没检测到人脸时程序崩溃。返回结果里取坐标和主导情绪,画个绿框,把情绪和置信度标在框上方。
try:
result = DeepFace.analyze(frame, actions=['emotion'], enforce_detection=False)
for face in result:
x, y, w, h = face['region']['x'], face['region']['y'], face['region']['w'], face['region']['h']
emotion = face['dominant_emotion']
confidence = face['emotion'][emotion]
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
text = f'{emotion} ({confidence:.2f}%)'
cv2.putText(frame, text, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
except Exception as e:
print("无法检测到人脸:", e)
显示和退出
左上角显示平滑后的 FPS,按 q 键退出,释放摄像头。
cv2.putText(frame, f'FPS: {fps:.2f}', (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 255), 2)
cv2.imshow("Emotion Detection", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
完整代码
把上面的片段拼起来就是一个完整的脚本:
import cv2
import time
import numpy as np
from deepface import DeepFace
cap = cv2.VideoCapture(0)
prev_time = time.time()
fps = 0
alpha = 0.9
while True:
ret, frame = cap.read()
if not ret:
break
current_time = time.time()
delta_time = current_time - prev_time
prev_time = current_time
if delta_time > 0:
instant_fps = 1.0 / delta_time
fps = alpha * fps + (1 - alpha) * instant_fps
try:
result = DeepFace.analyze(frame, actions=['emotion'], enforce_detection=False)
for face in result:
x, y, w, h = face['region']['x'], face['region']['y'], face['region']['w'], face['region']['h']
emotion = face['dominant_emotion']
confidence = face['emotion'][emotion]
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
text = f'{emotion} ({confidence:.2f}%)'
cv2.putText(frame, text, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
except Exception as e:
print("无法检测到人脸:", e)
cv2.putText(frame, f'FPS: {fps:.2f}', (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 255), 2)
cv2.imshow("Emotion Detection", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
效果图
下面是我自己跑出来的几张截图,DeepFace 对常见表情的识别还算稳定,不过真人情绪复杂,偶尔会识别成'neutral'。

自然状态

开心

伤心

恐惧

惊讶

收尾
核心就是 OpenCV 读视频 + DeepFace 做推理,几十行代码就能跑起来。如果想更实用,可以加个日志记录情绪变化,或者把结果推到后端做进一步分析。DeepFace 还能检测年龄、性别、种族,有兴趣可以自己改 actions 参数试试。


