2020-11-27

开车时双眼疲劳侦测报警检测:python联合来实现

转:https://www.toutiao.com/i6899377526662038029/?is_new_connect=0&is_new_user=0

1 说明

=====

1.1 高速上开车容易疲劳,双眼就会闭合,几秒钟可能诱发意外,甚至造成严重事故!

1.2 既然python这么厉害,是不是可以实现报警呢?当然可以!!所以高速交警一旦发现驾驶员有双眼闭合代表疲劳,可能就会直接拨打司机的电话,告知提醒驾驶员已经疲劳,危险驾驶,建议下一个服务区强制休息,以免意外发生。

1.3 当然上述太麻烦了,可以生成一个成品,自己放在自己的汽车上,摄像头对准自己的面部,一旦自己闭眼就会报警,一个小小的新科技产品从此就诞生了!!汽车生产制造商们注意了,可以卖钱哟。取个名字叫开始防眯眼警报狗!!哈哈哈。

开车时双眼疲劳侦测报警检测:python联合来实现

 

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 图

开车时双眼疲劳侦测报警检测:python联合来实现

 

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,别忘了给他点个星星。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值