OpenCV/Python/dlib眨眼检测

1. 云栖社区>
2. 翻译小组>
3. 博客>
4. 正文

## OpenCV/Python/dlib眨眼检测

【方向】 2018-01-07 10:47:12 浏览3567 评论0

OpenCVPythondlib进行眼睛眨眼检测

1.了解眼睛横比EAR

SoukupováČech在其2016年的论文“使用面部标志实时眼睛眨眼检测的工作，我们可以推导出反映这种关系的方程，称为眼睛纵横比（EAR）：

2.用面部志和OpenCV检测眨眼（代码篇）

``````# import the necessary packages
from scipy.spatial import distance as dist
from imutils.video import FileVideoStream
from imutils.video import VideoStream
from imutils import face_utils
import numpy as np
import argparse
import imutils
import time
import dlib
import cv2
``````

``````def eye_aspect_ratio(eye):
# compute the euclidean distances between the two sets of
# vertical eye landmarks (x, y)-coordinates
A = dist.euclidean(eye[1], eye[5])
B = dist.euclidean(eye[2], eye[4])
# compute the euclidean distance between the horizontal
# eye landmark (x, y)-coordinates
C = dist.euclidean(eye[0], eye[3])
# compute the eye aspect ratio
ear = (A + B) / (2.0 * C)
# return the eye aspect ratio
return ear
``````

A，B是计算两组垂直眼睛标志之间的距离，而C是计算水平眼睛标志之间的距离。

``````# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
help="path to facial landmark predictor")
help="path to input video file")
args = vars(ap.parse_args())
``````

1.--shape-predictordlib预训练面部检测器的路径。

2.--video：它控制留在磁上的视频文件的路径。如果您想要使用实时视频流需在行脚本省略此开关。

``````# define two constants, one for the eye aspect ratio to indicate
# blink and then a second constant for the number of consecutive
# frames the eye must be below the threshold
EYE_AR_THRESH = 0.3
EYE_AR_CONSEC_FRAMES = 3
# initialize the frame counters and the total number of blinks
COUNTER = 0
TOTAL = 0
``````

``````# initialize dlib's face detector (HOG-based) and then create
# the facial landmark predictor
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(args["shape_predictor"])
``````

dlib库使用一个预先训练的人脸检测器，该检测器基于对用于对象检测的定向梯度直方图+线性SVM方法的修改。然后，我们初始化的实际面部标志预测值predictor。

``````# grab the indexes of the facial landmarks for the left and
# right eye, respectively
(lStart, lEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"]
(rStart, rEnd) = face_utils.FACIAL_LANDMARKS_IDXS["right_eye"]
``````

``````# start the video stream thread
vs = FileVideoStream(args["video"]).start()
fileStream = True
# vs = VideoStream(src=0).start()
# vs = VideoStream(usePiCamera=True).start()
# fileStream = False
time.sleep(1.0)
``````

Raspberry Pi相机模块，取消注释：# vs = VideoStream(usePiCamera=True).start()

``````# loop over frames from the video stream
while True:
# if this is a file video stream, then we need to check if
# there any more frames left in the buffer to process
if fileStream and not vs.more():
break
# grab the frame from the threaded video file stream, resize
# it, and convert it to grayscale
# channels)
frame = imutils.resize(frame, width=450)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# detect faces in the grayscale frame
rects = detector(gray, 0)
``````

while我们开始从视频流循环帧。

``````# loop over the face detections
for rect in rects:
# determine the facial landmarks for the face region, then
# convert the facial landmark (x, y)-coordinates to a NumPy
# array
shape = predictor(gray, rect)
shape = face_utils.shape_to_np(shape)
# extract the left and right eye coordinates, then use the
# coordinates to compute the eye aspect ratio for both eyes
leftEye = shape[lStart:lEnd]
rightEye = shape[rStart:rEnd]
leftEAR = eye_aspect_ratio(leftEye)
rightEAR = eye_aspect_ratio(rightEye)
# average the eye aspect ratio together for both eyes
ear = (leftEAR + rightEAR) / 2.0
``````

shape确定面部区域的面部标志，接着将这些（x，y）坐标转换成NumPy阵列。

``````# compute the convex hull for the left and right eye, then
# visualize each of the eyes
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)
``````

``````# check to see if the eye aspect ratio is below the blink
# threshold, and if so, increment the blink frame counter
if ear < EYE_AR_THRESH:
COUNTER += 1
# otherwise, the eye aspect ratio is not below the blink
# threshold
else:
# if the eyes were closed for a sufficient number of
# then increment the total number of blinks
if COUNTER >= EYE_AR_CONSEC_FRAMES:
TOTAL += 1
# reset the eye frame counter
COUNTER = 0
``````

``````# draw the total number of blinks on the frame along with
# the computed eye aspect ratio for the frame
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
cv2.putText(frame, "EAR: {:.2f}".format(ear), (300, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
# show the frame
cv2.imshow("Frame", frame)
key = cv2.waitKey(1) & 0xFF
# if the `q` key was pressed, break from the loop
if key == ord("q"):
break
# do a bit of cleanup
cv2.destroyAllWindows()
vs.stop()
``````

3.眨眼检测结

--shape-predictor shape_predictor_68_face_landmarks.dat \

``````\$python detect_blinks.py \
--shape-predictor shape_predictor_68_face_landmarks.dat
``````

4.的眨眼检测

【云栖快讯】诚邀你用自己的技术能力来用心回答每一个问题，通过回答传承技术知识、经验、心得，问答专家期待你加入！  详情请点击

### 网友评论

【方向】

RDS是一种稳定可靠、可弹性伸缩的在线数据库服务。支持MySQL、SQL Server、Po... 查看详情