# 基于人脸关键点的多表情实时检测系统

基于人脸关键点的多表情实时检测系统

在计算机视觉领域,人脸表情识别技术已经取得了显著的进展。它不仅可以用于娱乐应用(如动态表情包生成),还能在心理健康监测、智能安防、人机交互等领域发挥重要作用。今天,我将分享一个基于人脸关键点的多表情实时检测系统,该系统能够通过摄像头实时识别微笑、大笑、哭泣和愤怒等多种表情。

1. 项目背景与动机

人脸表情是人类情感的重要外在表现形式。通过分析人脸的表情,我们可以更好地理解他人的情绪状态。传统的表情识别方法主要依赖于深度学习模型,这些模型虽然精度高,但计算复杂度较高,难以在资源受限的设备上实现实时检测。相比之下,基于人脸关键点的方法更加轻量级,通过分析关键点的位置关系来推断表情状态,适合在实时系统中应用。

本项目的目标是开发一个实时系统,能够通过摄像头捕捉人脸图像,并根据人脸关键点的位置关系判断当前的表情状态。我们将重点实现微笑、大笑、哭泣和愤怒这四种常见表情的检测。

2. 技术栈与工具

为了实现这个项目,我们使用了以下技术和工具:

  • Python:作为主要的开发语言,Python 提供了丰富的库支持,便于快速开发和调试。
  • OpenCV:用于图像处理和视频流操作,能够高效地读取摄像头数据并进行图像绘制。
  • dlib:提供了强大的人脸检测和关键点定位功能,是实现人脸关键点提取的核心工具。
  • scikit-learn:用于计算欧几里得距离,帮助我们分析关键点之间的空间关系。
  • Pillow:用于在图像上绘制中文文本,方便在实时视频中显示识别结果。

3. 关键技术实现

3.1 人脸检测与关键点提取

人脸检测是表情识别的第一步。我们使用 dlib 提供的 get_frontal_face_detector 方法来检测图像中的人脸区域。一旦检测到人脸,我们再利用 shape_predictor 模型提取人脸的 68 个关键点。这些关键点包括眼睛、眉毛、鼻子、嘴巴等部位的特征点,为后续的表情分析提供了基础数据。

detector = dlib.get_frontal_face_detector()  # 构造脸部位置检测器
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")  # 读取人脸关键点定位模型
faces = detector(frame, 0)  # 获取人脸
for face in faces:  # 循环遍历每一个人脸shape = predictor(frame, face)  # 获取关键点shape = np.array([[p.x, p.y] for p in shape.parts()])  # 将关键点转换为坐标(x,y)的形式

3.2 表情特征计算

为了判断不同表情,我们定义了多个特征指标,包括嘴宽比(MWR)、嘴高比(MHR)和眼睛宽高比(EAR)等。

  • 嘴高比(MHR):计算嘴巴的平均高度与嘴巴宽度的比值。嘴巴的高度通过关键点 50、51、52 与 58、57、56 的距离计算,嘴巴宽度通过关键点 48 和 54 的距离计算。当 MHR 超过一定阈值时,可能表示大笑。
  • 嘴宽比(MWR):计算嘴巴宽度与下颌宽度的比值。嘴巴宽度通过关键点 48 和 54 的距离计算,下颌宽度通过关键点 3 和 13 的距离计算。当 MWR 超过一定阈值时,可能表示微笑。
  • 眼睛宽高比(EAR):计算眼睛的宽高比,用于检测眼睛闭合程度。当 EAR 小于一定阈值时,可能表示眼睛闭合,进而推断出哭泣等表情。
def MAR(shape):A = euclidean_distances(shape[50].reshape(1, 2), shape[58].reshape(1, 2))B = euclidean_distances(shape[51].reshape(1, 2), shape[57].reshape(1, 2))C = euclidean_distances(shape[52].reshape(1, 2), shape[56].reshape(1, 2))D = euclidean_distances(shape[48].reshape(1, 2), shape[54].reshape(1, 2))return ((A + B + C) / 3) / Ddef MJR(shape):M = euclidean_distances(shape[48].reshape(1, 2), shape[54].reshape(1, 2))  # 嘴宽度J = euclidean_distances(shape[3].reshape(1, 2), shape[13].reshape(1, 2))  # 下颌宽度return M / Jdef EAR(shape):A = euclidean_distances(shape[37].reshape(1, 2), shape[41].reshape(1, 2))B = euclidean_distances(shape[38].reshape(1, 2), shape[40].reshape(1, 2))C = euclidean_distances(shape[36].reshape(1, 2), shape[39].reshape(1, 2))return (A + B) / (2.0 * C)

