動易網(wǎng)站官網(wǎng)網(wǎng)絡(luò)營銷的方式都有哪些
簡介
瞌睡經(jīng)常發(fā)生在汽車行駛的過程中,該行為害人害己,如果有一套能識別瞌睡的系統(tǒng),那么無疑該系統(tǒng)意義重大!
實現(xiàn)步驟
思路:疲勞駕駛的司機大部分都有打瞌睡的情形,所以我們根據(jù)駕駛員眼睛閉合的頻率和時間來判斷駕駛員是否疲勞駕駛(或嗜睡)。
詳細實現(xiàn)步驟
【1】眼部關(guān)鍵點檢測。
我們使用Face Mesh來檢測眼部關(guān)鍵點,Face Mesh返回了468個人臉關(guān)鍵點:
由于我們專注于駕駛員睡意檢測,在468個點中,我們只需要屬于眼睛區(qū)域的標(biāo)志點。眼睛區(qū)域有 32 個標(biāo)志點(每個 16 個點)。為了計算 EAR,我們只需要 12 個點(每只眼睛 6 個點)。
以上圖為參考,選取的12個地標(biāo)點如下:
對于左眼: [362, 385, 387, 263, 373, 380]
對于右眼:[33, 160, 158, 133, 153, 144]
選擇的地標(biāo)點按順序排列:P 1、 P 2、 P 3、 P 4、 P 5、 P 6
```bash```bash
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
獲取雙眼的地標(biāo)(索引)點。
`
```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 公式返回反映睜眼程度的單個標(biāo)量:
- 我們將使用 Mediapipe 的 Face Mesh 解決方案來檢測和檢索眼睛區(qū)域中的相關(guān)地標(biāo)(下圖中的點P 1 - P 6)。
- 檢索相關(guān)點后,會在眼睛的高度和寬度之間計算眼睛縱橫比 (EAR)。
當(dāng)眼睛睜開并接近零時,EAR 幾乎是恒定的,而閉上眼睛是部分人,并且頭部姿勢不敏感。睜眼的縱橫比在個體之間具有很小的差異。它對于圖像的統(tǒng)一縮放和面部的平面內(nèi)旋轉(zhuǎn)是完全不變的。由于雙眼同時眨眼,所以雙眼的EAR是平均的。
上圖:檢測到地標(biāo)P i的睜眼和閉眼。
底部:為視頻序列的幾幀繪制的眼睛縱橫比 EAR。存在一個閃爍。
首先,我們必須計算每只眼睛的 Eye Aspect Ratio:
|| 表示L2范數(shù),用于計算兩個向量之間的距離。
為了計算最終的 EAR 值,作者建議取兩個 EAR 值的平均值。
一般來說,平均 EAR 值在 [0.0, 0.40] 范圍內(nèi)。在“閉眼”動作期間 EAR 值迅速下降。
現(xiàn)在我們熟悉了 EAR 公式,讓我們定義三個必需的函數(shù):distance(…)、get_ear(…)和calculate_avg_ear(…)。
def distance(point_1, point_2):"""Calculate l2-norm between two points"""dist = sum([(i - j) ** 2 for i, j in zip(point_1, point_2)]) ** 0.5return dist
get_ear (…)函數(shù)將.landmark屬性作為參數(shù)。在每個索引位置,我們都有一個NormalizedLandmark對象。該對象保存標(biāo)準(zhǔn)化的x、y和z坐標(biāo)值。
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 ratio"""try:# 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(…)函數(shù):
def calculate_avg_ear(landmarks, left_eye_idxs, right_eye_idxs, image_w, image_h):"""Calculate Eye aspect ratio"""left_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_landmarks=True) 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, f"EAR: {round(EAR, 2)}", (1, 24),cv2.FONT_HERSHEY_COMPLEX, 0.9, (255, 255, 255), 2) plot(img_dt=image.copy(),img_eye_lmks_chosen=custom_chosen_lmk_image,face_landmarks=face_landmarks,ts_thickness=1, ts_circle_radius=3, lmk_circle_radius=3)
結(jié)果:
如您所見,睜眼時的 EAR 值為0.28,閉眼時(接近于零)為 0.08。
【3】設(shè)計一個實時檢測系統(tǒng)。
首先,我們聲明兩個閾值和一個計數(shù)器。
- EAR_thresh: 用于檢查當(dāng)前EAR值是否在范圍內(nèi)的閾值。
- D_TIME:一個計數(shù)器變量,用于跟蹤當(dāng)前經(jīng)過的時間量EAR < EAR_THRESH.
- WAIT_TIME:確定經(jīng)過的時間量是否EAR < EAR_THRESH超過了允許的限制。
- 當(dāng)應(yīng)用程序啟動時,我們將當(dāng)前時間(以秒為單位)記錄在一個變量中t1并讀取傳入的幀。
接下來,我們預(yù)處理并frame通過Mediapipe 的 Face Mesh 解決方案管道。
- 如果有任何地標(biāo)檢測可用,我們將檢索相關(guān)的 ( Pi )眼睛地標(biāo)。否則,在此處重置t1 和重置以使算法一致)。D_TIME (D_TIME
- 如果檢測可用,則使用檢索到的眼睛標(biāo)志計算雙眼的平均EAR值。
- 如果是當(dāng)前時間,則加上當(dāng)前時間和to之間的差。然后將下一幀重置為。EAR < EAR_THRESHt2t1D_TIMEt1 t2
- 如果D_TIME >= WAIT_TIME,我們會發(fā)出警報或繼續(xù)下一幀。