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

《OpenCV》——dlib(人脸应用实例)

文章目录

    • dlib库
    • dlib库——人脸应用实例——表情识别
    • dlib库——人脸应用实例——疲劳检测

dlib库

dlib库的基础用法介绍可以参考这篇文章:https://blog.csdn.net/lou0720/article/details/145968062?spm=1011.2415.3001.5331,故此这篇文章只介绍dlib的人脸应用实例。

dlib库——人脸应用实例——表情识别

在这里插入图片描述
代码:

import numpy as np
import cv2
import dlib
from sklearn.metrics.pairwise import euclidean_distances
from PIL import Image, ImageDraw, ImageFontdef cv2AddChineseText(img, text, position, textColor=(0, 255, 0), textSize=20):""" 向图片中添加中文 """# 判断输入的 img 是否为 OpenCV 格式的图片(即 numpy.ndarray 类型)if isinstance(img, np.ndarray):# 如果是 OpenCV 格式,将其从 BGR 颜色空间转换为 RGB 颜色空间,# 因为 PIL 库使用 RGB 颜色空间,而 OpenCV 使用 BGR 颜色空间img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))# 在 img 图片上创建一个绘图对象,用于后续绘制文本draw = ImageDraw.Draw(img)# 定义字体的格式,使用 "simsun.ttc" 字体文件,指定字体大小为 textSize,# 并设置编码为 UTF - 8 以支持中文显示fontStyle = ImageFont.truetype("simsun.ttc", textSize, encoding="utf-8")# 在指定的 position 位置,使用指定的 textColor 颜色和 fontStyle 字体绘制文本draw.text(position, text, textColor, font=fontStyle)# 将绘制好文本的 PIL 图片转换回 numpy.ndarray 类型,并将颜色空间从 RGB 转换回 BGR,# 以符合 OpenCV 的要求return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)def MAR(shape):"""计算嘴巴纵横比(Mouth Aspect Ratio):param shape: 68 个人脸特征点的坐标数组:return: 嘴巴纵横比"""# 计算嘴巴上下部分特定点之间的欧氏距离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):"""计算嘴巴与下巴宽度比(Mouth to Jaw Ratio):param shape: 68 个人脸特征点的坐标数组:return: 嘴巴与下巴宽度比"""# 计算嘴巴左右两侧特定点之间的欧氏距离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 MBR(shape):"""计算眉毛间距比(Mouth to Brow Ratio):param shape: 68 个人脸特征点的坐标数组:return: 眉毛间距比"""# 计算左右眉毛内侧特定点之间的欧氏距离F = euclidean_distances(shape[21].reshape(1, 2), shape[22].reshape(1, 2))# 计算左右眉毛外侧特定点之间的欧氏距离I = euclidean_distances(shape[17].reshape(1, 2), shape[26].reshape(1, 2))# 计算眉毛间距比return F / I# 打开默认摄像头,用于实时视频捕获
cap = cv2.VideoCapture(0)
# 加载预训练的 68 点人脸特征预测模型
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
# 创建人脸检测器对象
detector = dlib.get_frontal_face_detector()while True:# 从摄像头读取一帧视频ret, frame = cap.read()# 水平翻转视频帧,使画面看起来更自然frame = cv2.flip(frame, 1)# 如果读取失败,跳出循环if ret is None:break# 检测视频帧中的人脸faces = detector(frame, 0)for face in faces:# 预测人脸的 68 个特征点shape = predictor(frame, face)# 将特征点转换为 numpy 数组shape = np.array([[p.x, p.y] for p in shape.parts()])# 计算嘴巴纵横比mar = MAR(shape)# 计算嘴巴与下巴宽度比mjr = MJR(shape)# 计算眉毛间距比mbr = MBR(shape)# 初始化表情结果为正常result = '正常'# 打印各个比值print("mar", mar, '\tmjr', mjr, 'mbr', mbr)# 根据比值判断表情if mar > 0.5:result = "大笑"elif mjr > 0.45:result = '微笑'elif mbr < 0.15: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('img', frame)# 等待用户按键,等待时间为 1 毫秒key = cv2.waitKey(1)# 如果用户按下 ESC 键(ASCII 码为 27),跳出循环if key == 27:break
# 释放摄像头资源
cap.release()
# 关闭所有 OpenCV 窗口
cv2.destroyAllWindows()

在这里插入图片描述

dlib库——人脸应用实例——疲劳检测

