计算机视觉(opencv)——嘴部表情检测

实时嘴部表情检测系统:从微笑到哭泣的智能识别


一、项目背景与意义

在计算机视觉领域中,人脸表情识别(Facial Expression Recognition, FER)是一项重要的研究方向。传统的表情识别通常依赖于整张人脸的特征提取,但在很多场景下,仅仅通过嘴部的形变就能准确反映一个人的情绪变化。例如:

  • 驾驶员监控系统中,嘴角上扬代表心情放松,嘴角下垂可能表示疲劳或情绪低落;

  • 课堂学习状态分析中,微笑往往代表专注或兴趣;

  • 智能客服系统中,用户的嘴型可以作为辅助情绪输入。

本文基于 dlib68 点人脸特征定位模型 ,结合 OpenCV 实现实时嘴部表情检测。我们将实现以下功能:

  • 检测人脸;

  • 获取嘴部关键点;

  • 计算嘴部形态参数(MAR 与 MJR);

  • 识别"正常"、"微笑"、"大笑";

  • 拓展实现"哭/悲伤"的检测。


二、算法核心原理

本项目的核心思想是通过计算嘴部的几何比例参数来判断表情。

(1)68 点特征模型

shape_predictor_68_face_landmarks.dat 模型由 dlib 提供,能检测出人脸上的 68 个关键点:

  • 1--17:下颌轮廓;

  • 18--27:眉毛;

  • 28--36:鼻子;

  • 37--48:眼睛;

  • 49--68:嘴部。

嘴部的关键点如下图所示:

复制代码
48 ------ 54:嘴部外轮廓的左右端点
50, 52, 56, 58:嘴部上下边缘点

这些点为我们计算嘴部的几何特征提供了基础。


(2)嘴部高宽比 MAR(Mouth Aspect Ratio)

嘴部高宽比定义为:

MAR = \\frac{(A + B + C) / 3}{D}

其中:

  • A、B、C 分别是上下嘴唇之间的三条垂直距离;

  • D 是嘴的水平宽度(48 到 54 号点)。

在代码中实现如下:

复制代码
def MAR(shape):
    A = euclidean_distances(np.array(shape[50]), np.array(shape[58]))
    B = euclidean_distances(np.array(shape[51]), np.array(shape[57]))
    C = euclidean_distances(np.array(shape[52]), np.array(shape[56]))
    D = euclidean_distances(np.array(shape[48]), np.array(shape[54]))
    return ((A + B + C) / 3) / D

当人嘴张开时,A、B、C 增大,因此 MAR 值上升

  • 正常闭嘴:MAR ≈ 0.2~0.35

  • 微笑:MAR ≈ 0.4

  • 大笑或张嘴:MAR > 0.5


(3)嘴宽与脸颊宽比 MJR(Mouth--Jaw Ratio)

微笑不仅会让嘴角上扬,还会拉宽嘴部。因此,我们再引入一个嘴宽/脸颊宽比:

MJR = \\frac{嘴宽度}{下颌宽度} = \\frac{d_{48,54}}{d_{3,13}}

复制代码
def MJR(shape):
    M = euclidean_distances(np.array(shape[48]), np.array(shape[54]))  # 嘴宽
    J = euclidean_distances(np.array(shape[3]), np.array(shape[13]))   # 下颌宽
    return M / J

一般规律为:

  • 正常:MJR < 0.38

  • 微笑:MJR ≈ 0.40~0.45

  • 大笑:MJR > 0.46


三、系统功能实现与代码解析

完整代码如下:

复制代码
import numpy as np
import dlib
import cv2
from sklearn.metrics.pairwise import euclidean_distances
from PIL import Image, ImageDraw, ImageFont

# ------------------- 计算嘴部参数函数 -------------------
def MAR(shape):
    A = euclidean_distances(np.array(shape[50]), np.array(shape[58]))
    B = euclidean_distances(np.array(shape[51]), np.array(shape[57]))
    C = euclidean_distances(np.array(shape[52]), np.array(shape[56]))
    D = euclidean_distances(np.array(shape[48]), np.array(shape[54]))
    return ((A + B + C) / 3) / D

def MJR(shape):
    M = euclidean_distances(np.array(shape[48]), np.array(shape[54]))
    J = euclidean_distances(np.array(shape[3]), np.array(shape[13]))
    return M / J

# ------------------- 中文输出函数 -------------------
def cv2AddChineseText(img, text, position, textColor=(0, 255, 0), textSize=30):
    if (isinstance(img, np.ndarray)):
        img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    draw = ImageDraw.Draw(img)
    fontStyle = ImageFont.truetype("simsun.ttc", textSize, encoding="utf-8")
    draw.text(position, text, textColor, font=fontStyle)
    return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)

# ------------------- 模型加载 -------------------
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")

cap = cv2.VideoCapture(0)
while True:
    ret, frame = cap.read()
    rects = detector(frame, 0)
    for rect in rects:
        shape = predictor(frame, rect)
        shape = np.matrix([[p.x, p.y] for p in shape.parts()])

        mar = MAR(shape)
        mjr = MJR(shape)

        result = "正常"
        if mar > 0.5:
            result = "大笑"
        elif mjr > 0.45:
            result = "微笑"

        # 绘制嘴部区域
        mouthHull = cv2.convexHull(shape[48:61])
        cv2.drawContours(frame, [mouthHull], -1, (0, 255, 0), 1)

        frame = cv2AddChineseText(frame, f"{result}", (50, 100))

        print(f"MAR: {mar:.3f}\tMJR: {mjr:.3f}\t表情: {result}")

    cv2.imshow("Frame", frame)
    if cv2.waitKey(1) == 27:  # ESC 退出
        break

cv2.destroyAllWindows()
cap.release()

