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

疲劳检测-闭眼检测(详细代码教程)

简介

瞌睡经常发生在汽车行驶的过程中,该行为害人害己,如果有一套能识别瞌睡的系统,那么无疑该系统意义重大!
在这里插入图片描述

实现步骤

思路:疲劳驾驶的司机大部分都有打瞌睡的情形,所以我们根据驾驶员眼睛闭合的频率和时间来判断驾驶员是否疲劳驾驶(或嗜睡)。

详细实现步骤

【1】眼部关键点检测。

在这里插入图片描述

我们使用Face Mesh来检测眼部关键点,Face Mesh返回了468个人脸关键点:
由于我们专注于驾驶员睡意检测,在468个点中,我们只需要属于眼睛区域的标志点。眼睛区域有 32 个标志点(每个 16 个点)。为了计算 EAR,我们只需要 12 个点(每只眼睛 6 个点)。

以上图为参考,选取的12个地标点如下:

对于左眼: [362, 385, 387, 263, 373, 380]

对于右眼:[33, 160, 158, 133, 153, 144]

选择的地标点按顺序排列:P 1、 P 2、 P 3、 P 4、 P 5、 P 6

```bash```bash
import cv2
import numpy as np
import matplotlib.pyplot as plt
import mediapipe as mpmp_facemesh = mp.solutions.face_mesh
mp_drawing  = mp.solutions.drawing_utils
denormalize_coordinates = mp_drawing._normalized_to_pixel_coordinates%matplotlib inline
获取双眼的地标(索引)点。

`


```bash
# Landmark points corresponding to left eye
all_left_eye_idxs = list(mp_facemesh.FACEMESH_LEFT_EYE)
# flatten and remove duplicates
all_left_eye_idxs = set(np.ravel(all_left_eye_idxs)) # Landmark points corresponding to right eye
all_right_eye_idxs = list(mp_facemesh.FACEMESH_RIGHT_EYE)
all_right_eye_idxs = set(np.ravel(all_right_eye_idxs))# Combined for plotting - Landmark points for both eye
all_idxs = all_left_eye_idxs.union(all_right_eye_idxs)# The chosen 12 points:   P1,  P2,  P3,  P4,  P5,  P6
chosen_left_eye_idxs  = [362, 385, 387, 263, 373, 380]
chosen_right_eye_idxs = [33,  160, 158, 133, 153, 144]
all_chosen_idxs = chosen_left_eye_idxs + chosen_right_eye_idx
图片

【2】检测眼睛是否闭合——计算眼睛纵横比(EAR)。

要检测眼睛是否闭合,我们可以使用眼睛纵横比(EAR) 公式:

EAR 公式返回反映睁眼程度的单个标量:

  1. 我们将使用 Mediapipe 的 Face Mesh 解决方案来检测和检索眼睛区域中的相关地标(下图中的点P 1 - P 6)。
  2. 检索相关点后,会在眼睛的高度和宽度之间计算眼睛纵横比 (EAR)。
    当眼睛睁开并接近零时,EAR 几乎是恒定的,而闭上眼睛是部分人,并且头部姿势不敏感。睁眼的纵横比在个体之间具有很小的差异。它对于图像的统一缩放和面部的平面内旋转是完全不变的。由于双眼同时眨眼,所以双眼的EAR是平均的。
    在这里插入图片描述

上图:检测到地标P i的睁眼和闭眼。

底部:为视频序列的几帧绘制的眼睛纵横比 EAR。存在一个闪烁。

首先,我们必须计算每只眼睛的 Eye Aspect Ratio:

|| 表示L2范数,用于计算两个向量之间的距离。

为了计算最终的 EAR 值,作者建议取两个 EAR 值的平均值。

在这里插入图片描述

一般来说,平均 EAR 值在 [0.0, 0.40] 范围内。在“闭眼”动作期间 EAR 值迅速下降。

现在我们熟悉了 EAR 公式,让我们定义三个必需的函数:distance(…)、get_ear(…)和calculate_avg_ear(…)。

