zoukankan      html  css  js  c++  java
  • 机器学习进阶-疲劳检测(眨眼检测) 1.dist.eculidean(计算两个点的欧式距离) 2.dlib.get_frontal_face_detector(脸部位置检测器) 3.dlib.shape_predictor(脸部特征位置检测器) 4.Orderdict(构造有序的字典)

    1.dist.eculidean(A, B) # 求出A和B点的欧式距离

    参数说明:A,B表示位置信息

    2.dlib.get_frontal_face_detector()表示脸部位置检测器

    3.dlib.shape_predictor(args['shape_predictor]) 表示脸部特征位置检测器

    参数说明:args['shape_predictor'] 表示位置信息

    4.Orderdict([('mouth', (23, 30))])  # 构造有序的字典
    参数说明:'mouth'表示字典的键,(23, 30) 表示字典的值

    使用人脸检测可以获得人脸框的位置信息,再使用人脸框的关键点检测,检测出各个人脸部分的位置

    眨眼检测:主要是通过检测脸部6个点,即 A = dist.euclidean(eye[2], eye[4]), 即眼部的2号点与4号点的欧式距离

    B = dist.euclidean(eye[1], eye[5]) C = dist.euclidean(eye[0], eye[3])  # 即1号点与5号点的位置, 0号点与3号点的欧式距离

    EAR = (A + B) / 2 * C, 分别计算左眼和右眼的评分求平均作为最终的评分,如果小于阈值,则加1,如果连续3次都小于阈值,则表示进行了一次眨眼活动

    代码:

    第一步:使用OrderedDict() 构建有序的脸部位置序号字典

    第二步:使用argparse构造出可以传入的参数

    第三步:使用dlib.get_frontal_face_detector()获得脸部位置检测器

    第四步:使用dlib.shape_predictor构造脸部特征检测器

    第五步:进入循环,读取图片,对图片维度进行扩大,方便进行脸部特征检测,同时进行灰度化,为了脸部特征检测做准备

    第六步:使用detector(gray, 0) 进行脸部位置检测

    第七步:循环脸部位置,使用predictor(gray, rect)获得脸部特征的位置信息

    第八步:将脸部特征的位置信息转换为数组的形式

    第九步:根据字典的序号,获得左眼和右眼的位置array

    第十步:使用cv2.convexHull构造左右眼的凸包,并使用cv2.drawContours完成画图操作

    第十一步:构造函数计算左右眼的EAR值,使用平均值作为最终的EAR

    第十二步:循环,满足条件的,眨眼次数+1

    第十三步:进行画图操作,同时使用cv2.putText将眨眼次数进行显示

    import cv2
    import numpy as np
    import argparse
    import time
    import dlib
    from scipy.spatial import distance as dist
    from collections import  OrderedDict
    
    def shape_to_array(shape, dtype='int'):
        coords = np.zeros((shape.num_parts, 2), dtype=dtype)
        for i in range(shape.num_parts):
            coords[i] = (shape.part(i).x, shape.part(i).y)
    
        return coords
    
    def accu_angle_eye(eye):
        A = dist.euclidean(eye[1], eye[5])
        B = dist.euclidean(eye[2], eye[4])
        # 计算距离,水平的
        C = dist.euclidean(eye[0], eye[3])
        aspect_ratio = (A + B) / (2.0 *C)
    
        return aspect_ratio
    
    # 第一步:使用OrderedDict构造脸部特征序号的有序字典
    FACE_LANDMAKE_64_IDEX = OrderedDict([
        ("mouth", (48, 68)),
        ("right_eyebrow", (17, 22)),
        ("left_eyebrow", (22, 27)),
        ("right_eye", (36, 42)),
        ("left_eye", (42, 48)),
        ("nose", (27, 36)),
        ("jaw", (0, 17))
    ])
    # EAR的阈值
    BlINK_THRESH = 0.3
    # 眨眼帧数的阈值
    BLINK_TRUE = 3
    # 低于阈值的次数
    count_blink = 0
    # 眨眼次数
    Total = 0
    # 第二步:使用argparse构造变量参数
    ap = argparse.ArgumentParser()
    ap.add_argument('-p', '--shape-predictor', default='shape_predictor_68_face_landmarks.dat',
                    help='the weight to predictor')
    ap.add_argument('-v', '--video', default='test.mp4',
                    help='the video to read')
    args = vars(ap.parse_args())
    
    # 第三步:使用dlib.get_frontal_face_detector() 获得脸部位置检测器
    detector = dlib.get_frontal_face_detector()
    # 第四步:使用dlib.shape_predictor获得脸部特征检测器
    predictor = dlib.shape_predictor(args['shape_predictor'])
    
    vs = cv2.VideoCapture(args['video'])
    time.sleep(1)
    
    (lstart, lend) = FACE_LANDMAKE_64_IDEX['left_eye']
    (rstart, rend) = FACE_LANDMAKE_64_IDEX['right_eye']
    
    while True:
        # 第五步:进行循环,读取图片,并对图片做维度扩大,并进灰度化
        frame = vs.read()[1]
        (h, w) = frame.shape[:2]
        width = 1200
        r = width / float(w)
        dim = (width, int(r*h))
        frame = cv2.resize(frame, dim, interpolation=cv2.INTER_AREA)
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        # 第六步:使用detector(gray, 0)获得脸部位置信息
        rects = detector(gray, 0)
        # 第七步:循环脸部位置信息,使用predictor(gray, rect)获得脸部特征位置的信息
        for rect in rects:
            shape = predictor(gray, rect)
            # 第八步:将脸部特征信息转换为数组array的格式
            shape = shape_to_array(shape)
            # 第九步:根据字典,获得左眼和右眼的位置信息
            leftEye = shape[lstart:lend]
            rightEye = shape[rstart:rend]
    
            # 第十步:使用cv2.convexHull获得凸包位置,使用drawContours画出轮廓位置进行画图操作
            leftContours = cv2.convexHull(leftEye)
            rightContours = cv2.convexHull(rightEye)
            cv2.drawContours(frame, [leftContours], -1, (0, 255, 0), 1)
            cv2.drawContours(frame, [rightContours], -1, (0, 255, 0), 1)
            # 第十一步:计算左右眼的EAR值,获得其平均值
            leftScore = accu_angle_eye(leftEye)
            rightScore = accu_angle_eye(rightEye)
            meanScore = (leftScore + rightScore) / 2.0
            #第十二步:循环,满足条件,眨眼次数+1
            if meanScore < BlINK_THRESH:
                count_blink += 1
            else:
                if count_blink >= BLINK_TRUE:
                    Total += 1
    
                count_blink = 0
            # 第十三步:进行画图,使用cv2.putText展示眨眼次数
            cv2.putText(frame, 'Blinks: {}'.format(Total), (10, 30),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 1)
            cv2.putText(frame, 'EAR {:.2f}'.format(meanScore), (300, 30),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 1)
        cv2.imshow('frame', frame)
        if cv2.waitKey(10) & 0xff == 27:
            break
    
    vs.release()
    cv2.destroyAllWindows()

                                             效果图

  • 相关阅读:
    python连接mysql数据库(MySQL)
    PHP+Redis 实例【一】点赞 + 热度 上篇
    linux centos7安装phpMyAdmin详解,以及解决各种bug问题
    Linux crontab命令 定时任务 用法详解以及no crontab for root解决办法
    composer安装教程 windows系统 | Linux系统 | mac系统
    CentOS 7.0下使用yum安装MySQL
    Linux PHP多版本切换 超简单办法
    tornado 入门
    Websocket、长连接、循环连接
    阻塞和非阻塞,同步和异步
  • 原文地址:https://www.cnblogs.com/my-love-is-python/p/10464992.html
Copyright © 2011-2022 走看看