位置: IT常识 - 正文

【毕业设计】疲劳驾驶检测系统 - python 深度学习(毕业设计烦死了)

编辑:rootadmin
【毕业设计】疲劳驾驶检测系统 - python 深度学习 文章目录0 前言1 课题背景2 实现目标3 当前市面上疲劳驾驶检测的方法4 相关数据集5 基于头部姿态的驾驶疲劳检测5.1 如何确定疲劳状态5.2 算法步骤5.3 打瞌睡判断6 基于CNN与SVM的疲劳检测方法6.1 网络结构6.2 疲劳图像分类训练6.3 训练结果7 最后0 前言

推荐整理分享【毕业设计】疲劳驾驶检测系统 - python 深度学习(毕业设计烦死了),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:“毕业设计”,毕业设计vi,毕业设计vi,毕业设计mv,毕业设计mv,毕业设计vi,毕业设计vi,毕业设计合集,内容如对您有帮助,希望把文章链接给更多的朋友!

🔥 Hi,大家好,这里是丹成学长的毕设系列文章!

🔥 对毕设有任何疑问都可以问学长哦!

这两年开始,各个学校对毕设的要求越来越高,难度也越来越大… 毕业设计耗费时间,耗费精力,甚至有些题目即使是专业的老师或者硕士生也需要很长时间,所以一旦发现问题,一定要提前准备,避免到后面措手不及,草草了事。

为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的新项目是

🚩 基于深度学习的疲劳驾驶检测

🥇学长这里给一个题目综合评分(每项满分5分)

难度系数:4分工作量:4分创新点:3分

🧿 选题指导, 项目分享:

https://gitee.com/yaa-dc/BJH/blob/master/gg/cc/README.md

1 课题背景

关于对疲劳驾驶的研究不在少数, 不少学者从人物面部入手展开。 人类的面部包含着许多不同的特征信息, 例如其中一些比较明显的特征如打哈欠、 闭眼、 揉眼等表情特征可用来作为判断驾驶员是否处于疲劳状态的依据。 随着计算机技术的不断发展, 尤其是在人工智能相关技术勃发的今天, 借助计算机可以快速有效的识别出图片中人脸特征, 对处于当前时刻驾驶员的精神状态做出判断, 并将疲劳预警信息传达给司机, 以保证交通的安全运行, 减少伤亡事故的发生。

2 实现目标

经查阅相关文献,疲劳在人体面部表情中表现出大致三个类型:打哈欠(嘴巴张大且相对较长时间保持这一状态)、眨眼(或眼睛微闭,此时眨眼次数增多,且眨眼速度变慢)、点头(瞌睡点头)。本实验从人脸朝向、位置、瞳孔朝向、眼睛开合度、眨眼频率、瞳孔收缩率等数据入手,并通过这些数据,实时地计算出驾驶员的注意力集中程度,分析驾驶员是否疲劳驾驶和及时作出安全提示。

3 当前市面上疲劳驾驶检测的方法

学长通过对疲劳驾驶在不同方法下研究进展的分析, 可以更清晰的认识的到当下对该问题较为有效的判定方法。 根据研究对象的不同对检测方法进行分类, 具体分类方法如图

基于驾驶员面部特征的检测方法是根据人在疲劳时面部变化来分析此时的精神状态。 人在瞌睡、 疲劳时面部表情与清醒时有着明显的区别。 通过装置在车辆中的摄像头对驾驶员人脸图片的采集, 利用计算机图像处理和模式识别, 可以有效检测驾驶员的疲 劳特征信息, 比较直观的特征有: 打哈欠, 眨眼, 低头等。

4 相关数据集

学长收集的疲劳检测数据集

【毕业设计】疲劳驾驶检测系统 - python 深度学习(毕业设计烦死了)