def distance(point_1, point_2):"""Calculate l2-norm between two points"""dist = sum([(i - j) ** 2 for i, j in zip(point_1, point_2)]) ** 0.5return dist
get_ear ()函数将.landmark属性作为参数。在每个索引位置,我们都有一个NormalizedLandmark对象。该对象保存标准化的x、y和z坐标值。
def get_ear(landmarks, refer_idxs, frame_width, frame_height):"""Calculate Eye Aspect Ratio for one eye.Args:landmarks: (list) Detected landmarks listrefer_idxs: (list) Index positions of the chosen landmarksin order P1, P2, P3, P4, P5, P6frame_width: (int) Width of captured frameframe_height: (int) Height of captured frameReturns:ear: (float) Eye aspect ratio"""try:# Compute the euclidean distance between the horizontalcoords_points = []for i in refer_idxs:lm = landmarks[i]coord = denormalize_coordinates(lm.x, lm.y, frame_width, frame_height)coords_points.append(coord)# Eye landmark (x, y)-coordinatesP2_P6 = distance(coords_points[1], coords_points[5])P3_P5 = distance(coords_points[2], coords_points[4])P1_P4 = distance(coords_points[0], coords_points[3])# Compute the eye aspect ratioear = (P2_P6 + P3_P5) / (2.0 * P1_P4)except:ear = 0.0coords_points = Nonereturn ear, coords_points

最后定义了calculate_avg_ear(…)函数:

def calculate_avg_ear(landmarks, left_eye_idxs, right_eye_idxs, image_w, image_h):"""Calculate Eye aspect ratio"""left_ear, left_lm_coordinates = get_ear(landmarks, left_eye_idxs, image_w, image_h)right_ear, right_lm_coordinates = get_ear(landmarks, right_eye_idxs, image_w, image_h)Avg_EAR = (left_ear + right_ear) / 2.0return Avg_EAR, (left_lm_coordinates, right_lm_coordinates)

让我们测试一下 EAR 公式。我们将计算先前使用的图像和另一张眼睛闭合的图像的平均 EAR 值。

image_eyes_open  = cv2.imread("test-open-eyes.jpg")[:, :, ::-1]
image_eyes_close = cv2.imread("test-close-eyes.jpg")[:, :, ::-1]for idx, image in enumerate([image_eyes_open, image_eyes_close]):image = np.ascontiguousarray(image)imgH, imgW, _ = image.shape# Creating a copy of the original image for plotting the EAR valuecustom_chosen_lmk_image = image.copy()# Running inference using static_image_modewith mp_facemesh.FaceMesh(refine_landmarks=True) as face_mesh:results = face_mesh.process(image).multi_face_landmarks# If detections are available.if results:for face_id, face_landmarks in enumerate(results):landmarks = face_landmarks.landmarkEAR, _ = calculate_avg_ear(landmarks, chosen_left_eye_idxs, chosen_right_eye_idxs, imgW, imgH)# Print the EAR value on the custom_chosen_lmk_image.cv2.putText(custom_chosen_lmk_image, f"EAR: {round(EAR, 2)}", (1, 24),cv2.FONT_HERSHEY_COMPLEX, 0.9, (255, 255, 255), 2)                plot(img_dt=image.copy(),img_eye_lmks_chosen=custom_chosen_lmk_image,face_landmarks=face_landmarks,ts_thickness=1, ts_circle_radius=3, lmk_circle_radius=3)

结果:

图片

如您所见,睁眼时的 EAR 值为0.28,闭眼时(接近于零)为 0.08。

【3】设计一个实时检测系统。

在这里插入图片描述

首先,我们声明两个阈值和一个计数器。

  • EAR_thresh: 用于检查当前EAR值是否在范围内的阈值。
  • D_TIME:一个计数器变量,用于跟踪当前经过的时间量EAR < EAR_THRESH.
  • WAIT_TIME:确定经过的时间量是否EAR < EAR_THRESH超过了允许的限制。
  • 当应用程序启动时,我们将当前时间(以秒为单位)记录在一个变量中t1并读取传入的帧。

