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

《计算机视觉》—— 疲劳检测

文章目录

  • 一、疲劳检测实现的思想
  • 二、代码实现

一、疲劳检测实现的思想

  • 了解以下几篇文章有助于了解疲劳检测的方法
    • 基于dlib库的人脸检测
      • https://blog.csdn.net/weixin_73504499/article/details/142977202?spm=1001.2014.3001.5501
    • 基于dlib库的人脸关键点定位
      • https://blog.csdn.net/weixin_73504499/article/details/142990867?spm=1001.2014.3001.5501
    • 基于dlib库的人脸关键部位的轮廓检测
      • https://blog.csdn.net/weixin_73504499/article/details/143027371?spm=1001.2014.3001.5501
  • 实现疲劳检测的方法核心方法是通过眼睛的关键点定位来实现的,具体思想如下:
    • 通过68个人脸关键点定位后的效果如下:
      在这里插入图片描述

    • 通过[36-41]和[42~45]这分别两组6个关键点来确定左眼和右眼的位置,眼睛的闭合程度会改变这些点的位置, 因此可以通过这6个点来计算眼睛睁开时的宽高比

    • 设定一个阈值来判断眼睛的闭合程度,低于这个阈值则表示眼睛处于非正常睁开状态,若长时间都低于这个阈值,则会判定为是处于疲劳状态

    • 具体实现如下图
      在这里插入图片描述

      • 取眼睛的6个关键点的上下两组点,分别求出两个距离,并取平均值,作为眼睛镇开时的高度
      • 取左右两个点,计算距离,作为眼睛镇开时的宽度
      • 高度与宽度的比值与设定的阈值进行比较,并做出判断

二、代码实现

好未写完!!!!!!!!!!!!!!!!

  • 定义计算眼睛纵横比的函数

    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) / Creturn ear
    
  • 定义向图片中添加中文的函数

    def cv2AddChineseText(img, text, position, textColor=(0, 255, 0), textSize=30):if (isinstance(img, np.ndarray)):  # 判断是否是OpenCV图片类型img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))  # 实现 array 到 image 的转换draw = ImageDraw.Draw(img)  # 在img图片上创建一个绘图的对象# 字体的格式                       C 盘中的 Windows/Fonts 中,复制到此文件夹下可看到文件名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 格式
    
  • 完整代码:

    import numpy as np
    import dlib
    import cv2
    from sklearn.metrics.pairwise import euclidean_distances    # 计算欧氏距离
    from PIL import Image, ImageDraw, ImageFont"""------计算眼睛纵横比------"""
    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) / Creturn ear""" 向图片中添加中文 """
    def cv2AddChineseText(img, text, position, textColor=(0, 255, 0), textSize=30):if (isinstance(img, np.ndarray)):  # 判断是否是OpenCV图片类型img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))  # 实现 array 到 image 的转换draw = ImageDraw.Draw(img)  # 在img图片上创建一个绘图的对象# 字体的格式                       C 盘中的 Windows/Fonts 中,复制到此文件夹下可看到文件名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 格式""" 绘制眼眶凸包 """
    def drawEye(eye):eyeHull = cv2.convexHull(eye)cv2.drawContours(frame, [eyeHull], -1, (0, 255, 0))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()frame = cv2.flip(frame, 1)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到41(不包含42)leftEye = shape[42:48]      # 左眼,关键点索引从42到47(不包含48)rightEAR = eye_aspect_ratio(rightEye)   # 计算右眼纵横比leftEAR = eye_aspect_ratio(leftEye)     # 计算左眼纵横比ear = (rightEAR + leftEAR) / 2.0        # 均值处理if ear < 0.3:   # 小于0.3认为闭眼,也可能是眨眼(可根据实际调整)COUNTER += 1    # 每检测到一次,将+1if COUNTER >= 50:   # 持续50帧都闭眼,则警报frame = cv2AddChineseText(frame, "!!!!危险!!!!", (250, 250))# 宽高比>0.3,则计数器清零、解除疲劳标志else:COUNTER = 0drawEye(leftEye)      # 绘制左跟凸包drawEye(rightEye)     # 绘制右眼凸包info = "EAR: {:.2f}".format(ear[0][0])frame = cv2AddChineseText(frame, info, (0, 30))     # 显示眼睛闭合程度值cv2.imshow("Frame", frame)# 检查是否按下ESC键(ASCII码27),如果按下则退出循环if cv2.waitKey(10) == 27:break# 释放摄像头资源
    cap.release()
    # 关闭所有OpenCV创建的窗口
    cv2.destroyAllWindows()
    

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

相关文章:

  • Redux与Redux-thunk详解
  • CMake变量作用域
  • 从零开始的LeetCode刷题日记:199. 二叉树的右视图
  • 极氪7X路上能见度越来越高,就连小猎豹都被折服成为第10000号车主
  • openpose二维骨架搭建介绍及代码撰写详解(总结4)
  • 【python实操】python小程序之TestSuite和TestRunner
  • C语言二维数组的遍历 Java的强制转换和隐形转换
  • 人脸识别之疲劳检测
  • 集合框架11:泛型集合
  • 忙碌的工作和生活,地平线8号探界者商务背包伴左右
  • 【CAN 应用编程】SocketCan实战
  • Halcon基础-二维码识别
  • Java:类和对象
  • 【前端】Matter:基础概念与入门
  • 双指针 — 复写零
  • Java集合(2 :List)
  • 【工具变量】上市公司当年是否发生财务重述指标整理Stata代码(2000-2023年)
  • 【即见未来,为何不拜】聊聊分布式系统中的故障监测机制——Phi Accrual failure detector
  • [0633].第3-3节:@SentinueResource注解
  • nequip代码