在这里插入图片描述

当闭眼时间长时,发出危险警告。

代码:

import numpy as np
import cv2
import dlib
from sklearn.metrics.pairwise import euclidean_distances
from PIL import Image, ImageDraw, ImageFontdef cv2AddChineseText(img, text, position, textColor=(0, 255, 0), textSize=20):""" 向图片中添加中文 """# 判断输入的 img 是否为 OpenCV 格式的图片(即 numpy.ndarray 类型)if isinstance(img, np.ndarray):# 如果是 OpenCV 格式,将其从 BGR 颜色空间转换为 RGB 颜色空间,# 因为 PIL 库使用 RGB 颜色空间,而 OpenCV 使用 BGR 颜色空间img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))# 在 img 图片上创建一个绘图对象,用于后续绘制文本draw = ImageDraw.Draw(img)# 定义字体的格式,使用 "simsun.ttc" 字体文件,指定字体大小为 textSize,# 并设置编码为 UTF - 8 以支持中文显示fontStyle = ImageFont.truetype("simsun.ttc", textSize, encoding="utf-8")# 在指定的 position 位置,使用指定的 textColor 颜色和 fontStyle 字体绘制文本draw.text(position, text, textColor, font=fontStyle)# 将绘制好文本的 PIL 图片转换回 numpy.ndarray 类型,并将颜色空间从 RGB 转换回 BGR,# 以符合 OpenCV 的要求return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)def eye_aspect_ratio(eye):"""计算眼睛的纵横比(Eye Aspect Ratio,EAR):param eye: 眼睛的特征点坐标数组:return: 眼睛的纵横比"""# 计算眼睛垂直方向上的距离A = euclidean_distances(eye[1].reshape(1, 2), eye[5].reshape(1, 2))B = euclidean_distances(eye[2].reshape(1, 2), eye[4].reshape(1, 2))# 计算眼睛水平方向上的距离C = euclidean_distances(eye[0].reshape(1, 2), eye[3].reshape(1, 2))# 计算眼睛纵横比,即垂直方向平均距离与水平距离的比值ear = ((A + B) / 2) / Creturn eardef drawEye(eye):"""在图像上绘制眼睛的轮廓:param eye: 眼睛的特征点坐标数组"""# 计算眼睛特征点的凸包eyeHull = cv2.convexHull(eye)# 在图像 frame 上绘制眼睛的轮廓cv2.drawContours(frame, [eyeHull], -1, (0, 255, 0), 1)# 初始化计数器,用于记录眼睛闭合的帧数
COUNTER = 0
# 创建人脸检测器对象,用于检测图像中的人脸
detector = dlib.get_frontal_face_detector()
# 打开默认摄像头,用于实时视频捕获
cap = cv2.VideoCapture(0)
# 加载预训练的 68 点人脸特征预测模型
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')while True:# 从摄像头读取一帧视频ret, frame = cap.read()# 水平翻转视频帧,使画面看起来更自然frame = cv2.flip(frame, 1)# 如果读取失败,跳出循环if ret is None:break# 检测视频帧中的人脸faces = detector(frame, 0)for face in faces:# 预测人脸的 68 个特征点shape = predictor(frame, face)# 将特征点转换为 numpy 数组shape = np.array([[p.x, p.y] for p in shape.parts()])# 提取右眼的特征点rightEye = shape[36:42]# 提取左眼的特征点leftEye = shape[42:48]# 计算右眼的纵横比rightEAR = eye_aspect_ratio(rightEye)# 计算左眼的纵横比leftEAR = eye_aspect_ratio(leftEye)# 计算左右眼纵横比的平均值ear = (leftEAR + rightEAR) / 2# 如果眼睛纵横比小于 0.3,认为眼睛处于闭合状态if ear < 0.3:# 闭合帧数计数器加 1COUNTER += 1# 如果闭合帧数超过 50 帧,认为可能存在危险情况if COUNTER >= 50:# 在视频帧上添加中文提示信息frame = cv2AddChineseText(frame, "!!!危险!!!", (250, 250))else:# 如果眼睛处于睁开状态,将闭合帧数计数器重置为 0COUNTER = 0# 绘制左眼的轮廓drawEye(leftEye)# 绘制右眼的轮廓drawEye(rightEye)# 格式化眼睛纵横比信息,保留两位小数info = "EAR:{:.2f}".format(ear[0][0])# 在视频帧上添加眼睛纵横比信息frame = cv2AddChineseText(frame, info, (0, 30))# 显示处理后的视频帧cv2.imshow('Frame', frame)# 等待用户按键,等待时间为 1 毫秒key = cv2.waitKey(1)# 如果用户按下 ESC 键(ASCII 码为 27),跳出循环if key == 27:break# 释放摄像头资源
cap.release()
# 关闭所有 OpenCV 窗口
cv2.destroyAllWindows()

