opencv学习:基于计算机视觉的表情识别系统

简介

        基于计算机视觉的表情识别系统,该系统能够从视频流中实时检测人脸,并识别出两种基本表情:大笑和微笑。实验通过分析人脸关键点来计算表情特征指标,从而判断表情类型。

原理

基于以下原理进行:

  1. 人脸检测:使用dlib库的get_frontal_face_detector函数检测视频中的人脸。
  2. 特征点预测:使用dlib库的shape_predictor函数预测人脸的68个关键点。
  3. 表情特征计算
    • 嘴巴张开程度(MAR):通过计算嘴巴周围特定点之间的欧几里得距离来衡量嘴巴的张开程度。
      • 计算上下嘴唇的距离
      • 计算嘴唇的长度
    • 嘴巴宽度与脸部宽度的比例(MJR):通过比较嘴巴宽度和脸部宽度的比例来识别微笑表情。
  4. 表情判断:根据计算出的特征指标,结合预设的阈值判断表情类型。

代码步骤:

1.导入必要的库:

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

2.定义MAR函数:

        函数计算嘴巴张开的程度(MAR),通过计算嘴巴周围特定点之间的距离。

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

3.定义MJR函数:

        函数计算嘴巴宽度与脸部宽度的比例(MJR),用于判断微笑的程度。

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

4.定义cv2addchinese函数:

        检查图像类型并转换:

def cv2addchinese(img, text, position, textColor=255, textSize=30):
    if isinstance(img, np.ndarray):
        if len(img.shape) == 2:  # 灰度图像
            img_pil = Image.fromarray(img)
        else:  # 彩色图像
            img_pil = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    else:
        raise ValueError("img must be a numpy array")

        创建了一个 ImageDraw 对象用于在PIL图像上绘制,加载了一个中文字体文件,在指定位置绘制文本。

    draw = ImageDraw.Draw(img_pil)
    fontstyle = ImageFont.truetype("simsun.ttc", textSize, encoding="utf-8")
    draw.text(position, text, font=fontstyle, fill=textColor)

        将PIL图像转换回OpenCV图像,如果原图像是灰度图,直接转换即可;如果是彩色图,则需要从RGB色彩空间转换回BGR色彩空间。

    if len(img.shape) == 2:  # 灰度图像
        img_cv2 = np.array(img_pil, dtype=np.uint8)
    else:  # 彩色图像
        img_cv2 = cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)
    return img_cv2

5.初始化人脸检测器和特征点预测器:

detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
cap = cv2.VideoCapture('xiao.mp4')

6.读取视频帧并检测人脸:

while True:
    ret, image = cap.read()
    faces = detector(image, 0)
    for face in faces:
        #获取特征点
        shape = predictor(image, face)
        #将 predictor 返回的特征点横坐标与纵坐标转换为NumPy数组
        shape = np.array([[p.x, p.y] for p in shape.parts()])

7.计算表情指标并绘制结果:

        根据MAR和MJR的值来判断表情类型

        mar = MAR(shape)
        mjr = MJR(shape)
        result = '正常'
        print("mar", mar, "\tmjr", mjr)
        if mar > 0.5:
            result = "大笑"
        elif mjr > 0.45:
            result = "微笑"

        #计算嘴巴的凸包
        mouth = cv2.convexHull(shape[48:61])
        #在图像上添加表情文本
        image = cv2addchinese(image, result, mouth[0,0])
        #绘制嘴巴轮廓
        cv2.drawContours(image, [mouth], -1, (0, 255, 0), 1)
    cv2.imshow('frame', image)
    key = cv2.waitKey(60)
    if key == 27:
        break

运行结果

完整代码

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


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


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


def cv2addchinese(img, text, position, textColor=255, textSize=30):
    if isinstance(img, np.ndarray):
        if len(img.shape) == 2:  # 灰度图像
            img_pil = Image.fromarray(img)
        else:  # 彩色图像
            img_pil = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    else:
        raise ValueError("img must be a numpy array")

    draw = ImageDraw.Draw(img_pil)
    fontstyle = ImageFont.truetype("simsun.ttc", textSize, encoding="utf-8")
    draw.text(position, text, font=fontstyle, fill=textColor)

    # 将PIL图像转换回OpenCV图像
    if len(img.shape) == 2:  # 灰度图像
        img_cv2 = np.array(img_pil, dtype=np.uint8)
    else:  # 彩色图像
        img_cv2 = cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)

    return img_cv2


detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
cap = cv2.VideoCapture('xiao.mp4')

while True:
    ret, image = cap.read()
    faces = detector(image, 0)
    for face in faces:
        shape = predictor(image, 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 = "微笑"

        mouth = cv2.convexHull(shape[48:61])

        image = cv2addchinese(image, result, mouth[0,0])
        cv2.drawContours(image, [mouth], -1, (0, 255, 0), 1)
    cv2.imshow('frame', image)
    key = cv2.waitKey(60)
    if key == 27:
        break

改进方法:

  1. 提高特征点预测的稳定性:考虑使用更先进的特征点预测模型。
  2. 优化表情识别算法:使用深度学习模型来提高表情识别的准确性。
  3. 改进阈值设置:根据实际应用场景调整MAR和MJR的阈值,以提高识别准确率。
  4. 增强系统的鲁棒性:通过算法优化,提高系统在不同光照和表情变化下的鲁棒性。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Transformer(Vit+注意力机制)

文献基本信息: Encoder-Decoder: Transformer的结构: 输入编码器解码器输出 Transformer的工作流程: 获取输入句子的每一个单词的表示向量X,X由单词的embedding(embedding是一种将高维特征映射到低维的技…

机器学习中的图像处理与计算机视觉

引言 在现代计算机科学中,图像处理和计算机视觉已成为最活跃的研究领域之一,这得益于机器学习和深度学习的发展。本文将深入探讨图像处理与计算机视觉的基础概念、常见应用、关键技术、常用工具,以及在这些领域中的代码示例。通过本篇文章&a…

约80%的巴西消费者热捧跨境电商平台Shopee

巴西作为南美洲最大的经济体,拥有庞大的消费群体和日益增长的消费需求。随着互联网的普及和电子商务的快速发展,巴西消费者对海外商品的兴趣日益浓厚。他们渴望获得更多元化的商品选择,尤其是那些在国内难以找到的特色商品或国际知名品牌。这…

Python3 接口自动化测试,HTTPS下载文件(GET方法和POST方法)

Python3 接口自动化测试,HTTPS下载文件(GET方法和POST方法) requests-pkcs12 PyPI python中如何使用requests模块下载文件并获取进度提示 1、GET方法 1.1、调用 # 下载客户端(GET)def download_client_get(self, header_all):try:url = self.host + "/xxx/v1/xxx-mod…

DBdoctor推出无Agent轻量级纳管解决方案

目录 背景 DBdoctor推出无Agent轻量级纳管解决方案 方案优势: 实例纳管方式: 无Agent纳管可体验哪些功能? 1.全量SQL审核功能 2.实例巡检功能 3.性能洞察功能 4.基础监控功能 总结 背景 在数字化时代,数据库作为信息系…

前端拦截302重定向

背景: 根据业务场景需要拦截302做后续的逻辑处理 尝试一: : axios拦截 、、、、、async created() {// 获取302请求返回的location后手动修改video的src路径let targetSrc;try {await axios.get(this.video).then((res) > {const { headers, status } res;const { locat…

unity 屏幕波动反馈打击效果(附资源下载)

unity 屏幕波动反馈打击效果 一枪打出去整个屏幕都回波动的效果反馈。 知识点: 1、动画事件 2、屏幕后处理 效果如图:(波动速度浮动都可调整) 附件下载

[C#][winform]基于yolov8的DMS驾驶员抽烟打电话喝水吃东西检测系统C#源码+onnx模型+评估指标曲线+精美GUI界面

【重要说明】 该系统以opencvsharp作图像处理,onnxruntime做推理引擎,使用CPU进行推理,适合有显卡或者没有显卡windows x64系统均可,不支持macOS和Linux系统,不支持x86的windows操作系统。由于采用CPU推理,要比GPU慢。…

EWM 库存盘点

目录 1 业务流程图 2 后台配置 & 主数据 3 业务操作 1 流程图 2 后台配置 & 主数据 仓库活动区域设置 SCM Extended Warehouse Management -> Extended Warehouse Management -> Internal Warehouse Processes -> Physical Inventory -> Physical-Inv…

k8s-pod详解

Pod生命周期 我们一般将pod对象从创建至终的这段时间范围称为pod的生命周期,它主要包含下面的过程 pod创建过程 运行初始化容器(init container)过程 运行主容器(main container) 容器启动后钩子(post st…

C语言【调试】(个人笔记版)

调试 前言一、Bug二、调试工具1.DeBug2.Release 三、调试快捷键1、断点 四、调试时查看程序的当前信息1、查看临时变量2、查看内存3、查看调用堆栈、汇编、寄存器 总结 前言 这篇文章大都是我的个人笔记: 调试在日常程序设计中是很重要的。调试说白了就是为了解决代…

zookeeper客户端

启动单机版的zookeeper 配置Maven环境 (1) IDEA自带maven (2) 更新Maven库镜像地址: ① 拷贝D:\Program Files\JetBrains\IntelliJ IDEA 2018.3.5\plugins\maven\lib\maven3\conf\settings.xml [IntelliJ的安装目录]到 C:/用户/username/.m2 (如果.m2文件不存在&…

大话哈希冲突

Map是很常用的数据结构, 而哈希表是 HashMap 等集合的底层实现之一,它通过将键的哈希值映射到数组中的位置来存储键值对。哈希冲突 (Hash Collision) 是指在使用哈希函数将数据映射到有限大小的哈希表时,不同的数据项被映射到了同一个哈希表位置上。 一…

【C++】拆分详解 - stack和queue

文章目录 一、stack的介绍和使用1. 简介2. 使用3. 模拟实现 二、queue的介绍和使用1. 简介2. 使用3. 模拟实现 三、容器适配器1. 简介2. STL标准库中的使用 四、deque(了解)1. 简介2. 底层原理2.1 底层空间2.2 模拟访问元素2.3 迭代器2.4 STL源码片段摘要…

高清无水印推文视频素材下载网站推荐

在制作抖音短视频时,选择合适的视频素材至关重要。想知道哪里可以下载热门的推文视频素材吗?别担心,我为你整理了六个高品质的视频素材网站,让我们一起来看看吧! 蛙学网 首先介绍的是蛙学网,作为国内知名的…

期权懂|股票下跌时可以使用期权止损吗?

本期让我懂 你就懂的期权懂带大家来了解,股票下跌时可以使用期权止损吗?有兴趣的朋友可以看一下。期权小懂每日分享期权知识,帮助期权新手及时有效地掌握即市趋势与新资讯! 股票下跌时可以使用期权止损吗? 在股市中&am…

Oracle 使用位图索引 Cost降低200倍! 探讨位图索引的利与弊

一.简介 位图索引(Bitmap Index) 是 Oracle 数据库中一种特殊类型的索引,适用于低基数(Low Cardinality)列,即那些列中可选值相对较少的情况下使用。它与常规的 B-tree 索引不同,位图索引通过位…

MybatisPlus入门教程及实现基础的增删改查

此篇博客主要针对于有开发基础的朋友学习~ 首先提几个问题: 1、什么是Mybatis? 2、什么是MybatisPlus? 3、Mybatis和MybatisPlus又有什么区别呢? 问题1:Mybatis是一个持久层的框架,我们通过配置mapper.xm…

Linux 外设驱动 应用 2 KEY 按键实验

2 按键 2.1 按键介绍 按键是指轻触式按键开关,也称之为轻触开关。按键开关是一种电子开关,属于电子元器件类,最早出现在日本,称之为:敏感型开关,使用时以满足操作力的条件向开关操作方向施压开关功能闭合…

RabbitMQ系列学习笔记(三)--工作队列模式

文章目录 一、工作队列模式原理二、工作队列模式实战1、抽取工具类2、消费者代码3、生产者代码4、查看运行结果 本文参考 尚硅谷RabbitMQ教程丨快速掌握MQ消息中间件rabbitmq RabbitMQ 详解 Centos7环境安装Erlang、RabbitMQ详细过程(配图) 一、工作队列模式原理 与简单模式相…