驾驶疲劳人脸数据库图片来源分为 3 部分, 每部分均包含疲劳、 轻度疲劳和非疲劳三种精神状态类别。 样本数据库共 4800 张图像, 其中疲劳状态有 1622 张数据样本, 轻度疲劳有 1506 张数据样本, 非疲劳状态有 1618 张数据样本。 各部分数据结构如下: 网络采集部分疲劳包含 435 张样本图片, 轻度疲劳状态包含 430 张样本图片, 非疲劳状态包含 432 张样本图片, 共 1297 张样本数据图像; 视频数据库采集部分疲劳状态包含 1037张样本图像, 轻度疲劳状态包含 1030 张样本图片, 非疲劳状态包含 1036 张样本图片,共 3103 张样本数据图像;

5 基于头部姿态的驾驶疲劳检测5.1 如何确定疲劳状态

思路一:可利用姿态估计结果(如Pitch的读数)来判断是否点头及点头幅度

思路二:或用鼻尖处30号点的前后移动值(或是方差,方差表示一个单位时间数据的偏离程度,程度越大,则表示发生点头动作的概率越大、点头幅度越大)

5.2 算法步骤第一步:2D人脸关键点检测;第二步:3D人脸模型匹配;第三步:求解3D点和对应2D点的转换关系;第四步:根据旋转矩阵求解欧拉角。import cv2import dlibimport numpy as npfrom imutils import face_utils"""思路: 第一步:2D人脸关键点检测;第二步:3D人脸模型匹配; 第三步:求解3D点和对应2D点的转换关系;第四步:根据旋转矩阵求解欧拉角。"""# 加载人脸检测和姿势估计模型(dlib)face_landmark_path = 'D:/myworkspace/JupyterNotebook/fatigue_detecting/model/shape_predictor_68_face_landmarks.dat'"""只要知道世界坐标系内点的位置、像素坐标位置和相机参数就可以搞定旋转和平移矩阵(OpenCV自带函数solvePnp())"""# 世界坐标系(UVW):填写3D参考点,该模型参考http://aifi.isr.uc.pt/Downloads/OpenGL/glAnthropometric3DModel.cppobject_pts = np.float32([[6.825897, 6.760612, 4.402142], #33左眉左上角 [1.330353, 7.122144, 6.903745], #29左眉右角 [-1.330353, 7.122144, 6.903745], #34右眉左角 [-6.825897, 6.760612, 4.402142], #38右眉右上角 [5.311432, 5.485328, 3.987654], #13左眼左上角 [1.789930, 5.393625, 4.413414], #17左眼右上角 [-1.789930, 5.393625, 4.413414], #25右眼左上角 [-5.311432, 5.485328, 3.987654], #21右眼右上角 [2.005628, 1.409845, 6.165652], #55鼻子左上角 [-2.005628, 1.409845, 6.165652], #49鼻子右上角 [2.774015, -2.080775, 5.048531], #43嘴左上角 [-2.774015, -2.080775, 5.048531],#39嘴右上角 [0.000000, -3.116408, 6.097667], #45嘴中央下角 [0.000000, -7.415691, 4.070434]])#6下巴角# 相机坐标系(XYZ):添加相机内参K = [6.5308391993466671e+002, 0.0, 3.1950000000000000e+002, 0.0, 6.5308391993466671e+002, 2.3950000000000000e+002, 0.0, 0.0, 1.0]# 等价于矩阵[fx, 0, cx; 0, fy, cy; 0, 0, 1]# 图像中心坐标系(uv):相机畸变参数[k1, k2, p1, p2, k3]D = [7.0834633684407095e-002, 6.9140193737175351e-002, 0.0, 0.0, -1.3073460323689292e+000]# 像素坐标系(xy):填写凸轮的本征和畸变系数cam_matrix = np.array(K).reshape(3, 3).astype(np.float32)dist_coeffs = np.array(D).reshape(5, 1).astype(np.float32)# 重新投影3D点的世界坐标轴以验证结果姿势reprojectsrc = np.float32([[10.0, 10.0, 10.0], [10.0, 10.0, -10.0], [10.0, -10.0, -10.0], [10.0, -10.0, 10.0], [-10.0, 10.0, 10.0], [-10.0, 10.0, -10.0], [-10.0, -10.0, -10.0], [-10.0, -10.0, 10.0]])# 绘制正方体12轴line_pairs = [[0, 1], [1, 2], [2, 3], [3, 0], [4, 5], [5, 6], [6, 7], [7, 4], [0, 4], [1, 5], [2, 6], [3, 7]]def get_head_pose(shape): # 填写2D参考点,注释遵循https://ibug.doc.ic.ac.uk/resources/300-W/ """ 17左眉左上角/21左眉右角/22右眉左上角/26右眉右上角/36左眼左上角/39左眼右上角/42右眼左上角/ 45右眼右上角/31鼻子左上角/35鼻子右上角/48左上角/54嘴右上角/57嘴中央下角/8下巴角 """ # 像素坐标集合 image_pts = np.float32([shape[17], shape[21], shape[22], shape[26], shape[36], shape[39], shape[42], shape[45], shape[31], shape[35], shape[48], shape[54], shape[57], shape[8]]) """ 用solvepnp或sovlepnpRansac,输入3d点、2d点、相机内参、相机畸变,输出r、t之后 用projectPoints,输入3d点、相机内参、相机畸变、r、t,输出重投影2d点 计算原2d点和重投影2d点的距离作为重投影误差 """ # solvePnP计算姿势——求解旋转和平移矩阵: # rotation_vec表示旋转矩阵,translation_vec表示平移矩阵,cam_matrix与K矩阵对应,dist_coeffs与D矩阵对应。 _, rotation_vec, translation_vec = cv2.solvePnP(object_pts, image_pts, cam_matrix, dist_coeffs) # projectPoints重新投影误差 reprojectdst, _ = cv2.projectPoints(reprojectsrc, rotation_vec, translation_vec, cam_matrix,dist_coeffs) reprojectdst = tuple(map(tuple, reprojectdst.reshape(8, 2)))# 以8行2列显示 # 计算欧拉角calc euler angle # 参考https://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#decomposeprojectionmatrix rotation_mat, _ = cv2.Rodrigues(rotation_vec)#罗德里格斯公式(将旋转矩阵转换为旋转向量) pose_mat = cv2.hconcat((rotation_mat, translation_vec))# 水平拼接,vconcat垂直拼接 # eulerAngles –可选的三元素矢量,包含三个以度为单位的欧拉旋转角度 _, _, _, _, _, _, euler_angle = cv2.decomposeProjectionMatrix(pose_mat)# 将投影矩阵分解为旋转矩阵和相机矩阵 return reprojectdst, euler_angledef main(): # return cap = cv2.VideoCapture(0) if not cap.isOpened(): print("Unable to connect to camera.") return # 检测人脸 detector = dlib.get_frontal_face_detector() # 检测第一个人脸的关键点 predictor = dlib.shape_predictor(face_landmark_path) while cap.isOpened(): ret, frame = cap.read() if ret: face_rects = detector(frame, 0) if len(face_rects) > 0: # 循环脸部位置信息,使用predictor(gray, rect)获得脸部特征位置的信息 shape = predictor(frame, face_rects[0]) # 将脸部特征信息转换为数组array的格式 shape = face_utils.shape_to_np(shape) # 获取头部姿态 reprojectdst, euler_angle = get_head_pose(shape) pitch = format(euler_angle[0, 0]) yaw = format(euler_angle[1, 0]) roll = format(euler_angle[2, 0]) print('pitch:{}, yaw:{}, roll:{}'.format(pitch, yaw, roll)) # 标出68个特征点 for (x, y) in shape: cv2.circle(frame, (x, y), 1, (0, 0, 255), -1) # 绘制正方体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]), (20, 20), cv2.FONT_HERSHEY_SIMPLEX,0.75, (0, 0, 255), thickness=2) cv2.putText(frame, "Y: " + "{:7.2f}".format(euler_angle[1, 0]), (20, 50), cv2.FONT_HERSHEY_SIMPLEX,0.75, (0, 0, 255), thickness=2) cv2.putText(frame, "Z: " + "{:7.2f}".format(euler_angle[2, 0]), (20, 80), cv2.FONT_HERSHEY_SIMPLEX,0.75, (0, 0, 255), thickness=2) # 按q退出提示 cv2.putText(frame, "Press 'q': Quit", (20, 450),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (84, 255, 159), 2) # 窗口显示 show with opencv cv2.imshow("Head_Posture", frame) if cv2.waitKey(1) & 0xFF == ord('q'): break # 释放摄像头 release camera cap.release() # do a bit of cleanup cv2.destroyAllWindows()if __name__ == '__main__': main()

