赞
踩
非常简单的数字信号处理课程设计,先开个坑,待会再填,大概三月底会上传完整的版本,预览图在下面,如果实在需要可以联系Toss_3@163.com
正在编辑... 2024.3.20
数字信号处理课程设计——基于dlib,OpenCV,YOLOv5的疲劳驾驶与分心驾驶检测系统(附带效果展示)
这里采用的是dlib库的68点人脸检测模型,标记人脸关键点
使用的shape_predictor_68_face_landmarks.dat
68点人脸检测模型的下载链接:http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2
通过openCV调用本地摄像头实现人脸检测
- def _learning_face(self):
- """dlib的初始化调用"""
- # 使用人脸检测器get_frontal_face_detector
- self.detector = dlib.get_frontal_face_detector()
- # dlib的68点模型,使用作者训练好的特征预测器
- self.predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
- data = {
- 'type':'msg',
- 'value':u"加载模型成功!!!\n"
- }
- self.thread_signal.emit(data)
-
- # 分别获取左右眼面部标志的索引
- (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摄像头对象
- self.cap = cv2.VideoCapture(self.VIDEO_STREAM)
-
- data = {
- 'type': 'msg',
- }
- if self.cap.isOpened() == True: # 返回true/false 检查初始化是否成功
- self.CAMERA_STYLE = True
- data['value'] = u"打开摄像头成功!!!"
- else:
- data['value'] = u"摄像头打开失败!!!"
- self.thread_signal.emit(data)
- # 所有结果
- res = []
- t_time = datetime.datetime.now()
- e_time = datetime.datetime.now()
- h_time = datetime.datetime.now()
- # 打开视频,循环读取视频流
- while (self.cap.isOpened()):
- start_time = datetime.datetime.now()
- res = [' ' for i in range(9)]
- # 图像对象,图像的三维矩阵
- flag, im_rd = self.cap.read()
- #将摄像头读取的im_rd返回到myframe函数
- label = myframe.frametest(im_rd)
- print(label)
- # 取灰度
- img_gray = cv2.cvtColor(im_rd, cv2.COLOR_RGB2GRAY)
- # 使用人脸检测器检测每一帧图像中的人脸。并返回人脸数faces
- faces = self.detector(img_gray, 0)
-
- # 如果检测到人脸
- if (len(faces) != 0):
- res[0] = '识别到人脸'
- # enumerate方法同时返回数据对象的索引和数据,k为索引,d为faces中的对象
- for k, d in enumerate(faces):
- # 用红色矩形框出人脸
- cv2.rectangle(im_rd, (d.left(), d.top()), (d.right(), d.bottom()), (0, 0, 255), 1)
- # 使用预测器得到68点数据的坐标
- shape = self.predictor(im_rd, d)
- # 圆圈显示每个特征点
- for i in range(68):
- cv2.circle(im_rd, (shape.part(i).x, shape.part(i).y), 2, (0, 255, 0), -1, 8)
- # 将脸部特征信息转换为数组array的格式
- shape = face_utils.shape_to_np(shape)
1.1眨眼检测
通过定位眼睛和眼睑的轮廓得出眼睛的长宽比(Eye Aspect Ratio,EAR),用于估计睁眼状态。EAR详细内容参见基于人眼纵横比计算的人眼闭合检测算法_闭眼算法-CSDN博客
通过EAR值的改变来判断眨眼与否,并统计一个时间周期内(这里设置的时间周期为10s)的眨眼次数,并设定一个阈值。如果在这个时间周期内眨眼次数超过阈值,则会触发提醒警告,进入下一个时间周期。
下面是判断眨眼的相关代码
- if self.fun[0]:
- # 提取左眼和右眼坐标
- leftEye = shape[lStart:lEnd]
- rightEye = shape[rStart:rEnd]
- # 构造函数计算左右眼的EAR值,使用平均值作为最终的EAR
- leftEAR = self.eye_aspect_ratio(leftEye)
- rightEAR = self.eye_aspect_ratio(rightEye)
- ear = (leftEAR + rightEAR) / 2.0
- leftEyeHull = cv2.convexHull(leftEye)
- rightEyeHull = cv2.convexHull(rightEye)
- # 使用cv2.convexHull获得凸包位置,使用drawContours画出轮廓位置进行画图操作
- cv2.drawContours(im_rd, [leftEyeHull], -1, (0, 255, 0), 1)
- cv2.drawContours(im_rd, [rightEyeHull], -1, (0, 255, 0), 1)
- # 循环,满足条件的,眨眼次数+1
- if ear < self.EYE_AR_THRESH: # 眼睛长宽比:0.2
- self.COUNTER += 1
- res[5] = '闭眼'
- else:
- # 如果连续3次都小于阈值,则表示进行了一次眨眼活动
- if self.COUNTER >= self.EYE_AR_CONSEC_FRAMES: # 阈值:3
- self.TOTAL += 1
- self.thread_signal.emit({'type':'msg','value':time.strftime('%Y-%m-%d %H:%M:%S ', time.localtime()) + u"眨眼"})
- # 重置眼帧计数器
- self.COUNTER = 0
- res[5] = '睁眼'
1.2闭眼检测
同样是通过EAR值进行检测,如果EAR值一直小于阈值,当累积一定时间就记为
1.3哈欠检测
1.4瞌睡(前/后)点头检测
1.5左/右歪头检测
详细内容邮箱联系,Toss_3@std.uestc.edu.cn
歪头——超过时间阈值会提醒
使用手机——提醒
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。