接下来,我们预处理并frame通过Mediapipe 的 Face Mesh 解决方案管道。

  • 如果有任何地标检测可用,我们将检索相关的 ( Pi )眼睛地标。否则,在此处重置t1 和重置以使算法一致)。D_TIME (D_TIME
  • 如果检测可用,则使用检索到的眼睛标志计算双眼的平均EAR值。
  • 如果是当前时间,则加上当前时间和to之间的差。然后将下一帧重置为。EAR < EAR_THRESHt2t1D_TIMEt1 t2
  • 如果D_TIME >= WAIT_TIME,我们会发出警报或继续下一帧。

相关文章:

疲劳检测-闭眼检测(详细代码教程)

简介 瞌睡经常发生在汽车行驶的过程中&#xff0c;该行为害人害己&#xff0c;如果有一套能识别瞌睡的系统&#xff0c;那么无疑该系统意义重大&#xff01; 实现步骤 思路&#xff1a;疲劳驾驶的司机大部分都有打瞌睡的情形&#xff0c;所以我们根据驾驶员眼睛闭合的频率和…...

大数据日常运维命令

1、HDFS NameNode /usr/local/fqlhadoop/hadoop/sbin/hadoop-daemon.sh start namenode /usr/local/fqlhadoop/hadoop/sbin/hadoop-daemon.sh stop namenode bin/hdfs haadmin -DFSHAAdmin -getServiceState n1 2、HDFS DataNode /usr/local/fqlhadoop/hadoop/sbin/hadoop-…...

解锁安全高效办公——私有化部署的WorkPlus即时通讯软件

在当今信息时代&#xff0c;高效的沟通与协作对于企业的成功至关重要。然而&#xff0c;随着信息技术的发展&#xff0c;保护敏感信息和数据安全也变得越来越重要。为了满足企业对于安全沟通和高效办公的需求&#xff0c;我们隆重推出私有化部署的WorkPlus即时通讯软件&#xf…...

IDEA使用git

文章目录 给所有文件配置git初始化本地仓库创建.gitignore文件添加远程仓库分支操作 给所有文件配置git 初始化本地仓库 创建.gitignore文件 添加远程仓库 分支操作 新建分支 newbranch 切换分支 checkout 推送分支 push 合并分支 merge...

【跟小嘉学 Rust 编程】十八、模式匹配(Patterns and Matching)

系列文章目录 【跟小嘉学 Rust 编程】一、Rust 编程基础 【跟小嘉学 Rust 编程】二、Rust 包管理工具使用 【跟小嘉学 Rust 编程】三、Rust 的基本程序概念 【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念 【跟小嘉学 Rust 编程】五、使用结构体关联结构化数据 【跟小嘉学…...

keepalived+lvs+nginx高并发集群

keepalivedlvsnginx高并发集群 简介&#xff1a; keepalivedlvsnginx高并发集群&#xff0c;是通过LVS将请求流量均匀分发给nginx集群&#xff0c;而当单机nginx出现状态异常或宕机时&#xff0c;keepalived会主动切换并将不健康nginx下线&#xff0c;维持集群稳定高可用 1.L…...

剑指Offer65.不用加减乘除做加法 C++

1、题目描述 写一个函数&#xff0c;求两个整数之和&#xff0c;要求在函数体内不得使用 “”、“-”、“*”、“/” 四则运算符号。 示例: 输入: a 1, b 1 输出: 2 2、VS2019上运行 使用位运算的方法 #include <iostream>class Solution { public:/*** 计算两个整…...

【linux命令讲解大全】004.探索Linux命令行中的chmod和chown工具

文章目录 chmod概要主要用途参数选项返回值例子 chown补充说明语法选项参数实例 从零学 python chmod 用来变更文件或目录的权限 概要 chmod [OPTION]... MODE[,MODE]... FILE... chmod [OPTION]... OCTAL-MODE FILE... chmod [OPTION]... --referenceRFILE FILE...主要用途…...

nginx会话保持

ip_hash:通过IP保持会话 作用&#xff1a; nginx通过后端服务器地址将请求定向的转发到服务器上。 将客户端的IP地址通过哈希算法加密成一个数值 如果后端有多个服务器&#xff0c;第一次请求到服务器A&#xff0c; 并在务器登录成功&#xff0c;那么再登录B服务器就要重新…...

SpringBoot使用Druid连接池 + 配置监控页面(自定义版 + starter版)

目录 1. Druid连接池的功能2. 自定义版2.1 pom.xml添加依赖2.2 MyDataSourceConfig实现2.3 application.properties配置编写Controller进行测试2.4 druid监控页面查看 3. starter版3.1 pom.xml添加依赖3.2 自动配置分析3.3 使用application.properties对druid进行配置3.4 druid…...

【业务功能篇77】微服务-OSS对象存储-上传下载图片

3. 图片管理 文件存储的几种方式 单体架构可以直接把图片存储在服务器中 但是在分布式环境下面直接存储在WEB服务器中的方式就不可取了&#xff0c;这时我们需要搭建独立的文件存储服务器。 3.1 开通阿里云服务 针对本系统中的相关的文件&#xff0c;图片&#xff0c;文本等…...

【CSS 常用加载动画效果】

常用加载效果 呼吸灯效果波浪光效果转圈加载 呼吸灯效果 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><body><div id"ti"></div></body><style>b…...

python 模块requests 发送 HTTP 请求

一、简介 requests 模块是 python 基于 urllib&#xff0c;采用 Apache2 Licensed 开源协议的 HTTP 库。它比 urllib 更加方便&#xff0c;可以节约我们大量的工作 二、安装 pip install requestsimport requests三、方法 requsts.requst(method, url,headers,cookies,prox…...

关于 Camera 预览和录像画质不一样的问题分析

1、问题背景 基于之前安卓平台的一个项目&#xff0c;客户有反馈过一个 Camera app 预览的效果&#xff0c;和录像效果不一致的问题。 这里的预览是指打开 Camera app 后直接出图的效果&#xff1b;录像的效果则是指打开 Camera app 开启录像功能&#xff0c;录制一段视频&…...

【音视频】 视频的播放和暂停,当播放到末尾时触发 ended 事件,循环播放,播放速度

video 也可以 播放 MP3 音频&#xff0c;当不想让 视频显示出来的话&#xff0c;可以 给 video 设置宽和高 1rpx &#xff0c;不可以隐藏 <template><view class"form2box"><u-navbar leftClick"leftClick"><view slot"left&q…...

Python数据分析高薪实战第一天 python基础与项目环境搭建

开篇词 数据赋能未来&#xff0c;Python 势不可挡 互联网公司从红利下的爆发期&#xff0c;进入新的精细化发展阶段&#xff0c;亟须深入分析与挖掘业务与数据价值&#xff0c;从而找到新的增长点突破现有增长瓶颈。各行各业的数据分析需求井喷&#xff0c;数据分析人才成为争…...

pandas数据分析——groupby得到分组后的数据

groupbyagg分组聚合对数据字段进行合并拼接 Pandas怎样实现groupby聚合后字符串列的合并&#xff08;四十&#xff09; groupby得到分组后的数据 pandas—groupby如何得到分组里的数据 date_range补齐缺失日期 在处理时间序列的数据中&#xff0c;有时候会遇到有些日期的数…...

Android studio 软件git使用

在 test 分支添加的方法 , 现在切换到 master分支 总共 2 个分支 , 当前的分支是 test 出现了 先试一下 force checkout , 尝试之后发现 , 你更改没有带过来 , 以为哪个类在master分支没有 , 所以这边也没有 , 切回分支 test 发现之前的跟改没有 , 这样即可以找回 继续切换…...

通过C实现sqlite3操作,导入电子词典

#include <stdio.h> #include <string.h> #include <stdlib.h> #include <sqlite3.h> int main(int argc, const char *argv[]) {//创建并打开一个数据库sqlite3 *db NULL;if(sqlite3_open("./dict.db",&db) ! SQLITE_OK){printf("…...

K8S集群中使用JDOS KMS服务对敏感数据安全加密 | 京东云技术团队

基本概念 KMS&#xff0c;Key Management Service&#xff0c;即密钥管理服务&#xff0c;在K8S集群中&#xff0c;以驱动和插件的形式启用对Secret&#xff0c;Configmap进行加密。以保护敏感数据&#xff0c; 驱动和插件需要使用者按照需求进行定制和实现自己的KMS插件&…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

Golang——6、指针和结构体

指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

PostgreSQL——环境搭建

一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在&#xff0…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...