简介:

dlib库是一个很经典的用于图像处理的开源库,shape_predictor_68_face_landmarks.dat是一个用于人脸68个关键点检测的dat模型库,使用这个模型库可以很方便地进行人脸检测,并进行简单的应用。

简单实现一下疲劳检测功能,对视频中每帧图片检测眼睛长/宽的值是否大于阈值,连续超过50次则认为已经“睡着”,阈值的获取方式是:先采集30次数据,取其平均值作为默认的值。为了数据的准确,采集数据时应该平视摄像头。

(不过仅通过检测眼睛是否闭合来判断是否疲劳存在很多误差,也因为受各方面干扰比较难处理,最准确的大概是检测生理信息吧,然而检测生理信息又很不实用_(:з)∠)_。。。)

人脸68个特征点分布图:

人脸68个特征点模型库shape_predictor_68_face_landmarks.dat下载地址:

https://pan.baidu.com/s/133Rk9f7iWAF2WApl-a69-A   密码:sl19

python代码实现:

from scipy.spatial import distance as dis
from imutils.video import VideoStream
from imutils import face_utils
from threading import Thread
import numpy as np
import pyglet
import argparse
import imutils
import time
import dlib
import cv2 #计算嘴的长宽比,euclidean(u, v, w=None)用于计算两点的欧几里得距离
def mouthRatio(mouth):
left=dis.euclidean(mouth[2],mouth[10])
mid=dis.euclidean(mouth[3],mouth[9])
right=dis.euclidean(mouth[4],mouth[8])
horizontal=dis.euclidean(mouth[0],mouth[6])
return 10.0*horizontal/(3.0*left+4.0*mid+3.0*right) #计算眼睛的长宽比
def eyesRatio(eye):
left = dis.euclidean(eye[1], eye[5])
right = dis.euclidean(eye[2], eye[4])
horizontal = dis.euclidean(eye[0], eye[3])
return 2.0*horizontal/(left+right) #创建一个解析对象,向该对象中添加关注的命令行参数和选项,然后解析
ap = argparse.ArgumentParser()
ap.add_argument("-w", "--webcam", type=int, default=0)
args = vars(ap.parse_args()) #眼睛长宽比的阈值,如果超过这个值就代表眼睛长/宽大于采集到的平均值,默认已经"闭眼"
eyesRatioLimit=0
#数据采集的计数,采集30次然后取平均值
collectCount=0
#用于数据采集的求和
collectSum=0
#是否开始检测
startCheck=False #统计"闭眼"的次数
eyesCloseCount=0 #初始化dlib
detector=dlib.get_frontal_face_detector()
predictor=dlib.shape_predictor("68_face_landmarks.dat") #获取面部各器官的索引
#左右眼
(left_Start,left_End)=face_utils.FACIAL_LANDMARKS_IDXS["left_eye"]
(right_Start,right_End)=face_utils.FACIAL_LANDMARKS_IDXS["right_eye"]
#嘴
(leftMouth,rightMouth)=face_utils.FACIAL_LANDMARKS_IDXS['mouth']
#下巴
(leftJaw,rightJaw)=face_utils.FACIAL_LANDMARKS_IDXS['jaw']
#鼻子
(leftNose,rightNose)=face_utils.FACIAL_LANDMARKS_IDXS['nose']
#左右眉毛
(left_leftEyebrow,left_rightEyebrow)=face_utils.FACIAL_LANDMARKS_IDXS['left_eyebrow']
(right_leftEyebrow,right_rightEyebrow)=face_utils.FACIAL_LANDMARKS_IDXS['right_eyebrow'] #开启视频线程,延迟2秒钟
vsThread=VideoStream(src=args["webcam"]).start()
time.sleep(2.0) #循环检测
while True:
#对每一帧进行处理,设置宽度并转化为灰度图
frame = vsThread.read()
frame = imutils.resize(frame, width=720)
img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) #检测灰度图中的脸
faces = detector(img, 0)
for k in faces:
#确定面部区域的面部特征点,将特征点坐标转换为numpy数组
shape = predictor(img, k)
shape = face_utils.shape_to_np(shape) #左右眼
leftEye = shape[left_Start:left_End]
rightEye = shape[right_Start:right_End]
leftEyesVal = eyesRatio(leftEye)
rightEyesVal = eyesRatio(rightEye)
#凸壳
leftEyeHull = cv2.convexHull(leftEye)
rightEyeHull = cv2.convexHull(rightEye)
#绘制轮廓
cv2.drawContours(frame, [leftEyeHull], -1, (0, 255, 0), 1)
cv2.drawContours(frame, [rightEyeHull], -1, (0, 255, 0), 1)
#取两只眼长宽比的的平均值作为每一帧的计算结果
eyeRatioVal = (leftEyesVal + rightEyesVal) / 2.0 #嘴
mouth=shape[leftMouth:rightMouth]
mouthHull=cv2.convexHull(mouth)
cv2.drawContours(frame, [mouthHull], -1, (0, 255, 0), 1) #鼻子
nose=shape[leftNose:rightNose]
noseHull=cv2.convexHull(nose)
cv2.drawContours(frame, [noseHull], -1, (0, 255, 0), 1) #下巴
jaw=shape[leftJaw:rightJaw]
jawHull=cv2.convexHull(jaw)
cv2.drawContours(frame, [jawHull], -1, (0, 255, 0), 1) #左眉毛
leftEyebrow=shape[left_leftEyebrow:left_rightEyebrow]
leftEyebrowHull=cv2.convexHull(leftEyebrow)
cv2.drawContours(frame, [leftEyebrowHull], -1, (0, 255, 0), 1) #右眉毛
rightEyebrow=shape[right_leftEyebrow:right_rightEyebrow]
rightEyebrowHull=cv2.convexHull(rightEyebrow)
cv2.drawContours(frame, [rightEyebrowHull], -1, (0, 255, 0), 1) if collectCount<30:
collectCount+=1
collectSum+=eyeRatioVal
cv2.putText(frame, "DATA COLLECTING", (300, 30),cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)
startCheck=False
else:
if not startCheck:
eyesRatioLimit=collectSum/(1.0*30)
print('眼睛长宽比均值',eyesRatioLimit)
startCheck=True if startCheck:
#如果眼睛长宽比大于之前检测到的阈值,则计数,闭眼次数超过50次则认为已经"睡着"
if eyeRatioVal > eyesRatioLimit:
eyesCloseCount += 1
if eyesCloseCount >= 50:
cv2.putText(frame, "SLEEP!!!", (580, 30),cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)
else:
eyesCloseCount = 0
print('眼睛实时长宽比:{:.2f} '.format(eyeRatioVal))
#眼睛长宽比
cv2.putText(frame, "EYES_RATIO: {:.2f}".format(eyeRatioVal), (20, 30),cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 160, 0), 2)
#闭眼次数
cv2.putText(frame,"EYES_COLSE: {}".format(eyesCloseCount),(320,30),cv2.FONT_HERSHEY_SIMPLEX,0.6,(0,160,0),2) #通过检测嘴的长宽比检测有没有打哈欠,后来觉得没什么卵用
#cv2.putText(frame,"MOUTH_RATIO: {:.2f}".format(mouthRatio(mouth)),(30, 30),cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) cv2.imshow("Frame", frame)
key = cv2.waitKey(1) & 0xFF
#停止
if key == ord("S"): break cv2.destroyAllWindows()
vsThread.stop()

