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

【进阶OpenCV】 (20) --疲劳检测

文章目录

  • 疲劳检测
    • 一、面部识别
    • 二、主循环
      • 1. 计算眼睛纵横比
      • 2. 判断疲劳状态
      • 3. 绘制双眼凸包
      • 4. 显示眼睛闭合程度值
      • 5. 显示图像
    • 三、释放资源
    • 四、完整代码展示
  • 总结

疲劳检测

使用OpenCV实现疲劳检测通常依赖于面部特征分析,特别是眼睛的状态(如眼睛开合程度)以及闭眼的时间。

一、面部识别

通过Dlib库构造人脸检测器,用于检测人脸,然后通过shape_predictor()加载模型用于定位检测到的人脸的关键点:

detector = dlib.get_frontal_face_detector() # 构造人脸检测器
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat") # 定位关键点模型
cap = cv2.VideoCapture(0)

二、主循环

1. 计算眼睛纵横比

通过euclidean_distances()函数计算两点间的距离:

def eye_aspect_ratio(eye):"""-----计算眼睛纵横比-----"""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.0) / C # 纵横比return ear
COUNTER = 0 # 闭眼持续帧数统计
while True:ret,frame = cap.read()faces = detector(frame,0)for face in faces:shape = predictor(frame,face)# 获取关键点# 将关键点转换为坐标(x,y)的形式shape = np.array([[p.x,p.y] for p in shape.parts()])rightEye = shape[36:42] # 右眼,关键点索引从36到41leftEye = shape[42:48] # 左眼,关键点索引从42到47rightEAR = eye_aspect_ratio(rightEye) # 计算右眼纵横比leftEAR = eye_aspect_ratio(leftEye) # 计算左眼纵横比ear = (leftEAR + rightEAR) / 2.0 # 均值处理

2. 判断疲劳状态

当宽高比小于0.3,且连续50帧保持这个状态,则认定他处于疲劳状态:

def cv2ADDChineseText(img,text,position,textColor=(0,255,0),textSize=30):"""像图片中添加中文"""if (isinstance(img,np.ndarray)):img = Image.fromarray(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))draw = ImageDraw.Draw(img)fontStyle = ImageFont.truetype("simfang.ttf",textSize,encoding="Utf-8")draw.text(position,text,textColor,font=fontStyle)return cv2.cvtColor(np.asarray(img),cv2.COLOR_BGR2RGB)if ear < 0.3: # 小于0.3认为闭眼,也可能是眨眼COUNTER += 1if COUNTER >= 50:frame = cv2ADDChineseText(frame,"!!!危险!!!",(250,250))
# 宽高比 > 0.3,则计数器清零,解除疲劳标志
else:COUNTER = 0 # 闭眼次数清零

3. 绘制双眼凸包

将双眼绘制出来:

def drawEye(eye): # 绘制眼眶凸包eyeHull = cv2.convexHull(eye)cv2.drawContours(frame,[eyeHull],-1,(0,255,0),1)drawEye(leftEye) # 绘制左眼凸包
drawEye(rightEye) # 绘制右眼凸包

4. 显示眼睛闭合程度值

info = "EAR:{:.2f}".format(ear[0][0])
frame = cv2ADDChineseText(frame,info,(0,30)) # 显示眼睛闭合程度值

5. 显示图像

    cv2.imshow("Frame",frame)if cv2.waitKey(1) == 27:break

三、释放资源

cv2.destroyAllWindows()
cap.release()

四、完整代码展示

import numpy as np
import dlib
import cv2
from sklearn.metrics.pairwise import euclidean_distances
from PIL import Image,ImageDraw,ImageFontdef eye_aspect_ratio(eye):"""-----计算眼睛纵横比-----"""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.0) / C # 纵横比return eardef cv2ADDChineseText(img,text,position,textColor=(0,255,0),textSize=30):"""像图片中添加中文"""if (isinstance(img,np.ndarray)):img = Image.fromarray(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))draw = ImageDraw.Draw(img)fontStyle = ImageFont.truetype("simfang.ttf",textSize,encoding="Utf-8")draw.text(position,text,textColor,font=fontStyle)return cv2.cvtColor(np.asarray(img),cv2.COLOR_BGR2RGB)def drawEye(eye): # 绘制眼眶凸包eyeHull = cv2.convexHull(eye)cv2.drawContours(frame,[eyeHull],-1,(0,255,0),1)COUNTER = 0 # 闭眼持续帧数统计
detector = dlib.get_frontal_face_detector() # 构造人脸检测器
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat") # 定位关键点模型
cap = cv2.VideoCapture(0)while True:ret,frame = cap.read()faces = detector(frame,0)for face in faces:shape = predictor(frame,face)# 获取关键点# 将关键点转换为坐标(x,y)的形式shape = np.array([[p.x,p.y] for p in shape.parts()])rightEye = shape[36:42] # 右眼,关键点索引从36到41leftEye = shape[42:48] # 左眼,关键点索引从42到47rightEAR = eye_aspect_ratio(rightEye) # 计算右眼纵横比leftEAR = eye_aspect_ratio(leftEye) # 计算左眼纵横比ear = (leftEAR + rightEAR) / 2.0 # 均值处理if ear < 0.3: # 小于0.3认为闭眼,也可能是眨眼COUNTER += 1if COUNTER >= 50:frame = cv2ADDChineseText(frame,"!!!危险!!!",(250,250))# 宽高比 > 0.3,则计数器清零,解除疲劳标志else:COUNTER = 0 # 闭眼次数清零drawEye(leftEye) # 绘制左眼凸包drawEye(rightEye) # 绘制右眼凸包info = "EAR:{:.2f}".format(ear[0][0])frame = cv2ADDChineseText(frame,info,(0,30)) # 显示眼睛闭合程度值cv2.imshow("Frame",frame)if cv2.waitKey(1) == 27:break
cv2.destroyAllWindows()
cap.release()

总结

本篇介绍了,如何通过人脸部眼睛的变化来简单的进行疲劳检测。


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

相关文章:

  • 新的类Rufus应用可带来简单的Windows 11 24H2安装旁路
  • LeetCode 每日一题 最小差值 I
  • Java中的I/O流分类简介
  • 【Linux】进程间通信(匿名管道)
  • c++迷宫游戏
  • Pencils Protocol 用户特权?持有 DAPP 将获 Scroll 生态空投!
  • 6-2.Android 对话框之基础对话框问题清单(UI 线程问题、外部取消、冲突问题、dismiss 方法与 hide 方法)
  • 数据结构之单链表
  • 2063:【例1.4】牛吃牧草
  • CSDN Markdown 编辑器语法大全
  • 商​汤​二​面
  • 餐饮店怎么标注地图位置信息?
  • 2062:【例1.3】电影票
  • 48.旋转图像
  • FloodFill 算法(DFS)
  • [C++] C++类和对象 类的初始化列表和静态成员 类型转换/友元/内部类/匿名对象/编译器优化
  • Symbol简单介绍
  • 【电子通识】案例:两个按键同时按下把boot拉低电路如何设计?
  • VIT:论文关键点解读与常见疑问
  • mac安装jdk8
  • Linux——应用软件的生命周期
  • 0x3D service
  • 监督学习、无监督学习、半监督学习、强化学习、迁移学习、集成学习分别是什么对应什么应用场景
  • ReLitLRM: Generative Relightable Radiance for Large Reconstruction Models 论文解读
  • 二叉树刷题(JAVA)
  • NeRF三维重建—神经辐射场Neural Radiance Field(二)体渲染相关