5.3 打瞌睡判断

头部姿态判断打瞌睡得到实时头部姿态的旋转角度过后,为头部旋转角度的3个参数Yaw,Pitch和Roll的示意图,驾驶员在打瞌睡时,显然头部会做类似于点头和倾斜的动作.而根据一般人的打瞌睡时表现出来的头部姿态,显然很少会在Yaw上有动作,而主要集中在Pitch和Roll的行为.设定参数阈值为0.3,在一个时间段内10 s内,当I PitchI≥20°或者|Rolll≥20°的时间比例超过0.3时,就认为驾驶员处于打瞌睡的状态,发出预警。

from scipy.spatial import distance as distfrom imutils.video import FileVideoStreamfrom imutils.video import VideoStreamfrom imutils import face_utilsimport numpy as np # 数据处理的库 numpyimport argparseimport imutilsimport timeimport dlibimport cv2import mathimport timefrom threading import Thread,# 世界坐标系(UVW):填写3D参考点,该模型参考http://aifi.isr.uc.pt/Downloads/OpenGL/glAnthropometric3DModel.cppobject_pts = np.float32([[6.825897, 6.760612, 4.402142], #33左眉左上角 [1.330353, 7.122144, 6.903745], #29左眉右角 [-1.330353, 7.122144, 6.903745], #34右眉左角 [-6.825897, 6.760612, 4.402142], #38右眉右上角 [5.311432, 5.485328, 3.987654], #13左眼左上角 [1.789930, 5.393625, 4.413414], #17左眼右上角 [-1.789930, 5.393625, 4.413414], #25右眼左上角 [-5.311432, 5.485328, 3.987654], #21右眼右上角 [2.005628, 1.409845, 6.165652], #55鼻子左上角 [-2.005628, 1.409845, 6.165652], #49鼻子右上角 [2.774015, -2.080775, 5.048531], #43嘴左上角 [-2.774015, -2.080775, 5.048531],#39嘴右上角 [0.000000, -3.116408, 6.097667], #45嘴中央下角 [0.000000, -7.415691, 4.070434]])#6下巴角# 相机坐标系(XYZ):添加相机内参K = [6.5308391993466671e+002, 0.0, 3.1950000000000000e+002, 0.0, 6.5308391993466671e+002, 2.3950000000000000e+002, 0.0, 0.0, 1.0]# 等价于矩阵[fx, 0, cx; 0, fy, cy; 0, 0, 1]# 图像中心坐标系(uv):相机畸变参数[k1, k2, p1, p2, k3]D = [7.0834633684407095e-002, 6.9140193737175351e-002, 0.0, 0.0, -1.3073460323689292e+000]# 像素坐标系(xy):填写凸轮的本征和畸变系数cam_matrix = np.array(K).reshape(3, 3).astype(np.float32)dist_coeffs = np.array(D).reshape(5, 1).astype(np.float32)# 重新投影3D点的世界坐标轴以验证结果姿势reprojectsrc = np.float32([[10.0, 10.0, 10.0], [10.0, 10.0, -10.0], [10.0, -10.0, -10.0], [10.0, -10.0, 10.0], [-10.0, 10.0, 10.0], [-10.0, 10.0, -10.0], [-10.0, -10.0, -10.0], [-10.0, -10.0, 10.0]])# 绘制正方体12轴line_pairs = [[0, 1], [1, 2], [2, 3], [3, 0], [4, 5], [5, 6], [6, 7], [7, 4], [0, 4], [1, 5], [2, 6], [3, 7]]def get_head_pose(shape):# 头部姿态估计 # (像素坐标集合)填写2D参考点,注释遵循https://ibug.doc.ic.ac.uk/resources/300-W/ # 17左眉左上角/21左眉右角/22右眉左上角/26右眉右上角/36左眼左上角/39左眼右上角/42右眼左上角/ # 45右眼右上角/31鼻子左上角/35鼻子右上角/48左上角/54嘴右上角/57嘴中央下角/8下巴角 image_pts = np.float32([shape[17], shape[21], shape[22], shape[26], shape[36], shape[39], shape[42], shape[45], shape[31], shape[35], shape[48], shape[54], shape[57], shape[8]]) # solvePnP计算姿势——求解旋转和平移矩阵: # rotation_vec表示旋转矩阵,translation_vec表示平移矩阵,cam_matrix与K矩阵对应,dist_coeffs与D矩阵对应。 _, rotation_vec, translation_vec = cv2.solvePnP(object_pts, image_pts, cam_matrix, dist_coeffs) # projectPoints重新投影误差:原2d点和重投影2d点的距离(输入3d点、相机内参、相机畸变、r、t,输出重投影2d点) reprojectdst, _ = cv2.projectPoints(reprojectsrc, rotation_vec, translation_vec, cam_matrix,dist_coeffs) reprojectdst = tuple(map(tuple, reprojectdst.reshape(8, 2)))# 以8行2列显示 # 计算欧拉角calc euler angle # 参考https://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#decomposeprojectionmatrix rotation_mat, _ = cv2.Rodrigues(rotation_vec)#罗德里格斯公式(将旋转矩阵转换为旋转向量) pose_mat = cv2.hconcat((rotation_mat, translation_vec))# 水平拼接,vconcat垂直拼接 # decomposeProjectionMatrix将投影矩阵分解为旋转矩阵和相机矩阵 _, _, _, _, _, _, euler_angle = cv2.decomposeProjectionMatrix(pose_mat) pitch, yaw, roll = [math.radians(_) for _ in euler_angle] pitch = math.degrees(math.asin(math.sin(pitch))) roll = -math.degrees(math.asin(math.sin(roll))) yaw = math.degrees(math.asin(math.sin(yaw))) print('pitch:{}, yaw:{}, roll:{}'.format(pitch, yaw, roll)) return reprojectdst, euler_angle# 投影误差,欧拉角def eye_aspect_ratio(eye): # 垂直眼标志(X,Y)坐标 A = dist.euclidean(eye[1], eye[5])# 计算两个集合之间的欧式距离 B = dist.euclidean(eye[2], eye[4]) # 计算水平之间的欧几里得距离 # 水平眼标志(X,Y)坐标 C = dist.euclidean(eye[0], eye[3]) # 眼睛长宽比的计算 ear = (A + B) / (2.0 * C) # 返回眼睛的长宽比 return eardef mouth_aspect_ratio(mouth):# 嘴部 A = np.linalg.norm(mouth[2] - mouth[9]) # 51, 59 B = np.linalg.norm(mouth[4] - mouth[7]) # 53, 57 C = np.linalg.norm(mouth[0] - mouth[6]) # 49, 55 mar = (A + B) / (2.0 * C) return mar# 定义常数# 眼睛长宽比# 闪烁阈值EYE_AR_THRESH = 0.2EYE_AR_CONSEC_FRAMES = 3# 打哈欠长宽比# 闪烁阈值MAR_THRESH = 0.5MOUTH_AR_CONSEC_FRAMES = 3# 瞌睡点头HAR_THRESH = 0.3NOD_AR_CONSEC_FRAMES = 3# 初始化帧计数器和眨眼总数COUNTER = 0TOTAL = 0# 初始化帧计数器和打哈欠总数mCOUNTER = 0mTOTAL = 0# 初始化帧计数器和点头总数hCOUNTER = 0hTOTAL = 0# 初始化DLIB的人脸检测器(HOG),然后创建面部标志物预测print("[INFO] loading facial landmark predictor...")# 第一步:使用dlib.get_frontal_face_detector() 获得脸部位置检测器detector = dlib.get_frontal_face_detector()# 第二步:使用dlib.shape_predictor获得脸部特征位置检测器predictor = dlib.shape_predictor('D:/myworkspace/JupyterNotebook/fatigue_detecting/model/shape_predictor_68_face_landmarks.dat')# 第三步:分别获取左右眼面部标志的索引(lStart, lEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"](rStart, rEnd) = face_utils.FACIAL_LANDMARKS_IDXS["right_eye"](mStart, mEnd) = face_utils.FACIAL_LANDMARKS_IDXS["mouth"]# 第四步:打开cv2 本地摄像头cap = cv2.VideoCapture(0)# 从视频流循环帧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 cameracap.release()# do a bit of cleanupcv2.destroyAllWindows()

