基于深度学习的驾驶员分心驾驶行为 (疲劳+危险行为)预 警系统,使用改进网络结构YOLOV5+PERCLOS实现。
文章目录
- 1. 安装依赖
- 2. 数据准备
- 3. 模型配置
- 3.1 加载YOLOv5模型
- 3.2 配置PERCLOS(Percentage of Eye Closure)
- 4. 实时检测与预警
- 4.1 实时摄像头检测
- 5. GUI 应用程序
- 5.1 安装PySide2
- 5.2 构建GUI
- 1. 安装依赖
- 2. GUI界面
- 3. 实时摄像头检测与疲劳检测
- 4. 结合GUI和实时检测
疲劳驾驶司机异常驾驶行为检测及预警系统
实现目标:
1.基于深度学习的驾驶员分心驾驶行为 (疲劳+危险行为)预
警系统,使用改进网络结构YOLOV5+PERCLOS实现。
2.可以检测是否存在玩手机、抽烟、喝水这三种行为,可以通
过计算眼睛和嘴巴的开合程度来判断是存在否闭眼或者打哈
欠,并计算疲劳程度,可直接调用摄像头实时检测,有可视化界面。
3.包括疲劳检测(打哈欠,低头,闭眼),吸烟检测,吃喝东
西检测,打电话检测,摄像头实时检测,视频导入检测。
4.python疲劳驾驶预警系统
构建一个基于深度学习的驾驶员疲劳驾驶预警系统,可以检测多种异常驾驶行为(如玩手机、抽烟、喝水等),并通过计算眼睛和嘴巴的开合程度来判断是否存在闭眼或打哈欠的行为。以下是详细的步骤和代码示例:
仅参考。
1. 安装依赖
确保安装了以下依赖库:
pipinstalltorch torchvision opencv-python dlib numpy imutils PySide22. 数据准备
假设你已经有了标注好的数据集,包括人脸、眼睛、嘴巴等关键点的标注。
3. 模型配置
3.1 加载YOLOv5模型
fromultralyticsimportYOLO# 加载预训练的YOLOv5模型model=YOLO('yolov5s.pt')3.2 配置PERCLOS(Percentage of Eye Closure)
PERCLOS是通过计算眼睛闭合的时间百分比来评估疲劳程度的方法。
4. 实时检测与预警
4.1 实时摄像头检测
importcv2importdlibimportnumpyasnpimportimutilsfromimutilsimportface_utilsfromscipy.spatialimportdistanceasdistdefeye_aspect_ratio(eye):# 计算眼睛的长宽比A=dist.euclidean(eye[1],eye[5])B=dist.euclidean(eye[2],eye[4])C=dist.euclidean(eye[0],eye[3])ear=(A+B)/(2.0*C)returneardefmouth_aspect_ratio(mouth):# 计算嘴巴的长宽比A=dist.euclidean(mouth[2],mouth[10])# 51, 59B=dist.euclidean(mouth[4],mouth[6])# 53, 57C=dist.euclidean(mouth[0],mouth[8])# 49, 55mar=(A+B)/(2.0*C)returnmardefdetect_fatigue(frame,landmarks):# 提取眼睛和嘴巴的关键点left_eye=landmarks[36:42]right_eye=landmarks[42:48]mouth=landmarks[48:68]# 计算EAR和MARleft_ear=eye_aspect_ratio(left_eye)right_ear=eye_aspect_ratio(right_eye)ear=(left_ear+right_ear)/2.0mar=mouth_aspect_ratio(mouth)# 判断是否闭眼或打哈欠ifear<0.25:return"闭眼"ifmar>0.7:return"打哈欠"returnNonedefmain():# 初始化摄像头cap=cv2.VideoCapture(0)# 加载面部检测器detector=dlib.get_frontal_face_detector()predictor=dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")whileTrue:ret,frame=cap.read()ifnotret:breakgray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)rects=detector(gray,0)forrectinrects:shape=predictor(gray,rect)shape=face_utils.shape_to_np(shape)# 检测疲劳fatigue_status=detect_fatigue(frame,shape)iffatigue_status:print(f"检测到{fatigue_status}")# 绘制关键点for(x,y)inshape:cv2.circle(frame,(x,y),1,(0,255,0),-1)cv2.imshow("Fatigue Detection",frame)ifcv2.waitKey(1)&0xFF==ord('q'):breakcap.release()cv2.destroyAllWindows()if__name__=="__main__":main()5. GUI 应用程序
使用PySide2构建GUI应用程序。
5.1 安装PySide2
pipinstallPySide25.2 构建GUI
importsysfromPySide2.QtWidgetsimportQApplication,QMainWindow,QLabel,QVBoxLayout,QWidget,QPushButton,QFileDialog,QComboBoxfromPySide2.QtGuiimportQPixmap,QImagefromPySide2.QtCoreimportQTimerimportcv2importdlibimportnumpyasnpimportimutilsfromimutilsimportface_utilsfromscipy.spatialimportdistanceasdistclassFatigueDetectionApp(QMainWindow):def__init__(self):super().__init__()self.setWindowTitle('疲劳驾驶预警系统')self.setGeometry(100,100,800,600)self.image_label=QLabel(self)self.button=QPushButton("开始检测",self)self.button.clicked.connect(self.start_detection)vbox=QVBoxLayout()vbox.addWidget(self.image_label)vbox.addWidget(self.button)self.setLayout(vbox)self.cap=cv2.VideoCapture(0)self.detector=dlib.get_frontal_face_detector()self.predictor=dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")self.timer=QTimer(self)self.timer.timeout.connect(self.update_frame)self.timer.start(30)defupdate_frame(self):ret,frame=self.cap.read()ifnotret:returngray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)rects=self.detector(gray,0)forrectinrects:shape=self.predictor(gray,rect)shape=face_utils.shape_to_np(shape)# 检测疲劳fatigue_status=detect_fatigue(frame,shape)iffatigue_status:print(f"检测到{fatigue_status}")# 绘制关键点for(x,y)inshape:cv2.circle(frame,(x,y),1,(0,255,0),-1)height,width,channel=frame.shape bytes_per_line=3*width q_img=QImage(frame.data,width,height,bytes_per_line,QImage.Format_RGB888).rgbSwapped()pixmap=QPixmap.fromImage(q_img)self.image_label.setPixmap(pixmap)defstart_detection(self):self.cap.open(0)defcloseEvent(self,event):self.cap.release()event.accept()if__name__=="__main__":app=QApplication(sys.argv)demo=FatigueDetectionApp()demo.show()sys.exit(app.exec_())为了帮助你构建一个完整的驾驶员疲劳检测系统,我将提供详细的代码示例。这个系统包括以下几个部分:
- GUI界面:使用
tkinter库创建一个简单的图形用户界面。 - 摄像头实时检测:使用
cv2库进行视频流处理。 - 面部关键点检测:使用
dlib库检测面部关键点。 - 疲劳检测算法:计算眼睛闭合程度(PERCLOS)和嘴巴开合程度(MAR)。
1. 安装依赖
确保安装了以下依赖库:
pipinstallopencv-python dlib numpy imutils tkinter2. GUI界面
使用tkinter创建一个简单的GUI界面。
importtkinterastkfromtkinterimportmessageboxclassFatigueDetectionApp:def__init__(self,root):self.root=root self.root.title("驾驶员疲劳检测")self.root.geometry("600x400")# 创建标签label=tk.Label(root,text="驾驶员疲劳检测",font=("Helvetica",16))label.pack(pady=20)# 创建按钮btn_open_camera=tk.Button(root,text="测试1: 打开相机",command=self.open_camera)btn_open_camera.pack(pady=10)btn_open_camera_record=tk.Button(root,text="测试2: 打开相机并记录",command=self.open_camera_and_record)btn_open_camera_record.pack(pady=10)btn_open_camera_detect=tk.Button(root,text="测试3: 打开摄像头并检测",command=self.open_camera_and_detect)btn_open_camera_detect.pack(pady=10)btn_detect_record=tk.Button(root,text="测试4: 检测记录",command=self.detect_record)btn_detect_record.pack(pady=10)btn_blink_detect_record=tk.Button(root,text="测试5: 检测眨眼并录制声音",command=self.blink_detect_and_record)btn_blink_detect_record.pack(pady=10)btn_exit=tk.Button(root,text="退出",command=root.quit)btn_exit.pack(pady=10)defopen_camera(self):messagebox.showinfo("提示","打开相机功能未实现")defopen_camera_and_record(self):messagebox.showinfo("提示","打开相机并记录功能未实现")defopen_camera_and_detect(self):messagebox.showinfo("提示","打开摄像头并检测功能未实现")defdetect_record(self):messagebox.showinfo("提示","检测记录功能未实现")defblink_detect_and_record(self):messagebox.showinfo("提示","检测眨眼并录制声音功能未实现")if__name__=="__main__":root=tk.Tk()app=FatigueDetectionApp(root)root.mainloop()3. 实时摄像头检测与疲劳检测
使用cv2和dlib库进行实时摄像头检测,并计算眼睛闭合程度(PERCLOS)和嘴巴开合程度(MAR)。
importcv2importdlibimportnumpyasnpimportimutilsfromimutilsimportface_utilsfromscipy.spatialimportdistanceasdistdefeye_aspect_ratio(eye):A=dist.euclidean(eye[1],eye[5])B=dist.euclidean(eye[2],eye[4])C=dist.euclidean(eye[0],eye[3])ear=(A+B)/(2.0*C)returneardefmouth_aspect_ratio(mouth):A=dist.euclidean(mouth[2],mouth[10])# 51, 59B=dist.euclidean(mouth[4],mouth[6])# 53, 57C=dist.euclidean(mouth[0],mouth[8])# 49, 55mar=(A+B)/(2.0*C)returnmardefdetect_fatigue(frame,landmarks):left_eye=landmarks[36:42]right_eye=landmarks[42:48]mouth=landmarks[48:68]left_ear=eye_aspect_ratio(left_eye)right_ear=eye_aspect_ratio(right_eye)ear=(left_ear+right_ear)/2.0mar=mouth_aspect_ratio(mouth)ifear<0.25:return"闭眼"ifmar>0.7:return"打哈欠"returnNonedefmain():cap=cv2.VideoCapture(0)detector=dlib.get_frontal_face_detector()predictor=dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")whileTrue:ret,frame=cap.read()ifnotret:breakgray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)rects=detector(gray,0)forrectinrects:shape=predictor(gray,rect)shape=face_utils.shape_to_np(shape)fatigue_status=detect_fatigue(frame,shape)iffatigue_status:print(f"检测到{fatigue_status}")for(x,y)inshape:cv2.circle(frame,(x,y),1,(0,255,0),-1)cv2.imshow("Fatigue Detection",frame)ifcv2.waitKey(1)&0xFF==ord('q'):breakcap.release()cv2.destroyAllWindows()if__name__=="__main__":main()4. 结合GUI和实时检测
将上述代码结合在一起,创建一个完整的应用程序。
importtkinterastkfromtkinterimportmessageboximportcv2importdlibimportnumpyasnpimportimutilsfromimutilsimportface_utilsfromscipy.spatialimportdistanceasdistclassFatigueDetectionApp:def__init__(self,root):self.root=root self.root.title("驾驶员疲劳检测")self.root.geometry("600x400")# 创建标签label=tk.Label(root,text="驾驶员疲劳检测",font=("Helvetica",16))label.pack(pady=20)# 创建按钮btn_open_camera=tk.Button(root,text="测试1: 打开相机",command=self.open_camera)btn_open_camera.pack(pady=10)btn_open_camera_record=tk.Button(root,text="测试2: 打开相机并记录",command=self.open_camera_and_record)btn_open_camera_record.pack(pady=10)btn_open_camera_detect=tk.Button(root,text="测试3: 打开摄像头并检测",command=self.open_camera_and_detect)btn_open_camera_detect.pack(pady=10)btn_detect_record=tk.Button(root,text="测试4: 检测记录",command=self.detect_record)btn_detect_record.pack(pady=10)btn_blink_detect_record=tk.Button(root,text="测试5: 检测眨眼并录制声音",command=self.blink_detect_and_record)btn_blink_detect_record.pack(pady=10)btn_exit=tk.Button(root,text="退出",command=root.quit)btn_exit.pack(pady=10)self.cap=cv2.VideoCapture(0)self.detector=dlib.get_frontal_face_detector()self.predictor=dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")defopen_camera(self):messagebox.showinfo("提示","打开相机功能未实现")defopen_camera_and_record(self):messagebox.showinfo("提示","打开相机并记录功能未实现")defopen_camera_and_detect(self):whileTrue:ret,frame=self.cap.read()ifnotret:breakgray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)rects=self.detector(gray,0)forrectinrects:shape=self.predictor(gray,rect)shape=face_utils.shape_to_np(shape)fatigue_status=detect_fatigue(frame,shape)iffatigue_status:print(f"检测到{fatigue_status}")for(x,y)inshape:cv2.circle(frame,(x,y),1,(0,255,0),-1)cv2.imshow("Fatigue Detection",frame)ifcv2.waitKey(1)&0xFF==ord('q'):breakself.cap.release()cv2.destroyAllWindows()defdetect_record(self):messagebox.showinfo("提示","检测记录功能未实现")defblink_detect_and_record(self):messagebox.showinfo("提示","检测眨眼并录制声音功能未实现")defeye_aspect_ratio(eye):A=dist.euclidean(eye[1],eye[5])B=dist.euclidean(eye[2],eye[4])C=dist.euclidean(eye[0],eye[3])ear=(A+B)/(2.0*C)returneardefmouth_aspect_ratio(mouth):A=dist.euclidean(mouth[2],mouth[10])# 51, 59B=dist