检测结果:

dlib库检测人脸使用方法与简单的疲劳检测应用的更多相关文章

  1. 人脸识别之Python DLib库进行人脸关键点识别

    一.首先安装DLib模块 这里只介绍linux安装的过程,windows安装过程请自行百度 1.首先,安装dlib.skimage前:先安装libboost sudo apt-get install ...

  2. 使用dlib自带的面向梯度直方图(HOG)和线性分类器方法来检测人脸

    之前使用opencv里面CascadeClassifier(级联分类器)来识别人脸, 下面使用dlib库来实现人脸识别. dlib是一个开源的库,它包含了很多内容有机器学习,图像处理,数值算法等等. ...

  3. Dlib库中实现正脸人脸关键点(landmark)检测的测试代码

    Dlib库中提供了正脸人脸关键点检测的接口,这里参考dlib/examples/face_landmark_detection_ex.cpp中的代码,通过调用Dlib中的接口,实现正脸人脸关键点检测的 ...

  4. Dlib库中实现正脸人脸检测的测试代码

    Dlib库中提供了正脸人脸检测的接口,这里参考dlib/examples/face_detection_ex.cpp中的代码,通过调用Dlib中的接口,实现正脸人脸检测的测试代码,测试代码如下: #i ...

  5. HAAR与DLib的实时人脸检测之实现与对比

    人脸检测方法有许多,比如opencv自带的人脸Haar特征分类器和dlib人脸检测方法等. 对于opencv的人脸检测方法,优点是简单,快速:存在的问题是人脸检测效果不好.正面/垂直/光线较好的人脸, ...

  6. Python 3 利用 Dlib 实现摄像头人脸检测特征点标定

    0. 引言 利用 Python 开发,借助 Dlib 库捕获摄像头中的人脸,进行实时人脸 68 个特征点标定: 支持多张人脸: 有截图功能: 图 1 工程效果示例( gif ) 图 2 工程效果示例( ...

  7. 使用dlib基于CNN(卷积神经网络)的人脸检测器来检测人脸

    基于机器学习CNN方法来检测人脸比之前介绍的效率要慢很多 需要先下载一个训练好的模型数据: 地址点击下载 // dlib_cnn_facedetect.cpp: 定义控制台应用程序的入口点. // # ...

  8. Python 3.6.3 利用Dlib 19.7库进行人脸识别

    0.引言 自己在下载dlib官网给的example代码时,一开始不知道怎么使用,在一番摸索之后弄明白怎么使用了: 现分享下 face_detector.py 和 face_landmark_detec ...

  9. 机器学习进阶-人脸关键点检测 1.dlib.get_frontal_face_detector(构建人脸框位置检测器) 2.dlib.shape_predictor(绘制人脸关键点检测器) 3.cv2.convexHull(获得凸包位置信息)

    1.dlib.get_frontal_face_detector()  # 获得人脸框位置的检测器, detector(gray, 1) gray表示灰度图, 2.dlib.shape_predict ...

随机推荐

  1. 业务基类对象BaseBLL

    using System; using System.Collections; using System.Data; using System.Text; using System.Collectio ...

  2. NIO浅析(一)

    一:NIO与IO的区别 1.NIO面对的是缓冲区,IO面对的是流 2.NIO是非阻塞的,IO是阻塞的 3.NIO中引入了选择器 二:既然NIO面对的是缓冲区,那就先来了解缓冲区 1.NIO中Buffe ...

  3. vue中checkbox 样式自定义重写;循环遍历checkbox,拿到不同的v-model绑定值;及获取当前checked 状态,全选和全不选等功能。

    开始写这个功能,不得不吐槽原始的checkbox,灰色小方块的丑陋,虽说eleUI,mintUI,等各种框架的单复选框已经对其优化,但还是不想要这种.那我们就来研究一下怎么处理它. <secti ...

  4. Error(10028):Can't resolve multiple constant drivers for net “ ” at **.v

    两个进程里都有同一个条件判断的话,会产生并行信号冲突的问题. 同一个信号不允许在多个进程中赋值,否则则为多驱动. 进程的并行性决定了多进程不同能对同一个对象进行赋值.

  5. javascript中var同时声明多个变量时的原理是什么?

    <script> function show(){ var a=b=c=d=5; } show(); alert(a);//弹a时报错(not defined),而b.c.d都能弹出5 & ...

  6. org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported

    最后找到我的问题,springmvc配置文件中没加 <mvc:annotation-driven/> java代码: @RequestMapping(value="/reques ...

  7. JS window对象 Location对象 location用于获取或设置窗体的URL,并且可以用于解析URL。 语法: location.[属性|方法]

    Location对象 location用于获取或设置窗体的URL,并且可以用于解析URL. 语法: location.[属性|方法] location对象属性图示: location 对象属性: lo ...

  8. javaSE Comparable接口中的compareTo()方法

    我们都知道,要对自建对象按照一定规则进行排序的话,要求自建对象实现Comparable接口,并重写compareTo() 方法,但compareTo() 方法的释义却不是那么容易搞清楚,下面举例进行阐 ...

  9. 【Luogu】【关卡2-11】简单数学问题(2017年10月)【还差三道题】

    火星人 麦森数 P1403 [AHOI2005]约数研究 f(n)表示n的约数个数,现在给出n,要求求出f(1)到f(n)的总和. 解答:有几个1做约数的个数 = n /1; 有几个2做约数的个数 = ...

  10. QList和QVector等容器的区别:(转)

    源地址:https://blog.csdn.net/qq_33266987/article/details/53333373 Qlist.QVector 与 list.vector似乎不太类似: li ...