3.3 实时视频流处理

我们通过 OpenCV 的 VideoCapture 方法获取摄像头的实时视频流,并在每一帧图像上进行人脸检测和表情识别。识别结果会以中文文本的形式显示在视频窗口中,同时绘制嘴巴的凸包轮廓,以便直观地观察嘴巴的形状变化。

cap = cv2.VideoCapture(0)
while True:ret, frame = cap.read()if not ret:breakgray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)faces = detector(gray, 0)for face in faces:shape = predictor(gray, face)shape = np.array([[p.x, p.y] for p in shape.parts()])mar = MAR(shape)mjr = MJR(shape)ear = EAR(shape)result = "正常"if mar > 0.5:result = "大笑"elif mjr > 0.45:result = "微笑"elif ear < 0.2:  # 眼睛闭合,可能是在哭result = "哭"elif euclidean_distances(shape[19].reshape(1, 2), shape[24].reshape(1, 2)) < 20:  # 眉毛距离变小,可能是在愤怒result = "愤怒"print("MAR:", mar, "\tMJR:", mjr, "\tEAR:", ear, "\t表情:", result)mouthHull = cv2.convexHull(shape[48:61])frame = cv2AddChineseText(frame, result, (mouthHull[0, 0][0], mouthHull[0, 0][1] - 20))cv2.drawContours(frame, [mouthHull], -1, (0, 255, 0), 1)cv2.imshow("Frame", frame)if cv2.waitKey(1) == 27:  # 按ESC退出breakcv2.destroyAllWindows()
cap.release()

5. 总结

通过本项目,我们成功实现了一个基于人脸关键点的多表情实时检测系统。这个项目不仅展示了人脸关键点在表情识别中的应用,还为后续的扩展和优化提供了基础。希望这个项目能够为对人脸表情识别感兴趣的朋友提供一些参考和启发。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/900398.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在 Ubuntu24.04 LTS 上 Docker Compose 部署基于 Dify 重构二开的开源项目 Dify-Plus

一、安装环境信息说明 硬件资源&#xff08;GB 和 GiB 的主要区别在于它们的换算基数不同&#xff0c;GB 使用十进制&#xff0c;GiB 使用二进制&#xff0c;导致相同数值下 GiB 表示的容量略大于 GB&#xff1b;换算关系&#xff1a;1 GiB ≈ 1.07374 GB &#xff1b;1 GB ≈ …

SQL Server存储过程和触发器的使用

存储过程 &#xff08;1&#xff09;创建存储过程&#xff0c;使用Employees表中的员工人数来初始化一个局部变量&#xff0c;并调用这个存储过程。 1. Create PROCEDURE test number1 int output --输出参数&#xff0c;可以从程序中返回信息 2. As 3. begin 4. D…

子类是否能继承

继承 父类&#xff1a; 子 类 构造方法 非私有 不能继承 私有&#xff08;private&#xff09;不能继承 成员变量 非私有 能继承 私有&…

2025年【山东省安全员C证】考试题及山东省安全员C证考试内容

在当今建筑行业蓬勃发展的背景下&#xff0c;安全生产已成为企业生存与发展的基石。安全员作为施工现场安全管理的直接责任人&#xff0c;其专业能力和资质认证显得尤为重要。山东省安全员C证作为衡量安全员专业水平的重要标准&#xff0c;不仅关乎个人职业发展&#xff0c;更直…

Spring 中的 bean 生命周期

&#x1f331; 一、什么是 Bean 生命周期&#xff1f; 在 Spring 容器中&#xff0c;一个 Bean 从“创建 → 初始化 → 使用 → 销毁”&#xff0c;经历了完整的生命周期。 Spring 提供了 多个扩展点 让你可以在这些阶段做事情&#xff0c;比如注入资源、日志记录、连接资源、清…

Media streaming mental map

Media streaming is a huge topic with a bunch of scattered technologies, protocols, and formats. You may feel like hearing fragments without seeing the big picture. Let’s build that mental map together — here’s a high-level overview that connects everyt…

AIDD-深度学习 MetDeeCINE 破译代谢调控机制

深度学习 MetDeeCINE 破译代谢调控机制 目录 使用 FEP/REMD 和 DFT 方法准确预测药物多靶点绝对结合自由能的新途径。Scorpio 框架利用对比学习优化核苷酸序列表示&#xff0c;提升基因组分析效率&#xff0c;尤其在未知序列的分类和泛化能力上表现出色。LPM 模型整合多模态扰…

【2】搭建k8s集群系列(二进制)之安装etcd数据库集群