6 基于CNN与SVM的疲劳检测方法6.1 网络结构

学长将卷积神经网络作为特征提取器, 支持向量机作为分类识别器并通过串联将两者结合 , 构造理想的深度识别模型, 提高对驾驶员疲劳的识别准确率。 本次课题主要以实现提高识别精度为目的, 设计使用的特征提取网络结构中卷积层、 池化层以及全连接层个数均为两层; 在网络的结尾处添加一层支持向量机作为识别分类器;

根据对卷积神经网络的描述, 这里设计使用的网络结构为: 输入层、 二层卷积层、 二层池化层、 二层全连接层以及 SVM 分类器组成的卷积神经网络对采集数据进行实验。

可将网络视为三个部分, 数据输入部分即网络输入层, 为特征提取部分由卷积层和池化层构成, SVM 为分类识别部分; 三部分网络串联出整体识别框架, 且相互间约束不大, 为后续优化工作提供了条件。

6.2 疲劳图像分类训练

网络的训练由于数据量较大进行实验时将数据分为多个批次, 每个批次中含有 20张图像, 经过前向、 反向传播后更新网络参数, 训练出误差合适的网络。 测试时, 图像由网络进行识别, 根据得到的识别正确率来验证网络的可行性。

疲劳驾驶检测需对网络进行训练, 在保证网络训练准确率达到一定精度后即可对图像进行判别; 疲劳驾驶网络训练算法过程如下:

