当前位置: 首页 > news >正文

Opencv之dilib库:表情识别

一、简介

        在计算机视觉领域,表情识别是一个既有趣又具有挑战性的任务。它在人机交互、情感分析、安防监控等众多领域都有着广泛的应用前景。本文将详细介绍如何使用 Python 中的 OpenCV 库和 Dlib 库来实现一个简单的实时表情识别系统。

二、实现原理

       表情识别系统主要基于面部关键点的检测与分析。Dlib 库提供了强大的面部关键点检测器,能够准确地定位出面部的 68 个关键点,这些关键点涵盖了眼睛、眉毛、鼻子、嘴巴等重要面部特征部位。通过计算这些关键点之间的距离比例,我们可以提取出能够表征不同表情的特征指标。

三、具体代码实现

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

上述代码导入了实现表情识别所需的各种库。OpenCV 用于图像处理和视频捕获;Numpy 用于数值计算;Dlib 用于面部检测和关键点定位;scikit - learn 的 euclidean_distances 函数用于计算欧几里得距离,以帮助我们计算面部关键点之间的距离;Pillow 库则用于在图像上添加中文文本。

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) / D

在MAR函数中,通过选取嘴巴周围的关键点(如嘴角、嘴唇中部等),计算它们之间的欧几里得距离,然后根据特定的公式计算出嘴巴长宽比。这个比值越大,通常表示嘴巴张开得越大,越有可能是大笑表情。

def 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/J

MJR函数则计算了嘴巴宽度与脸部宽度的比值。当这个比值超过一定阈值时,我们认为面部表情为微笑。这里通过比较嘴巴宽度和脸部特定宽度(两眼外角之间的宽度近似代表脸部宽度),来捕捉微笑时嘴巴相对脸部的变化特征。

def cv2AddChineseText(img, text, position, textColor = (255, 0, 0), textSize =50):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)

函数首先将 OpenCV 的 BGR 图像转换为 RGB 格式,然后使用 Pillow 库的 ImageDraw 和 ImageFont 在图像上指定位置绘制中文文本,最后再将图像转换回 BGR 格式,以便后续在 OpenCV 中使用。下面是主程序部分

detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
cap = cv2.VideoCapture(0)

这里使用 Dlib 的 get_frontal_face_detector 函数初始化面部检测器,加载预训练的 68 个面部关键点模型 shape_predictor_68_face_landmarks.dat 用于关键点预测,并通过 cv2.VideoCapture(0) 打开电脑默认摄像头。

while True:ret,frame = cap.read()faces = detector(frame, 0)for face in faces:shape = predictor(frame, face)shape = np.array([[p.x, p.y] for p in shape.parts()])mar = MAR(shape)mjr = MJR(shape)result = "正常"print("mar",mar,"\tmjr",mjr)if mar > 0.5:result = "大笑"elif mjr > 0.45:result = "微笑"mouthHULL = cv2.convexHull(shape[48:61])frame = cv2AddChineseText(frame, result,mouthHULL[0,0])cv2.drawContours(frame, [mouthHULL], -1, (0, 255, 0), 1)cv2.imshow("Frame",frame)if cv2.waitKey(1) == 27:break
cv2.destroyAllWindows()
cap.release()

在循环中,每读取一帧视频图像,首先使用面部检测器检测图像中的所有面部。对于每个检测到的面部,通过关键点预测器获取面部关键点坐标,并将其转换为 Numpy 数组形式以便后续计算。接着计算 MAR 和 MJR 值,并根据预设的阈值判断表情类别,将识别结果存储在 result 变量中。为了可视化效果,我们使用 cv2.convexHull 函数计算嘴巴区域的凸包,并使用 cv2.drawContours 函数将其绘制在图像上。同时,调用 cv2AddChineseText 函数在嘴巴凸包的起始位置添加识别出的表情文本。最后,通过 cv2.imshow 函数显示处理后的图像。当用户按下 Esc 键(键值为 27)时,循环结束,关闭所有窗口并释放摄像头资源。

运行结果

四、总结

通过上述步骤,我们成功构建了一个简单的实时表情识别系统,能够识别出大笑和微笑两种表情。然而,当前系统还存在一些局限性。例如,仅通过两个简单的特征指标来判断表情,可能无法准确识别更复杂多样的表情,如愤怒、悲伤、惊讶等。并且,阈值的设定是基于经验,可能在不同环境和个体上表现不稳定。


http://www.mrgr.cn/news/97396.html

相关文章:

  • 人大金仓数据库dum文件进行备份数据和恢复数据
  • 使用OpenSceneGraph生成3D数据格式文件
  • 某碰瓷国赛美赛,号称第三赛事的数模竞赛
  • HarmonyOS 基础组件和基础布局的介绍
  • LeetCode Hot100 刷题笔记(3)—— 链表
  • spring boot 整合redis
  • MySQL窗口函数学习
  • AI爬虫?爬!
  • [ctfshow web入门] 零基础版题解 目录(持续更新中)
  • Nginx-keepalived-高可用
  • Nginx 负载均衡案例配置
  • RAG 架构地基工程-Retrieval 模块的系统设计分享
  • 深度学习环境安装
  • 蓝桥杯嵌入式第十四届模拟二(PWM、USART)
  • K8S学习之基础七十四:部署在线书店bookinfo
  • Nginx 配置文件解析
  • 如何让 -webkit-slider-thumb 生效
  • c++项目 网络聊天服务器 实现;QPS测试
  • 【HFP】蓝牙HFP应用层核心技术研究
  • 算法基础—前缀和