开车时双眼疲劳侦测报警检测python联合来实现
1 说明
=====
1.1 高速上开车容易疲劳,双眼就会闭合,几秒钟可能诱发意外,甚至造成严重事故!
1.2 既然python这么厉害,是不是可以实现报警呢?当然可以!!所以高速交警一旦发现驾驶员有双眼闭合代表疲劳,可能就会直接拨打司机的电话,告知提醒驾驶员已经疲劳,危险驾驶,建议下一个服务区强制休息,以免意外发生。
1.3 当然上述太麻烦了,可以生成一个成品,自己放在自己的汽车上,摄像头对准自己的面部,一旦自己闭眼就会报警,一个小小的新科技产品从此就诞生了!!汽车生产制造商们注意了,可以卖钱哟。取个名字叫开始防眯眼警报狗!!哈哈哈。
2 分析
====
2.1 资料来源:竟然有巨大bug(真不该),对代码进行增加,删除,注释,排版和运行调试。https://github.com/raja434/driver-fatigue-detection-system
2.2 对于那个巨大bug,竟然有人去问stackoverflow,也没有解决。https://stackoverflow.com/questions/53579289/run-a-certain-code-while-it-detects-something-python/53579720
2.3 被我这个半路出家的人搞定了!!,分享出来,但是还是感谢原作者。
3 文件
=====
3.1 图
3.2 这个文件从计算机系统中搜索,安装软件复制过来:shape_predictor_68_face_landmarks.dat
3.3 drowsiness_detection.py代码名改为这样比较正规。
3.4 执行:终端输入:python3.8 drowsiness_detection.py --alarm=alarm.wav
3.5 打开摄像头,睁眼识别,如果闭眼一会就会报警;如果继续睁眼,报警声就会停止;如果再闭眼,报警声还会响起......
4 drowsiness_detection.py代码讲解
============================
4.1 导入模块#第1步:导入模块 from scipy.spatial import distance as dist import imutils from imutils.video import VideoStream from imutils import face_utils from threading import Thread import argparse import time import dlib import cv2 import numpy as np import pyglet
没有的模块,这样安装,本机是这样安装sudo pip3.8 install -i https://pypi.tuna.tsinghua.edu.cn/simple xxx
本机环境:python3.8+deepin-linux深度操作系统+微软编辑器vscode;
软件:opencv4.2.0+numpy1.19.4+dlib19.21.99
4.2 #第2步:终端参数构建 ap = argparse.ArgumentParser() #默认为0,就是摄像头获取视频 ap.add_argument("-w", "--webcam", type=int, default=0, help="index of webcam on system") #巨大的bug,原来没有这个的,我自己增加的 ap.add_argument("-a", "--alarm", help="index of alarm on system") args = vars(ap.parse_args())
4.3 eye=眼睛,ear=耳朵,怕误解将ear改为EAR=eye aspect ratio#第3步:函数定义 #报警声函数定义 def sound_alarm(path): # play an alarm sound music = pyglet.resource.media("alarm.wav") #bug,原来未对齐,缩进去了 music.play() pyglet.app.run() #返回双眼睑比率函数测定 def eye_aspect_ratio(eye): A = dist.euclidean(eye[1], eye[5]) B = dist.euclidean(eye[2], eye[4]) C = dist.euclidean(eye[0], eye[3]) # compute the eye aspect ratio=ear,not ear耳朵 #ear = (A + B) / (2.0 * C) EAR = (A + B) / (2.0 * C) #return ear return EAR
4.4 #第4步:参数初始化 EYE_AR_THRESH = 0.3 EYE_AR_CONSEC_FRAMES = 48 COUNTER = 0 ALARM_ON = False #加载dlib的侦测器 print("[INFO] loading facial landmark predictor...") detector = dlib.get_frontal_face_detector() #原来的dat名字都错了,该文件需要自己复制过来 #predictor = dlib.shape_predictor("68 face landmarks.dat") predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat") #获取左右眼的坐标点信息 (lStart, lEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"] (rStart, rEnd) = face_utils.FACIAL_LANDMARKS_IDXS["right_eye"] # start the video stream thread print("[INFO] starting video stream thread...") vs = VideoStream(src=args["webcam"]).start() time.sleep(1.0)
4.5#第5步:循环 # loop over frames from the video stream while True: frame = vs.read() #设定大小 frame = imutils.resize(frame, width=450) #灰度转换 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) #侦测 # detect faces in the grayscale frame rects = detector(gray, 0) # loop over the face detections for rect in rects: shape = predictor(gray, rect) shape = face_utils.shape_to_np(shape) 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 EAR = (leftEAR + rightEAR) / 2.0 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) #修改为大写 #if ear < EYE_AR_THRESH: if EAR < EYE_AR_THRESH: COUNTER += 1 if COUNTER >= EYE_AR_CONSEC_FRAMES: # if the alarm is not on, turn it on if not ALARM_ON: ALARM_ON = True if args["alarm"] != "": #报错,已经上面修改好了 t = Thread(target=sound_alarm, args=(args["alarm"],)) t.deamon = True t.start() # draw an alarm on the frame cv2.putText(frame, "DROWSINESS ALERT!", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) else: COUNTER = 0 ALARM_ON = False #修改为大写 #cv2.putText(frame, "EAR: {:.2f}".format(ear), (300, 30),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 key == ord("q"): break #第6步:收尾和结束 # do a bit of cleanup cv2.destroyAllWindows() vs.stop()
5 我已经亲测过,可行,视频就不上了,人丑没办法。嘻嘻。
自己整理并分享出来,希望大家喜欢,也感谢原作者的github,别忘了给他点个星星。