Step1: 网络初始化: 初始化网络学习率η, 在数值范围[0, 1]中随机初始化网络参数权值及偏置值; 设置网络结构: 卷积核大小为 5×5, 每批次样本数量 20;Step2: 随机选择数据库内面部表情图像并依次输入网络, 网络按照送入每一批次的图像进行训练;Step3: 网络将训练得到的输出值同图像期望值进行比较, 计算出输出误差;Step4: 根据反向传播原理将误差反向传播计算, 并调整网络参数权值和偏置值;Step5: 判断迭代次数, 达到期望的迭代步数后转到 Step6, 否则转到 Step3;Step6: 将 CNN 提取到的图像特征传入 SVM 中进行训练;Step7: 结束。6.3 训练结果

学长将对建立起的数据集进行实验, 实验中分别在每一批次下对识别正确和错误个数进行统计, 然后同批次中图片数量相比, 得出最终的准确率和损失率(错误率) 。

模型测试结果

7 最后
本文链接地址:https://www.jiuchutong.com/zhishi/299360.html 转载请保留说明!

上一篇:如何在Vue3+Vite中使用JSX(vue3 技巧)

下一篇:叮咚,您有一封告白信件待查收(原生HTML+CSS+JS绘制表白信件,代码+链接+步骤详解)(叮咚你有一份好运请查收图片)

  • facetime用的是话费还是流量

    facetime用的是话费还是流量

  • 荣耀play4tpro可以升级鸿蒙系统吗(荣耀play4tpro可以插内存卡吗)

    荣耀play4tpro可以升级鸿蒙系统吗(荣耀play4tpro可以插内存卡吗)

  • 京东如何退货申请退款(京东如何退货申请退款先要确定收货吗)

    京东如何退货申请退款(京东如何退货申请退款先要确定收货吗)

  • vivo手机如何设置铃声(vivo手机如何设置下面三个快捷键)

    vivo手机如何设置铃声(vivo手机如何设置下面三个快捷键)

  • 苹果手机怎么设置按键音(苹果手机怎么设置陌生号码拦截)

    苹果手机怎么设置按键音(苹果手机怎么设置陌生号码拦截)

  • 苹果手机的短信怎么导入另外一个手机(苹果手机的短信怎么导入另一个苹果手机)

    苹果手机的短信怎么导入另外一个手机(苹果手机的短信怎么导入另一个苹果手机)

  • 微信怎么彻底删除好友(微信怎么彻底删除聊天记录)

    微信怎么彻底删除好友(微信怎么彻底删除聊天记录)

  • 什么软件可以让手机不卡顿(什么软件可以让模糊的图片变清晰)

    什么软件可以让手机不卡顿(什么软件可以让模糊的图片变清晰)

  • 买家已经收货款未到账(买家已经收货款怎么退货)

    买家已经收货款未到账(买家已经收货款怎么退货)

  • 小米双击唤醒屏幕不灵(小米双击唤醒屏幕耗电吗)

    小米双击唤醒屏幕不灵(小米双击唤醒屏幕耗电吗)

  • 荣耀手表S1无法充电怎么回事(荣耀为智能手表)

    荣耀手表S1无法充电怎么回事(荣耀为智能手表)

  • 宽带没欠费为什么连接不上网络(宽带没欠费为什么网络变得很差)

    宽带没欠费为什么连接不上网络(宽带没欠费为什么网络变得很差)

  • vivox9可不可以无线充电(vivox9l有无线充电功能吗)

    vivox9可不可以无线充电(vivox9l有无线充电功能吗)

  • vivo modemlog什么意思(手机modemlog什么意思)

    vivo modemlog什么意思(手机modemlog什么意思)

  • ipad10.5支持快充吗(ipad支持快充的机型)

    ipad10.5支持快充吗(ipad支持快充的机型)

  • 快手推广审核中是什么情况(快手推广审核未通过会退款吗)

    快手推广审核中是什么情况(快手推广审核未通过会退款吗)

  • 天猫进口超市可以退货吗(天猫进口超市可以开发票吗)

    天猫进口超市可以退货吗(天猫进口超市可以开发票吗)

  • 如何发传真给对方(如何发传真给对方手机)

    如何发传真给对方(如何发传真给对方手机)

  • 抖音直播点亮怎么回事(抖音直播点亮怎么点亮)

    抖音直播点亮怎么回事(抖音直播点亮怎么点亮)

  • 苹果11pro max颜色有哪些(苹果11pro max颜色价格一样吗)

    苹果11pro max颜色有哪些(苹果11pro max颜色价格一样吗)

  • 铃声多多收藏弄到本地(铃声多多收藏的歌曲怎么删除)

    铃声多多收藏弄到本地(铃声多多收藏的歌曲怎么删除)

  • 计算机键盘基础知识(计算机键盘基础题目)

    计算机键盘基础知识(计算机键盘基础题目)

  • ps可以把图片变清晰吗(PS可以把图片变成线稿吗)

    ps可以把图片变清晰吗(PS可以把图片变成线稿吗)

  • word保存后内容丢失(word保存后内容丢失怎么恢复)

    word保存后内容丢失(word保存后内容丢失怎么恢复)

  • 【Vue全家桶】Pinia状态管理(vue全家桶学多久能上手项目)

    【Vue全家桶】Pinia状态管理(vue全家桶学多久能上手项目)

  • 海关进口啥意思
  • 防疫物资采购计入什么费用
  • 应税项目和非应税项目起征点一样吗
  • 收据四联分别叫什么
  • 作废的发票还需要保存吗
  • 筹备期间人工成本怎么算
  • 网银盾属于什么费用
  • 酒店购买餐具会计分录
  • 经营范围预付卡是什么
  • 债务重组偿债顺序
  • 房产折旧计算方法 举例
  • 发票冲红增值税怎么申报
  • 异地施工需要缴纳什么税
  • 银行缴纳印花税的范围
  • 个人转让土地使用权 增值税
  • 为什么有的单位没有住房公积金
  • 职工福利费发票不小心抵扣了汇算清缴
  • 如何计算工程预付款
  • 企业不动产如何带抵押转让
  • 固定资产残值率一般是多少
  • 销售净利率怎么求
  • 软件行业的收入怎么样
  • 苹果电脑初始化设置
  • 劳务费和服务费一样吗
  • 鸿蒙的usb调试
  • 经济成本和会计成本的大小
  • 顺丰充值的钱可以退吗
  • 苹果手机清理内存怎么清理微信内存
  • 出口货物免抵退税 组织收入 影响
  • php初学
  • 柏林亚历山大广场1980
  • php数组操作函数
  • 企业所得税申报表在哪里打印
  • 商家为消费者提供餐具
  • 这可能是最好的144平米小平层户型
  • php判断用户是否登录
  • 销售不同商品的会计分录
  • 流动资产与资产总额的比率叫什么比率
  • python之sqlalchemy创建表的实例详解
  • 小规模纳税人的条件
  • 累计折旧会影响净残值吗
  • 两个日期是否一致
  • mysql索引命令
  • 一般纳税人商贸企业的税负是多少
  • 增值税销项税的借贷方向
  • 建筑行业现在还能斤不
  • 开具发票后,如发生销售退回,通常有的两种处理方式是?
  • 市政建设配套费 契税
  • 持有至到期投资和债权投资的区别
  • 小规模附加税要交吗
  • 制造企业费用会计
  • 预付账款属于哪一类账户
  • 展览展示服务费计入什么科目
  • 办土地证费用会退吗
  • mysql中的ifnull函数
  • mysql 正则表达式分组替换
  • win7端口怎么查看
  • Vista技巧:何在Vista上运行不兼容的旧版本软件
  • ubuntu系统中怎么重启proftpd程序
  • 升级mac os
  • win8快捷键设置在哪里设置
  • win7 注册表 ahci
  • Windows 7 Apache下计算机无法访问局域网网站的解决方法
  • linux装完显卡驱动分辨率低
  • mingw 编译
  • jquery fadein 源码
  • Python自然语言处理PDF
  • unityai寻路
  • 文档对象模型DOM主要作用是
  • 批处理设置ip地址配置的dns
  • 安卓手机界面设计
  • jquery-easyui-1.3.3
  • jquery图片轮播无缝连接
  • javascript数组的常用方法
  • Flow之一个新的Javascript静态类型检查器
  • js table插件
  • 开票资料?
  • 收到unknown发来的短信
  • 工信部摩托车目录查询
  • 税务征收社保费
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设