四、运行效果与结果分析

系统运行后,会实时捕获摄像头图像,检测人脸并计算嘴部参数。程序每帧打印 MARMJR 的值,并在窗口中用中文显示当前表情类型。

表情 MAR 范围 MJR 范围 特征描述
正常 0.25--0.35 0.35--0.40 嘴闭合,嘴角自然
微笑 0.35--0.45 0.40--0.45 嘴角上扬,嘴部稍宽
大笑 >0.5 >0.46 嘴张开明显,上下唇分离

通过打印值可以自行调整阈值,以适应不同光线和人脸大小。


五、算法拓展:加入"哭/悲伤"检测

"哭"或"悲伤"表情通常伴随嘴角下垂、嘴部略张。为了检测此类表情,可以结合嘴角坐标高度差。

(1)嘴角高度差计算

设左嘴角点为 48,右嘴角点为 54,嘴部中心点为 51(上唇中点)。

如果嘴角比中点低很多,说明嘴角下垂,可视为"悲伤"或"哭泣"。

计算公式如下:

Sadness = \\frac{y_{48} + y_{54}}{2} - y_{51}

复制代码
def SAD(shape):
    left = shape[48][1, 0]
    right = shape[54][1, 0]
    top = shape[51][1, 0]
    return ((left + right) / 2) - top

一般规律:

  • 正常/微笑:SAD < 0;

  • 哭/悲伤:SAD > 2~5(像素差)。


(2)集成到主循环

加入悲伤检测逻辑:

复制代码
sad_value = SAD(shape)
if mar > 0.5:
    result = "大笑"
elif mjr > 0.45:
    result = "微笑"
elif sad_value > 3:
    result = "哭泣/悲伤"
else:
    result = "正常"

通过组合三个特征(MAR、MJR、SAD),可以区分更多情绪状态。


六、性能优化与注意事项

  1. 关键点模型加载时间

    • shape_predictor_68_face_landmarks.dat 文件较大(约 100MB),建议在程序开头加载一次;

    • 若需速度更快,可使用 shape_predictor_5_face_landmarks.dat 轻量模型,仅包含眼睛和嘴角特征。

  2. 摄像头分辨率

    • 默认分辨率可能较低(640×480),可以通过:

      复制代码
      cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
      cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)

      提升检测精度。

  3. 光照条件

    • 建议使用均匀光线,避免强背光;

    • 可加入 cv2.equalizeHist 对图像亮度进行均衡化。

  4. 多线程优化

    • 如果需要在实时监控系统中使用,可将检测与绘图分离至两个线程,提高帧率。

七、应用场景拓展

应用场景 功能说明
驾驶员监控 检测驾驶员微笑/打哈欠,判断疲劳或情绪
教育场景 检测学生表情变化,分析学习兴趣
智能客服 根据客户表情动态调整语气或推荐内容
互动娱乐 表情控制游戏角色(如微笑触发动作)
医疗康复 辅助评估患者面部肌肉恢复情况

八、未来方向

未来可结合深度学习模型(如 CNN + LSTM)实现更精准的多情绪识别,同时加入眼部、眉毛等特征,实现更全面的情绪判断。此外,还可采用面部 3D 重建或光流分析,识别更细微的表情动态。


九、总结

本文从嘴部几何特征出发,通过计算 MAR(高宽比)MJR(嘴宽比),实现了实时的"微笑"、"大笑"、"正常"表情识别,并扩展实现了"哭/悲伤"的检测。该系统具有以下优点:

  • 轻量级:无需深度学习模型;

  • 实时性强:CPU 即可流畅运行;

  • 可扩展性高:容易加入更多表情类型。

这种基于几何分析的嘴部表情识别方法,虽然精度略低于深度神经网络,但在嵌入式设备、实时监控、教学分析等场景中具备极高的实用价值。


完整检测公式汇总

参数 定义 功能
MAR 嘴部高度 / 宽度 检测张嘴程度
MJR 嘴宽 / 下颌宽 检测微笑程度
SAD 嘴角高度差 检测悲伤/哭泣

通过组合判断:

复制代码
if mar > 0.5:
    表情 = "大笑"
elif mjr > 0.45:
    表情 = "微笑"
elif sad_value > 3:
    表情 = "哭泣/悲伤"
else:
    表情 = "正常"
相关推荐
woshihonghonga6 小时前
Jupyter Notebook模块导入错误排查
人工智能
B站计算机毕业设计之家7 小时前
智慧交通项目:Python+PySide6 车辆检测系统 YOLOv8+OpenCV 自定义视频 自定义检测区域 (源码+文档)✅
大数据·python·opencv·yolo·智慧交通·交通·车流量
ting_zh8 小时前
PyTorch、TensorFlow、JAX 简介
人工智能·pytorch·tensorflow
数据与人工智能律师8 小时前
AI的法治迷宫:技术层、模型层、应用层的法律痛点
大数据·网络·人工智能·云计算·区块链
椒颜皮皮虾྅8 小时前
【DeploySharp 】基于DeploySharp 的深度学习模型部署测试平台:安装和使用流程
人工智能·深度学习·开源·c#·openvino
迈火9 小时前
PuLID_ComfyUI:ComfyUI中的图像生成强化插件
开发语言·人工智能·python·深度学习·计算机视觉·stable diffusion·语音识别
AI新兵10 小时前
AI大事记10:从对抗到创造——生成对抗网络 (GANs)
人工智能·神经网络·生成对抗网络
却道天凉_好个秋10 小时前
深度学习(十五):Dropout
人工智能·深度学习·dropout
你好~每一天11 小时前
2025 中小企业 AI 转型:核心岗技能 “怎么证、怎么用”?
人工智能·百度·数据挖掘·数据分析·职业·转行