跳到主要内容用 DeepFace 和 OpenCV 做实时情绪识别 | 极客日志PythonVScodeAI大前端
用 DeepFace 和 OpenCV 做实时情绪识别
结合 OpenCV 和 DeepFace 可以很快做出一个实时情绪识别原型:OpenCV 负责打开摄像头、读取视频帧、绘制人脸框和 FPS,DeepFace 通过 `DeepFace.analyze(frame, actions=['emotion'], enforce_detection=False)` 返回每张脸的主导情绪和置信度。代码里用滑动平均平滑 FPS,并在画面上直接标注结果。这个方案适合演示和原型验证,但对光照、遮挡和人脸角度比较敏感,落地时还要补异常处理和更稳的检测策略。

效果展示
自然的

开心的

伤心的

恐惧的

惊讶的

能做什么
这类情绪识别最直观的用法,还是围绕摄像头实时画面展开。它能把人脸框出来,再给出当前更像哪种情绪,适合做演示、交互原型,或者作为更复杂系统里的一个信号源。
我会把它看成'够快、够直接'的方案,而不是'足够可靠'的终局方案。心理健康、用户体验研究、互动娱乐、安全监控、教育培训、智能助手、疲劳驾驶预测,这些场景都能挂上去,但真正落地时,光有识别结果远远不够,环境光、人脸角度、遮挡和误判都会影响效果。
组成部分
1. 硬件
- 摄像头:内置摄像头或外接 USB 摄像头都可以,关键是画面要稳定,别指望低质量视频里跑出漂亮结果。
2. 依赖库
- OpenCV (
cv2):负责打开摄像头、读取视频帧、画框、写字。
- time:用来计算帧间间隔,顺手估一下 FPS。
- numpy (
np):这段代码里没有真正用上,但很多 OpenCV 项目都会带着它。
DeepFace:负责情绪分析,DeepFace.analyze() 是核心入口。3. 功能模块
- 视频捕捉与处理:
cv2.VideoCapture(0) 打开默认摄像头,循环读取每一帧。
- FPS 计算:通过前后两次时间戳差值算瞬时 FPS,再用滑动平均压一压抖动。
- 情绪分析:对每帧调用
DeepFace.analyze(frame, actions=['emotion'], enforce_detection=False),拿到人脸位置和主导情绪。
- 结果显示:用
cv2.rectangle() 和 cv2.putText() 把框和文字画回画面。
- 退出控制:按
q 结束循环。
代码思路
实现并不复杂:摄像头负责喂帧,DeepFace 负责识别,OpenCV 负责展示。难点不在流程,而在细节处理上,比如帧率别掉得太狠,没人脸时别直接崩掉,显示结果时尽量别把画面弄得太乱。
导入库
import cv2
import time
import numpy as np
from deepface import DeepFace
cv2 用于图像和视频处理,time 用于计算 FPS,numpy 这里没有直接参与逻辑,DeepFace 则提供情绪分析能力。
打开摄像头并初始化变量
cap = cv2.VideoCapture(0)
prev_time = time.time()
fps = 0
alpha = 0.9
0 表示默认摄像头。prev_time 记录上一次时间点,fps 保存平滑后的帧率,alpha 是滑动平均权重,数值越大,显示越稳,但响应也越慢。
主循环
while True:
ret, frame = cap.read()
if not ret:
break
cap.release()
cv2.destroyAllWindows()
循环里不断读取视频帧,失败就退出。实际项目里,资源释放一般会放在循环外面,这里原代码写法有点别扭,但不影响理解主流程。
FPS 计算
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
每帧计算一次时间差,再换算成瞬时帧率。直接显示瞬时值会抖得很厉害,所以再做一次平滑处理,读数会更像'当前体验',而不是'这一帧的噪声'。
情绪分析和标注
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)
这里的重点只有一个:enforce_detection=False。它让模型在没检测到明确人脸时也别直接报错,适合做实时视频流。代价是结果会更宽松,不能把它理解成'每一帧都很准'。
显示 FPS 和画面
cv2.putText(frame, f'FPS: {fps:.2f}', (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 255), 2)
cv2.imshow("Emotion Detection", frame)
画面左上角显示 FPS,窗口中展示带标注的视频流。这个部分很朴素,但对调试很有用,至少能看出程序是在跑,还是只是识别结果在'看起来正常'。
退出条件
if cv2.waitKey(1) & 0xFF == ord('q'):
break
按 q 退出。这个交互足够简单,也没必要再折腾成复杂菜单。
完整代码
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()
小结
这套实现的价值不在于'情绪识别有多神',而在于把 OpenCV 的视频流处理和 DeepFace 的分析能力接起来,快速跑出一个能看、能改、能继续往下搭的原型。要做成真正可用的系统,还得再补上更稳的检测策略、异常处理和场景约束。
相关免费在线工具
- RSA密钥对生成器
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
- Mermaid 预览与可视化编辑
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
- 随机西班牙地址生成器
随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online
- curl 转代码
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online