疲劳检测_驾驶员疲劳检测设计Opencv完整代码实战
疲劳检测_驾驶员疲劳检测设计Opencv完整代码实战
·
第一步:疲劳检测实现原理介绍
1.检测到人脸
2.获取人脸关键点
3.根据人脸关键点判断脸部的情况
更加详细的介绍可以参考这篇博客:
疲劳检测-闭眼检测(详细代码教程)_驾驶员疲劳检测设计完整代码-CSDN博客

第二步:代码展示
# 从视频流循环帧
while True:
# 第五步:进行循环,读取图片,并对图片做维度扩大,并进灰度化
ret, frame = cap.read()
frame = imutils.resize(frame, width=720)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 第六步:使用detector(gray, 0) 进行脸部位置检测
rects = detector(gray, 0)
# 第七步:循环脸部位置信息,使用predictor(gray, rect)获得脸部特征位置的信息
for rect in rects:
shape = predictor(gray, rect)
# 第八步:将脸部特征信息转换为数组array的格式
shape = face_utils.shape_to_np(shape)
# 第九步:提取左眼和右眼坐标
leftEye = shape[lStart:lEnd]
rightEye = shape[rStart:rEnd]
# 嘴巴坐标
mouth = shape[mStart:mEnd]
# 第十步:构造函数计算左右眼的EAR值,使用平均值作为最终的EAR
leftEAR = eye_aspect_ratio(leftEye)
rightEAR = eye_aspect_ratio(rightEye)
ear = (leftEAR + rightEAR) / 2.0
# 打哈欠
mar = mouth_aspect_ratio(mouth)
# 第十一步:使用cv2.convexHull获得凸包位置,使用drawContours画出轮廓位置进行画图操作
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)
mouthHull = cv2.convexHull(mouth)
cv2.drawContours(frame, [mouthHull], -1, (0, 255, 0), 1)
# 第十二步:进行画图操作,用矩形框标注人脸
left = rect.left()
top = rect.top()
right = rect.right()
bottom = rect.bottom()
cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 1)
'''
分别计算左眼和右眼的评分求平均作为最终的评分,如果小于阈值,则加1,如果连续3次都小于阈值,则表示进行了一次眨眼活动
'''
# 第十三步:循环,满足条件的,眨眼次数+1
if ear < EYE_AR_THRESH: # 眼睛长宽比:0.2
COUNTER += 1
else:
# 如果连续3次都小于阈值,则表示进行了一次眨眼活动
if COUNTER >= EYE_AR_CONSEC_FRAMES: # 阈值:3
TOTAL += 1
# 重置眼帧计数器
COUNTER = 0
# 第十四步:进行画图操作,同时使用cv2.putText将眨眼次数进行显示
cv2.putText(frame, "Faces: {}".format(len(rects)), (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
cv2.putText(frame, "COUNTER: {}".format(COUNTER), (150, 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)
cv2.putText(frame, "Blinks: {}".format(TOTAL), (450, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 0), 2)
'''
计算张嘴评分,如果小于阈值,则加1,如果连续3次都小于阈值,则表示打了一次哈欠,同一次哈欠大约在3帧
'''
# 同理,判断是否打哈欠
if mar > MAR_THRESH: # 张嘴阈值0.5
mCOUNTER += 1
cv2.putText(frame, "Yawning!", (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
else:
# 如果连续3次都小于阈值,则表示打了一次哈欠
if mCOUNTER >= MOUTH_AR_CONSEC_FRAMES: # 阈值:3
mTOTAL += 1
# 重置嘴帧计数器
mCOUNTER = 0
cv2.putText(frame, "COUNTER: {}".format(mCOUNTER), (150, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
cv2.putText(frame, "MAR: {:.2f}".format(mar), (300, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
cv2.putText(frame, "Yawning: {}".format(mTOTAL), (450, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 0), 2)
"""
瞌睡点头
"""
# 第十五步:获取头部姿态
reprojectdst, euler_angle = get_head_pose(shape)
har = euler_angle[0, 0] # 取pitch旋转角度
if har > HAR_THRESH: # 点头阈值0.3
hCOUNTER += 1
else:
# 如果连续3次都小于阈值,则表示瞌睡点头一次
if hCOUNTER >= NOD_AR_CONSEC_FRAMES: # 阈值:3
hTOTAL += 1
# 重置点头帧计数器
hCOUNTER = 0
# 绘制正方体12轴
# for start, end in line_pairs:
# cv2.line(frame, reprojectdst[start], reprojectdst[end], (0, 0, 255))
# 显示角度结果
cv2.putText(frame, "X: " + "{:7.2f}".format(euler_angle[0, 0]), (10, 90), cv2.FONT_HERSHEY_SIMPLEX, 0.75,
(0, 255, 0), thickness=2) # GREEN
cv2.putText(frame, "Y: " + "{:7.2f}".format(euler_angle[1, 0]), (150, 90), cv2.FONT_HERSHEY_SIMPLEX, 0.75,
(255, 0, 0), thickness=2) # BLUE
cv2.putText(frame, "Z: " + "{:7.2f}".format(euler_angle[2, 0]), (300, 90), cv2.FONT_HERSHEY_SIMPLEX, 0.75,
(0, 0, 255), thickness=2) # RED
cv2.putText(frame, "Nod: {}".format(hTOTAL), (450, 90), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 0), 2)
# 第十六步:进行画图操作,68个特征点标识
for (x, y) in shape:
cv2.circle(frame, (x, y), 1, (0, 0, 255), -1)
print('嘴巴实时长宽比:{:.2f} '.format(mar) + "\t是否张嘴:" + str([False, True][mar > MAR_THRESH]))
print('眼睛实时长宽比:{:.2f} '.format(ear) + "\t是否眨眼:" + str([False, True][COUNTER >= 1]))
# 确定疲劳提示:眨眼50次,打哈欠15次,瞌睡点头15次
if TOTAL >= 50 or mTOTAL >= 15 or hTOTAL >= 15:
cv2.putText(frame, "SLEEP!!!", (100, 200), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 3)
# 按q退出
cv2.putText(frame, "Press 'q': Quit", (20, 500), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (84, 255, 159), 2)
# 窗口显示 show with opencv
cv2.imshow("Frame", frame)
# if the `q` key was pressed, break from the loop
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放摄像头 release camera
cap.release()
# do a bit of cleanup
cv2.destroyAllWindows()
第三步:搭建GUI界面
具体功能包括,摄像头和视频流识别的功能


第四步:整个工程的内容

项目完整文件下载请见演示与介绍视频的简介处给出:➷➷➷
https://www.bilibili.com/video/BV1SrSuY6EwJ/

更多推荐
所有评论(0)