駕駛員嗜睡分類 - 深度學(xué)習(xí)
瞌睡檢測是一種汽車安全技術(shù),有助于防止駕駛員在駕駛時睡著了造成的事故。根據(jù) NHTSA(美國國家公路交通安全管理局)的數(shù)據(jù),警方報告的 91,000 起車禍涉及疲勞駕駛。這些車禍導(dǎo)致 2017 年估計有 50,000 人受傷和近 800 人死亡。目前,方法主要集中在使用深度學(xué)習(xí)或機(jī)器學(xué)習(xí)技術(shù)進(jìn)行眨眼檢測,但是,如果司機(jī)戴墨鏡怎么辦?
如果我們同時考慮駕駛員的頭部傾斜、打哈欠和其他因素會怎樣?是的,這正是本文所做的。
在進(jìn)入特征提取部分之前,從“ULg 多模態(tài)嗜睡數(shù)據(jù)庫”(也稱為DROZY )中獲取數(shù)據(jù),該數(shù)據(jù)庫包含各種類型的嗜睡相關(guān)數(shù)據(jù)(信號、圖像等)。
該數(shù)據(jù)集包含大約 45 個視頻剪輯,這些剪輯按照卡羅林斯卡嗜睡量表 (KSS) 進(jìn)行標(biāo)記。KSS 量表范圍從 1 到 9,其中 1 表示非常警覺,9 表示非常困。
由于該數(shù)據(jù)集中缺少數(shù)據(jù)和標(biāo)簽,因此將標(biāo)簽從 1-9 轉(zhuǎn)換為 1-3,分別表示無嗜睡、中度嗜睡和高度嗜睡。本來會使用視頻分類過程,但由于數(shù)據(jù)不夠,先提取特征并將它們用作我的模型輸入。這樣,模型將使用更少的數(shù)據(jù)達(dá)到更準(zhǔn)確的效果。
特征提取
對于這個特定任務(wù),我將使用 TensorFlow-GPU 2.6 和 python 3.6 以及使用 pip 預(yù)安裝的庫 open-cv、dlib、scipy。
特征提取所需的所有庫:
from scipy.spatial import distance as dist
from imutils.video import FileVideoStream
from imutils.video import VideoStream
from imutils import face_utils
import numpy as np
import argparse
import imutils
import time
import dlib
import cv2
import datetime
import csv
import os
import math
平均眨眼持續(xù)時間:眼睛縱橫比低于 0.3 然后高于 0.3 的持續(xù)時間被檢測為眨眼。眨眼發(fā)生的時間稱為眨眼持續(xù)時間。平均每分鐘眨眼持續(xù)時間以計算平均眨眼持續(xù)時間。
# grab the indexes of the facial landmarks for the left and
# right eye, respectively
(lStart, lEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"]
(rStart, rEnd) = face_utils.FACIAL_LANDMARKS_IDXS["right_eye"]
def eye_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)
return ear
眨眼頻率:每分鐘眨眼的次數(shù)稱為眨眼頻率。
def time_difference(start_time, end_time):
start_time = start_time.split()
for i in range(0,8):
hours = int(start_time[3])
mins = int(start_time[4])
secs = int(start_time[5])
milisecs = int(start_time[6])
microsecs = int(start_time[7])
#converting it to microsecs
t1, m1, s1, ms1, mis1 = hours, mins, secs, milisecs, microsecs
start_time_microsecs = mis1 + 1000*(ms1 + 1000*(s1 + 60*(m1 + 60*t1)))
end_time = end_time.split()
for x in range(0,8,1):
hours = int(end_time[3])
mins = int(end_time[4])
secs = int(end_time[5])
milisecs = int(end_time[6])
microsecs = int(end_time[7])
t2, m2, s2, ms2, mis2 = hours, mins, secs, milisecs, microsecs
end_time_microsecs = mis2 + 1000*(ms2 + 1000*(s2 + 60*(m2 + 60*t2)))
#finding the duration of blink
time_differ = end_time_microsecs - start_time_microsecs
#print 'time_difference in microsecs = ', time_differ
return time_differ
嘴部縱橫比:計算 MAR 以檢測一個人是否在打哈欠。
(omouth, emouth) = face_utils.FACIAL_LANDMARKS_IDXS["mouth"]
def mouth_aspect_ratio(mouth):
# compute the euclidean distances between the two sets of
# vertical mouth landmarks (x, y)-coordinates
A = dist.euclidean(mouth[2], mouth[10]) # 51, 59
B = dist.euclidean(mouth[4], mouth[8]) # 53, 57
# compute the euclidean distance between the horizontal
# mouth landmark (x, y)-coordinates
C = dist.euclidean(mouth[0], mouth[6]) # 49, 55
# compute the mouth aspect ratio
mar = (A + B) / (2.0 * C)
# return the mouth aspect ratio
return mar
頭部姿態(tài):每幀計算不同的角度,得到頭部的姿態(tài)。
def getHeadTiltAndCoords(size, image_points, frame_h(yuǎn)eight):
focal_length = size[1]
center = (size[1]/2, size[0]/2)
camera_matrix = np.a(chǎn)rray([[focal_length, 0, center[0]], [
0, focal_length, center[1]], [0, 0, 1]], dtype="double")
dist_coeffs = np.zeros((4, 1)) # Assuming no lens distortion
(_, rotation_vector, translation_vector) = cv2.solvePnP(model_points, image_points,
camera_matrix, dist_coeffs,
flags = cv2.SOLVEPNP_ITERATIVE) # flags=cv2.CV_ITERATIVE)
(nose_end_point2D, _) = cv2.projectPoints(np.a(chǎn)rray(
[(0.0, 0.0, 1000.0)]), rotation_vector, translation_vector, camera_matrix, dist_coeffs)
#get rotation matrix from the rotation vector
rotation_matrix, _ = cv2.Rodrigues(rotation_vector)
#calculate head tilt angle in degrees
head_tilt_degree = abs(
[-180] - np.rad2deg([rotationMatrixToEulerAngles(rotation_matrix)[0]]))
#calculate starting and ending points for the two lines for illustration
starting_point = (int(image_points[0][0]), int(image_points[0][1]))
ending_point = (int(nose_end_point2D[0][0][0]), int(nose_end_point2D[0][0][1]))
ending_point_alternate = (ending_point[0], frame_h(yuǎn)eight // 2)
return head_tilt_degree, starting_point, ending_point, ending_point_alternate
這就是我的特征提取過程中的樣子。
是時候制作模型了!
由于我們已經(jīng)完成了特征選擇部分,我們不必構(gòu)建復(fù)雜的模型。我將使用人工神經(jīng)網(wǎng)絡(luò)
import numpy as np
import sklearn
from sklearn import preprocessing
#from sklearn.datasets.samples_generator import make_blobs
#from sklearn.preprocessing import LabelEncoder, StandardScaler
import csv
import os
from tensorflow import keras
import random
from keras.models import Sequential
from keras.layers import Dense , Dropout, Activation, BatchNormalization
from keras import regularizers
importmatplotlib.pyplot as plt
#from keras.utils import plot_model
import sklearn
from sklearn.metrics import chaos_matrix
from sklearn.metrics import accuracy_score
from sklearn.metrics import classification_report
import pickle
from keras.utils import np_utils
from keras import optimizers
from keras.models import load_model
這是深度學(xué)習(xí)中最簡單的模型的設(shè)計,但由于特征提取而有效。因為我們計算的是每分鐘的瞌睡程度,所以要確保你將你的輸入連接起來,然后傳遞給模型。
#designing the model
model=Sequential()
model.a(chǎn)dd(Dense(64, input_dim=6, activation='relu'))
model.a(chǎn)dd(Dropout(0.001))
model.a(chǎn)dd(Dense(64, input_dim=6, activation='relu'))
model.a(chǎn)dd(Dropout(0.001))
model.a(chǎn)dd(Dense(32, input_dim=6, activation='relu'))
model.a(chǎn)dd(Dense(16, input_dim=6, activation='relu'))
model.a(chǎn)dd(Dense(4, activation='softmax', use_bias=False))
#compile the model
#adam = keras.optimizers.Adam(lr=0.01)
adam = keras.optimizers.Adam(lr=0.001)
model.compile(loss='categorical_crossentropy', optimizer=adam, metrics=['accuracy'])
#fit the model
checkpoint = keras.callbacks.ModelCheckpoint(filepath="trained_models/DrowDet_model(output4).hdf5", period=1)
tbCallBack = keras.callbacks.TensorBoard(log_dir='./scalar',
histogram_freq=0, write_graph=True, write_images=True)
history=model.fit(Xtrain, Ytrain, epochs=50, batch_size=256, callbacks=[checkpoint, tbCallBack], validation_data=(Xval,Yval))
使用準(zhǔn)確性與驗證準(zhǔn)確性和訓(xùn)練損失與驗證損失的模型性能。
超參數(shù)調(diào)優(yōu)模型!我改變了學(xué)習(xí)率(0.01 -> 0.001),不同的優(yōu)化器(RMSprop),時期數(shù)(20 -> 50)。
使用 Sklearn 的混淆矩陣,我在測試集上評估了模型,得到了 73% 的準(zhǔn)確率和 89% 的訓(xùn)練準(zhǔn)確率。再使用大約 4 個隱藏層,我在測試集上得到了大約 74% 的準(zhǔn)確率,在訓(xùn)練數(shù)據(jù)集上得到了 93% 的準(zhǔn)確率。
原文標(biāo)題 : 駕駛員嗜睡分類 - 深度學(xué)習(xí)
請輸入評論內(nèi)容...
請輸入評論/評論長度6~500個字
最新活動更多
推薦專題
- 1 Intel宣布40年來最重大轉(zhuǎn)型:年底前裁員15000人、拋掉2/3房產(chǎn)
- 2 因美封殺TikTok,字節(jié)股價骨折!估值僅Meta1/5
- 3 宏山激光重磅發(fā)布行業(yè)解決方案,助力智能制造產(chǎn)業(yè)新飛躍
- 4 國產(chǎn)AI芯片公司破產(chǎn)!白菜價拍賣
- 5 具身智能火了,但規(guī)模落地還需時間
- 6 三次錯失風(fēng)口!OpenAI前員工殺回AI編程賽道,老東家捧金相助
- 7 國產(chǎn)英偉達(dá)們,抓緊沖刺A股
- 8 英特爾賦能智慧醫(yī)療,共創(chuàng)數(shù)字化未來
- 9 英偉達(dá)的麻煩在后頭?
- 10 將“網(wǎng)紅”變成“商品”,AI“爆改”實力拉滿
- 高級軟件工程師 廣東省/深圳市
- 自動化高級工程師 廣東省/深圳市
- 光器件研發(fā)工程師 福建省/福州市
- 銷售總監(jiān)(光器件) 北京市/海淀區(qū)
- 激光器高級銷售經(jīng)理 上海市/虹口區(qū)
- 光器件物理工程師 北京市/海淀區(qū)
- 激光研發(fā)工程師 北京市/昌平區(qū)
- 技術(shù)專家 廣東省/江門市
- 封裝工程師 北京市/海淀區(qū)
- 結(jié)構(gòu)工程師 廣東省/深圳市