一、etcd服务架构 Etcd 是一个分布式键值存储系统&#xff0c;Kubernetes 使用 Etcd 进行数据存储&#xff0c;所以先 准备一个 Etcd 数据库&#xff0c;为解决 Etcd 单点故障&#xff0c;应采用集群方式部署&#xff0c;这里使用 3 台组建集群&#xff0c;可容忍 1 台机器故障…

fastGPT—前端开发获取api密钥调用机器人对话接口(HTML实现)

官网文档链接&#xff1a;OpenAPI 介绍 | FastGPT 首先按照文档说明创建api密钥 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-sca…

cpp自学 day19(多态)

一、基本概念 同一操作作用于不同的对象&#xff0c;产生不同的执行结果 &#x1f449; 就像「按F1键」&#xff1a;在Word弹出帮助文档&#xff0c;在PS弹出画笔设置&#xff0c;​同一个按键触发不同功能 &#xff08;1&#xff09;多态类型 类型实现方式绑定时机​静态多态…

Java 大视界 -- Java 大数据在航天遥测数据分析中的技术突破与应用(177)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

人脸考勤管理一体化系统(人脸识别系统,签到打卡)

人脸考勤管理一体化系统 项目介绍 本项目是基于Flask、SQLAlchemy、face_recognition库的人脸考勤管理一体化系统。 系统通过人脸识别技术实现员工考勤打卡、人脸信息采集、人脸模型训练等功能。 项目采用前后端分离的技术框架&#xff0c;基于Flask轻量级Web框架搭建后端服务…

单调栈学习C++

目录 一&#xff0c;每日温度 二&#xff0c;下一个更大的元素I 三&#xff0c;下一个更大的元素II 四&#xff0c;接雨水 小结&#xff1a; 单调栈是一种特殊的栈结构&#xff0c;里面的元素按照单调递增或者递减的顺序排列。常用于解决元素左边或者右边比它大或者小的问…

网络钓鱼攻击的威胁和执法部门的作用(第一部分)

在当今的数字世界中&#xff0c;网络犯罪分子不断开发新技术来利用个人、企业和政府机构。 最普遍和最具破坏性的网络犯罪形式之一是网络钓鱼——一种社会工程手段&#xff0c;用于欺骗人们提供敏感信息&#xff0c;例如登录凭据、财务数据和个人详细信息。 随着网络钓鱼攻击…

左值与右值,空间与数据

左值是空间&#xff0c;右值是数据 编程总是对“数据”&#xff0c;对"存放数据的空间"操作 a返回一个当前的数据&#xff0c;存放到一个临时空间中&#xff0c;自身的空间中的数据再进行运算 a直接对自身空间中的数据进行运算 其余知识&#xff1a; 1.变量名的意…

无人机飞行术语科普!

一、基础操作类 1. 炸机 指无人机意外坠毁或严重损坏&#xff08;如撞树、撞楼、失控摔机等&#xff09;。 例句&#xff1a;“今天风太大&#xff0c;差点炸机&#xff01;” 2. 一键放生 调侃某些情况下无人机失控飞丢&#xff0c;无法找回&#xff08;源自某些品牌…

模拟算法(一):一维数组模拟

目录 模拟的概念 例1&#xff1a;开关灯 算法思路&#xff1a; 代码如下&#xff1a; 输入输出&#xff1a; 例2&#xff1a;序列操作和查询 算法思路&#xff1a; 代码如下&#xff1a; 输入输出&#xff1a; 例3&#xff1a;数组折叠 算法思路&#xff1a; 代码如…

MySQL 基础入门

写在前面 关于MySQL的下载安装和其图形化软件Navicat的下载安装,网上已经有了很多的教程,这里就不再赘述了,本文主要是介绍了关于MySQL数据库的基础知识。 MySQL数据库 MySQL数据库基础 MySQL数据库概念 MySQL 数据库&#xff1a; 是一个关系型数据库管理系统 。 支持SQL语…

Qt中的多种输出方式,信号与槽的基本使用

完成Hello World可以通过很多控件实现 如采用编辑框来完成hello world 编辑框分为单行编辑框----QLineEdit 和多行编辑框---QTextEdit 采用单行编辑框&#xff0c;创建项目后&#xff0c;展开forms文件夹&#xff0c;双击ui文件进入 qt designer设计页面 找到line edit 拖到页…

英语表达年代和世纪

英语表达年代和世纪 1. Century (世纪)1.1. Start and end of centuries 2. Decade (年代)2.1. Usage 3. 英语表达年代和世纪4. HomeworkReferences XXX0 年代指 XXX0 年 - XXX9 年的连续 10 年&#xff0c;例如 1760 年代指 1760 年至 1769 年这连续 10 年。 XX 世纪 X0 年代…