|
楼主 |
发表于 2020-4-5 20:20:55
|
显示全部楼层
import numpy as np#1.导入各模块
import cv2
import dlib
from scipy.spatial import distance
import os
from imutils import face_utils
import matplotlib.pyplot as plt
import winsound
def eye_aspect_ratio(eye):#2.计算EAR模块
A = distance.euclidean(eye[1], eye[5])
B = distance.euclidean(eye[2], eye[4])
C = distance.euclidean(eye[0], eye[3])
ear = (A + B) / (2.0 * C)
return ear
#3.导入检测器模块
pwd = os.getcwd()#获取当前路劲
model_path = os.path.jion(pwd,'model')#模型文件夹路劲
shape_detector_path = os.path.join(model_path,'shape_predictor_68_face_landmarks.dat')#人脸特征点检测模型路劲
detector = dlib.get_frontal_face_detector()#人脸检测器
predictor = dlib.shape_predictor(shape_detector_path)#人脸特征点检测器
#4.定义各模块
EYE_EAR = 0.15# EAR阈值
EYE_EAR_BEYOND_TIME = 30#设置眨眼超过时间,累计眨眼次数
EYE_EAR_WARNIG = 2#设置眨眼超时次数超过次数,给予提醒警告
WARNIG = 0
RIGHT_EYE_START = 37 - 1#对应特征点的序号
RIGHT_EYE_END = 42 - 1
LEFT_EYE_START = 43 - 1
LEFT_EYE_END = 48 - 1
frame_counter = 0#连续帧计数
blink_counter = 0#眨眼计数
duration = 1000#眨眼超过持续时间
duration2 = 5000#警告持续时间
freq = 440#报警声频率
#5.启动模块
ey = []# 定义一个Y轴的空列表来接受动态的数据
plt.ion()#开启一个画图窗口
leftEAR_TXT = open("data/leftEAR.txt","w")# 打开保存data的文本
rightEAR_TXT = open("data/rightEAR.txt","w")
EAR_TXT = open("data/ear.txt","w")
#6.视频流处理模块
cap = cv2.VideoCapture(0)#导入视频流,0是本地摄像头导入视频
while(1):
ret, img = cap.read()#读取视频流的一帧
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转换为灰阶
rects = detector(gray, 0)#人脸检测
for rect in rects:
shape = predictor(gray, rect)#检测特征点
points = face _utils.shape_to_np(shape)#将面部界标(x,y)坐标转换为Numpy数组
letfEye = points[LEFT_EYE_START:LEFT_EYE_END + 1]#取出特征点
rightEye = points[RIGHT_EYE_START:RIGHT_EYE_END + 1]
leftEAR = eye_aspect_ratio(leftEye)#计算左右眼
rightEAR = eye_aspect_ratio(rightEye)
ear = (leftEAR + rightEAR) / 2.0 #求平均EAR
leftEyeHull = cv2.convexHull(lfetEye)#寻找轮廓
rightEyeHull = cv2.convexHull(rightEye)
cv2.drawContours(img,[leftEyeHull], -1,(192,255,62),1)#绘制轮廓
cv2.drawContours(img,[rightEyeHull], -1,(192,255,62),1)
if ear < EYE_EAR : #如果EAR小于阈值,开始累积连续眨眼次数
frame_counter += 1
else:
if frame_counter >= EYE_EAR_BEYOND_TIME:#连续帧数超过EYE_EAR_BEYOND_TIME的帧数时,累加超市次数
winsound.Beep(freq,duration1)# 提示报警声
blink_counter += 1
frame_counter = 0
if blink_counter >= EYE_EAR_WARNIG:#连续帧计数超过EYE_EAR_WARNIG帧数时,给WARING+1(警告次数)
winsound.Beep(freq, duration2)#长时间报警声
WARNIG += 1
blink_counter = 0
#7.输出显示模块
#在图像上显示EAR的值,Exceeding-number超过次数,WARNIG警告次数
cv2.putText(img, "WARNIG!:{0}".format(WARNIG),(250, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7,(0,0,0), 2)
cv2.putText(img, "Exceeding-number:{0}".format(blink_counter),(250, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.7,(0,0,0), 2)
cv2.putText(img, "EAR:{:.2f}".format(ear), (250, 90), cv2.FONT_HERSHEY_SIMPLEX, 0.7,(0,0,0), 2)
print('leftEAR = {0}'.format(leftEAR))#直接输出值
print('rightEAR = {0}'.format(rightEAR))
print('ear = {0}'.format(ear))
print('-'*20)
ey.append(ear)#添加i的平方到y轴的数据中
plt.clf()#清除之前画的图
plt.plot(ey)#画出当前值得图像
plt.pause(0.1)#暂停一秒
#8.数据保存模块
print('{0}'.format(leftEAR),file=leftEAR_TXT)#保存左右眼EAR的数据
print('{0}'.format(rightEAR),file=rightEAR_TXT)
print('{0}'.format(ear),file=EAR_TXT)
#9.退出模块
cv2.imshow("KZero", img)#显示视频窗口
if cv2.waitKey(1) & 0xFF == 27:#按esc退出
break
plt.ioff()#关闭画图的窗口
cap.release()
cv2.destritAllWindows() |
|