在线免费视频网站推广,成为软件工程师的条件,有源码手机怎么搭建网站,wordpress 静态链接简介
瞌睡经常发生在汽车行驶的过程中#xff0c;该行为害人害己#xff0c;如果有一套能识别瞌睡的系统#xff0c;那么无疑该系统意义重大#xff01;
实现步骤
思路#xff1a;疲劳驾驶的司机大部分都有打瞌睡的情形#xff0c;所以我们根据驾驶员眼睛闭合的频率和…简介
瞌睡经常发生在汽车行驶的过程中该行为害人害己如果有一套能识别瞌睡的系统那么无疑该系统意义重大
实现步骤
思路疲劳驾驶的司机大部分都有打瞌睡的情形所以我们根据驾驶员眼睛闭合的频率和时间来判断驾驶员是否疲劳驾驶(或嗜睡)。
详细实现步骤
【1】眼部关键点检测。 我们使用Face Mesh来检测眼部关键点Face Mesh返回了468个人脸关键点 由于我们专注于驾驶员睡意检测在468个点中我们只需要属于眼睛区域的标志点。眼睛区域有 32 个标志点每个 16 个点。为了计算 EAR我们只需要 12 个点每只眼睛 6 个点。
以上图为参考选取的12个地标点如下
对于左眼 [362, 385, 387, 263, 373, 380]
对于右眼[33, 160, 158, 133, 153, 144]
选择的地标点按顺序排列P 1、 P 2、 P 3、 P 4、 P 5、 P 6
bashbash
import cv2
import numpy as np
import matplotlib.pyplot as plt
import mediapipe as mpmp_facemesh mp.solutions.face_mesh
mp_drawing mp.solutions.drawing_utils
denormalize_coordinates mp_drawing._normalized_to_pixel_coordinates%matplotlib inline
获取双眼的地标索引点。bash
# Landmark points corresponding to left eye
all_left_eye_idxs list(mp_facemesh.FACEMESH_LEFT_EYE)
# flatten and remove duplicates
all_left_eye_idxs set(np.ravel(all_left_eye_idxs)) # Landmark points corresponding to right eye
all_right_eye_idxs list(mp_facemesh.FACEMESH_RIGHT_EYE)
all_right_eye_idxs set(np.ravel(all_right_eye_idxs))# Combined for plotting - Landmark points for both eye
all_idxs all_left_eye_idxs.union(all_right_eye_idxs)# The chosen 12 points: P1, P2, P3, P4, P5, P6
chosen_left_eye_idxs [362, 385, 387, 263, 373, 380]
chosen_right_eye_idxs [33, 160, 158, 133, 153, 144]
all_chosen_idxs chosen_left_eye_idxs chosen_right_eye_idx
图片【2】检测眼睛是否闭合——计算眼睛纵横比(EAR)。
要检测眼睛是否闭合我们可以使用眼睛纵横比(EAR) 公式
EAR 公式返回反映睁眼程度的单个标量
我们将使用 Mediapipe 的 Face Mesh 解决方案来检测和检索眼睛区域中的相关地标下图中的点P 1 - P 6。检索相关点后会在眼睛的高度和宽度之间计算眼睛纵横比 (EAR)。 当眼睛睁开并接近零时EAR 几乎是恒定的而闭上眼睛是部分人并且头部姿势不敏感。睁眼的纵横比在个体之间具有很小的差异。它对于图像的统一缩放和面部的平面内旋转是完全不变的。由于双眼同时眨眼所以双眼的EAR是平均的。
上图检测到地标P i的睁眼和闭眼。
底部为视频序列的几帧绘制的眼睛纵横比 EAR。存在一个闪烁。
首先我们必须计算每只眼睛的 Eye Aspect Ratio
|| 表示L2范数用于计算两个向量之间的距离。
为了计算最终的 EAR 值作者建议取两个 EAR 值的平均值。 一般来说平均 EAR 值在 [0.0, 0.40] 范围内。在“闭眼”动作期间 EAR 值迅速下降。
现在我们熟悉了 EAR 公式让我们定义三个必需的函数distance(…)、get_ear(…)和calculate_avg_ear(…)。
def distance(point_1, point_2):Calculate l2-norm between two pointsdist sum([(i - j) ** 2 for i, j in zip(point_1, point_2)]) ** 0.5return dist
get_ear (…)函数将.landmark属性作为参数。在每个索引位置我们都有一个NormalizedLandmark对象。该对象保存标准化的x、y和z坐标值。def get_ear(landmarks, refer_idxs, frame_width, frame_height):Calculate Eye Aspect Ratio for one eye.Args:landmarks: (list) Detected landmarks listrefer_idxs: (list) Index positions of the chosen landmarksin order P1, P2, P3, P4, P5, P6frame_width: (int) Width of captured frameframe_height: (int) Height of captured frameReturns:ear: (float) Eye aspect ratiotry:# Compute the euclidean distance between the horizontalcoords_points []for i in refer_idxs:lm landmarks[i]coord denormalize_coordinates(lm.x, lm.y, frame_width, frame_height)coords_points.append(coord)# Eye landmark (x, y)-coordinatesP2_P6 distance(coords_points[1], coords_points[5])P3_P5 distance(coords_points[2], coords_points[4])P1_P4 distance(coords_points[0], coords_points[3])# Compute the eye aspect ratioear (P2_P6 P3_P5) / (2.0 * P1_P4)except:ear 0.0coords_points Nonereturn ear, coords_points最后定义了calculate_avg_ear(…)函数
def calculate_avg_ear(landmarks, left_eye_idxs, right_eye_idxs, image_w, image_h):Calculate Eye aspect ratioleft_ear, left_lm_coordinates get_ear(landmarks, left_eye_idxs, image_w, image_h)right_ear, right_lm_coordinates get_ear(landmarks, right_eye_idxs, image_w, image_h)Avg_EAR (left_ear right_ear) / 2.0return Avg_EAR, (left_lm_coordinates, right_lm_coordinates)让我们测试一下 EAR 公式。我们将计算先前使用的图像和另一张眼睛闭合的图像的平均 EAR 值。
image_eyes_open cv2.imread(test-open-eyes.jpg)[:, :, ::-1]
image_eyes_close cv2.imread(test-close-eyes.jpg)[:, :, ::-1]for idx, image in enumerate([image_eyes_open, image_eyes_close]):image np.ascontiguousarray(image)imgH, imgW, _ image.shape# Creating a copy of the original image for plotting the EAR valuecustom_chosen_lmk_image image.copy()# Running inference using static_image_modewith mp_facemesh.FaceMesh(refine_landmarksTrue) as face_mesh:results face_mesh.process(image).multi_face_landmarks# If detections are available.if results:for face_id, face_landmarks in enumerate(results):landmarks face_landmarks.landmarkEAR, _ calculate_avg_ear(landmarks, chosen_left_eye_idxs, chosen_right_eye_idxs, imgW, imgH)# Print the EAR value on the custom_chosen_lmk_image.cv2.putText(custom_chosen_lmk_image, fEAR: {round(EAR, 2)}, (1, 24),cv2.FONT_HERSHEY_COMPLEX, 0.9, (255, 255, 255), 2) plot(img_dtimage.copy(),img_eye_lmks_chosencustom_chosen_lmk_image,face_landmarksface_landmarks,ts_thickness1, ts_circle_radius3, lmk_circle_radius3)结果 如您所见睁眼时的 EAR 值为0.28闭眼时接近于零为 0.08。
【3】设计一个实时检测系统。 首先我们声明两个阈值和一个计数器。
EAR_thresh 用于检查当前EAR值是否在范围内的阈值。D_TIME一个计数器变量用于跟踪当前经过的时间量EAR EAR_THRESH.WAIT_TIME确定经过的时间量是否EAR EAR_THRESH超过了允许的限制。当应用程序启动时我们将当前时间以秒为单位记录在一个变量中t1并读取传入的帧。
接下来我们预处理并frame通过Mediapipe 的 Face Mesh 解决方案管道。
如果有任何地标检测可用我们将检索相关的 ( Pi )眼睛地标。否则在此处重置t1 和重置以使算法一致。D_TIME (D_TIME如果检测可用则使用检索到的眼睛标志计算双眼的平均EAR值。如果是当前时间则加上当前时间和to之间的差。然后将下一帧重置为。EAR EAR_THRESHt2t1D_TIMEt1 t2如果D_TIME WAIT_TIME我们会发出警报或继续下一帧。