在这里插入图片描述

相关文章:

《OpenCV》——dlib(人脸应用实例)

文章目录 dlib库dlib库——人脸应用实例——表情识别dlib库——人脸应用实例——疲劳检测 dlib库 dlib库的基础用法介绍可以参考这篇文章&#xff1a;https://blog.csdn.net/lou0720/article/details/145968062?spm1011.2415.3001.5331&#xff0c;故此这篇文章只介绍dlib的人…...

以太网通讯

接口开发笔记-WebApi-CSDN博客 以太网常用通讯协议 1、modbus tcp using EasyModbus; using System;class Program {static void Main(string[] args){// 创建Modbus客户端实例ModbusClient modbusClient new ModbusClient("192.168.1.100"); // IP地址modbusCli…...

UDP学习笔记(一)为什么UDP需要先将数据转换为字节数组

UDP 发送数据时需要先将数据转换为字节数组再发送&#xff0c;主要是因为计算机网络传输的最基本单位是“字节”&#xff08;Byte&#xff09;。让我们从以下几个方面来深入理解这个设计选择&#xff1a; 1. 计算机网络只能传输“字节” 在网络通信中&#xff0c;无论是 TCP 还…...

数据分析/数据科学常见SQL题目:连续登录用户、留存率、最大观看人数

文章目录 1. SQL的执行顺序是什么&#xff1f;on和join谁先执行&#xff0c;为什么&#xff1f;on和where的区别&#xff1f;2. 已知表user,字段id, date&#xff0c;求新用户的次日留存率3. 已知表user&#xff0c;字段id&#xff0c;date&#xff0c;求每个日期新用户的次日留…...

【Conda】Windows安装conda/Anaconda环境

安装conda并配置powershell 访问该网址&#xff0c;下载安装即可&#xff1a; Anaconda下载 安装完成后&#xff0c;打开Anaconda&#xff0c;并访问Powershell Prompt 弹出Windows Terminal&#xff0c;并正常进入Conda 【非必须】如果不是通过Windows Terminal打开&#x…...

olmOCR:高效精准的 PDF 文本提取工具

在日常的工作和学习中&#xff0c;是否经常被 PDF 文本提取问题困扰&#xff1f;例如&#xff1a; 想从学术论文 PDF 中提取关键信息&#xff0c;却发现传统 OCR 工具识别不准确或文本格式混乱&#xff1f;需要快速提取商务合同 PDF 中的条款内容&#xff0c;却因工具不给力而…...

数字投屏叫号器-发射端python窗口定制

窗口 本系列前章介绍&#xff0c;叫号器的显示端&#xff0c;完成了视频音频的形成和传输的介绍。本章节开始定制小窗口。 最终实现&#xff0c;处于桌面最前端&#xff0c;发送指令&#xff0c;集合前篇即可完成&#xff1a; 处理本地text.txt更新&#xff0c;随之被rtsp采集…...

从零开始实现大语言模型(十四):高阶训练技巧

1. 前言 预训练大语言模型的流程与训练普通神经深度网络模型本质上并没有任何不同。可以使用深度学习实践中已经被证明非常有效的高阶训练技巧&#xff0c;优化大语言模型预训练流程&#xff0c;使大语言模型预训练效率更高&#xff0c;训练过程更稳定。 本文介绍深度学习领域…...

Spring-framework源码编译

版本统一&#xff08;搭配其他版本会遇到不可知错误&#xff09;&#xff1a; 1&#xff09;spring 5.2.X&#xff08;5.5.26&#xff09; 2&#xff09;JDK8 3&#xff09;Gradle:5.6.4 可以在gradle-wrapper.properties中修改 https\://services.gradle.org/distribution…...

分布式系统的核心挑战与解决方案

1、分布式系统的引入 在移动互联网、云计算和物联网的推动下&#xff0c;现代软件系统需要处理亿级用户请求、PB级数据存储和毫秒级响应需求。传统的单体架构受限于单机性能瓶颈和容灾能力&#xff0c;逐渐被分布式系统取代。例如&#xff0c;电商平台在“双十一”期间需应对每…...

fastjson漏洞

fastjson漏洞 fastjson工作原理攻击原理补充 例子 fastjson工作原理 fastjson的作用是将JAVA对象转换成对应的json表示形式&#xff0c;也可以反过来将json转化为对应的Java对象。fastjson使用AutoType功能进行反序列化&#xff0c;AutoType使用type标记字符的原始类型&#x…...

upload-labs详解(13-20)文件上传分析

目录 upload-labs-env upload-labs-env第十三关 文件包含漏洞 代码 测试 上传一个.jpg图片 上传一个.png文件 上传一个.gif图片 upload-labs-env第十四关 代码 思路 upload-labs-env第十五关 代码 思路 upload-labs-env第十六关 代码 思路 测试 上传gif格式…...

HTML第四节

一.复合选择器 1.后代选择器 注&#xff1a;1.后代选择器会选中后代所有的要选择的标签 2.儿子选择器 3.并集选择器 注&#xff1a;1.注意换行&#xff0c;同时选中多种标签 4.交集选择器 注&#xff1a;1.标签选择器放在最前面&#xff0c;例如放在类选择器的前面 2.两个选择…...

基于 LeNet 网络的 MNIST 数据集图像分类

1.LeNet的原始实验数据集MNIST 名称&#xff1a;MNIST手写数字数据集 数据类型&#xff1a;灰度图 &#xff08;一通道&#xff09; 图像大小&#xff1a;28*28 类别数&#xff1a;10类&#xff08;数字0-9&#xff09; 1.通过torchvision.datasets.MNIST下载并保存到本地…...

win11编译llama_cpp_python cuda128 RTX30/40/50版本

Geforce 50xx系显卡最低支持cuda128&#xff0c;llama_cpp_python官方源只有cpu版本&#xff0c;没有cuda版本&#xff0c;所以自己基于0.3.5版本源码编译一个RTX 30xx/40xx/50xx版本。 1. 前置条件 1. 访问https://developer.download.nvidia.cn/compute/cuda/12.8.0/local_…...

Spring Boot静态资源访问顺序

在 Spring Boot 中&#xff0c;static 和 public 目录都用于存放静态资源&#xff08;如 HTML、CSS、JavaScript、图片等文件&#xff09;&#xff0c;但它们在使用上有一些细微的区别。以下是它们的详细对比&#xff1a; 1. 默认优先级 Spring Boot 会按照以下优先级加载静态…...

电脑总显示串口正在被占用处理方法

1.现象 在嵌入式开发过程中&#xff0c;有很多情况下要使用串口调试&#xff0c;其中485/422/232转usb串口是非常常见的做法。 根据协议&#xff0c;接口芯片不同&#xff0c;需要安装对应的驱动程序&#xff0c;比如ch340&#xff0c;cp2102&#xff0c;CDM212364等驱动。可…...

工具介绍《HACKBAR V2》

HackBar V2 是一款功能强大的浏览器渗透测试工具&#xff0c;主要用于测试 SQL 注入、XSS 漏洞、POST 传参等安全场景。以下是其核心功能、用法及实际案例操作的综合介绍&#xff1a; 一、核心功能与用法详解 1. 基础操作 Load URL 功能&#xff1a;将当前浏览器地址栏的 URL …...

Java算法语法学习 美丽子集的数目 - 力扣 Map接口

文章目录 题目解题思路题解统计数组中每个数字按模k分组的出现次数&#xff0c;并保持数值有序作用 **merge(x, 1, Integer::sum)**解释**检查键是否存在**:**合并现有值**: 示例在代码中的应用**计算余数**:**存储余数及其出现次数**: merge 的常见用法统计频率合并字符串合并…...

Vue项目通过内嵌iframe访问另一个vue页面,获取token适配后端鉴权(以内嵌若依项目举例)

1. 改造子Vue项目进行适配(ruoyi举例) (1) 在路由文件添加需要被外链的vue页面配置 // 若依项目的话是 router/index.js文件 {path: /contrast,component: () > import(/views/contrast/index),hidden: true },(2) 开放白名单 // 若依项目的话是 permission.js 文件 cons…...

APT41 (Barium) 的演进:从游戏行业到供应链攻击的AI应用

前言 1. 技术背景 —— 这个技术在攻防体系中的位置 高级持续性威胁 (Advanced Persistent Threat, APT) 是网络攻防体系金字塔的顶端。它并非指某种单一技术&#xff0c;而是一个复杂的、有组织的、长期的网络攻击活动集合。在整个攻防图谱中&#xff0c;APT代表着最高级别的对…...

阿里云域名动态解析避坑指南:从AccessKey到API调用的完整流程

阿里云域名动态解析实战手册&#xff1a;从权限配置到高可用方案设计 对于拥有个人博客、家庭NAS或远程开发环境的技术爱好者而言&#xff0c;动态公网IP始终是个令人头疼的问题。每当ISP重新分配IP地址时&#xff0c;原本稳定的服务连接就会突然中断。本文将分享如何利用阿里云…...

桶排序:分布式排序的高效实现

桶排序&#xff1a;分布式排序的高效实现 算法原理 核心思路 桶排序是一种分布式排序算法&#xff0c;其核心思想是&#xff1a; 将待排序的数据分到有限数量的桶里每个桶再分别进行排序&#xff08;可以使用其他排序算法&#xff09;最后将各个桶中的数据有序地合并起来 复杂度…...

从ChatGPT到机器翻译:GRPO算法如何优化大语言模型的生成效果?

GRPO算法&#xff1a;大语言模型生成效果优化的新范式 在自然语言处理领域&#xff0c;序列生成任务的质量优化一直是研究热点。从ChatGPT的对话流畅度到机器翻译的准确性&#xff0c;生成效果直接影响用户体验。传统优化方法如PPO虽然有效&#xff0c;但在处理复杂语言任务时存…...

ESP32-C3开发环境搭建(VSCode+ESP-IDF)与串口占用疑难排查实战

1. ESP32-C3开发环境搭建全攻略 第一次接触ESP32-C3开发板时&#xff0c;我和大多数开发者一样&#xff0c;被环境搭建这个"入门杀"折腾得够呛。特别是使用合宙经典款开发板时&#xff0c;USB转串口芯片带来的各种"惊喜"让人措手不及。这里分享一套经过实战…...

英集芯-IP5316、IP5219有什么区别?详细总结一下

简介 IP5219和IP5316都是英集芯的充电管理IC,两款移动电源SOC芯片输出/输入参数基本一致,但是使用起来却有一些差异,下面就对两款IC使用中遇到的一些问题做一些总结。 IP5219:2.1A 充电 2.4A 放电集成 TYPE_C 协议移动电源 SOC; IP5316:集成 TYPE_C 协议的 2.4A 充电/2.4…...

保姆级教程:Arduino IDE离线安装ESP32开发板支持包(附稳定镜像源)

Arduino IDE离线安装ESP32开发板支持包全攻略 对于国内开发者来说&#xff0c;Arduino IDE安装ESP32开发板支持包常常会遇到网络连接不稳定、下载速度慢甚至完全无法访问的问题。本文将提供一套完整的离线安装方案&#xff0c;通过国内镜像源和分步操作指南&#xff0c;确保即…...

QDKTAI实战面试题50问之41-50

一、逐题详细解析&#xff08;41-50题&#xff09;第41题&#xff1a;如何设计一个有效的AI内容审核系统&#xff1f;1. 考察重点对大模型“生成式而非判别式”核心特性的理解识别AI审核场景中的关键冲突点&#xff08;长文本处理、语气/风格干扰&#xff09;针对性解决方案的设…...

【愚公系列】《剪映+DeepSeek+即梦:短视频制作》026-字幕:用文字来美化画面(美化字幕)

&#x1f48e;【行业认证权威头衔】 ✔ 华为云天团核心成员&#xff1a;特约编辑/云享专家/开发者专家/产品云测专家 ✔ 开发者社区全满贯&#xff1a;CSDN博客&商业化双料专家/阿里云签约作者/腾讯云内容共创官/掘金&亚马逊&51CTO顶级博主 ✔ 技术生态共建先锋&am…...

【实战指南】Spirent TCL 并发与新建连接测试全流程解析

1. Spirent TCL测试基础与环境搭建 第一次接触Spirent TestCenter时&#xff0c;我也被它强大的功能和复杂的界面吓到过。但实际用下来发现&#xff0c;只要掌握几个核心模块&#xff0c;就能完成大多数性能测试任务。这里先带大家快速搭建测试环境&#xff0c;为后续的并发和新…...