卡車司機在白天和晚上長途運輸貨物和重物,他們經(jīng)常遭受睡眠不足的困擾。疲勞和困倦是高速公路上發(fā)生重大事故的一些主要原因。汽車行業(yè)正在研究一些可以檢測困倦并提醒駕駛員注意的技術。
在這個項目中,我們將使用 Raspberry Pi、OpenCV 和 Pi 攝像頭模塊為駕駛員構建睡眠感應和警報系統(tǒng)。該系統(tǒng)的基本目的是跟蹤駕駛員的面部狀況和眼球運動,如果駕駛員感到困倦,則系統(tǒng)將觸發(fā)警告信息。這是我們之前人臉地標檢測和人臉識別應用的擴展。
所需組件
硬件組件
樹莓派 3
Pi 相機模塊
微型 USB 數(shù)據(jù)線
蜂鳴器
軟件和在線服務
開放式CV
數(shù)據(jù)庫
在繼續(xù)這個 驅動程序嗜睡檢測項目之前, 首先我們需要在這個項目中安裝 OpenCV、imutils、dlib、Numpy 和一些其他依賴項。OpenCV在這里用于 數(shù)字圖像處理。數(shù)字圖像處理最常見的應用是 物體檢測、 人臉識別和 人數(shù)統(tǒng)計。
這里我們只使用樹莓派、Pi Camera 和蜂鳴器來構建這個睡眠檢測系統(tǒng)。
在樹莓派中安裝 OpenCV
在安裝 OpenCV 和其他依賴項之前,Raspberry Pi 需要完全更新。使用以下命令將 Raspberry Pi 更新到其最新版本:
?
sudo apt-get 更新
?
然后使用以下命令安裝在 Raspberry Pi 上安裝 OpenCV 所需的依賴項。
?
sudo apt-get install libhdf5-dev -y sudo apt-get install libhdf5-serial-dev –y sudo apt-get install libatlas-base-dev –y sudo apt-get install libjasper-dev -y sudo apt-get install libqtgui4 –y sudo apt-get install libqt4-test –y
?
最后,使用以下命令在 Raspberry Pi 上安裝 OpenCV。
?
pip3 安裝 opencv-contrib-python==4.1.0.25
?
安裝其他必需的軟件包
在對 Raspberry Pi 進行嗜睡檢測器編程之前,讓我們安裝其他所需的軟件包。
安裝 dlib:?dlib 是現(xiàn)代工具包,其中包含用于解決實際問題的機器學習算法和工具。使用以下命令安裝 dlib。
?
pip3 安裝 dlib
?
安裝 NumPy:?NumPy 是科學計算的核心庫,包含強大的 n 維數(shù)組對象,提供集成 C、C++ 等的工具。
?
pip3 安裝 numpy
?
安裝 face_recognition 模塊:該庫用于從 Python 或命令行識別和操作人臉。使用以下命令安裝人臉識別庫。
?
Pip3 安裝 face_recognition
?
最后,使用以下命令安裝eye_game庫:
?
pip3 安裝眼睛游戲
?
對樹莓派進行編程
使用 OpenCV 的 Driver Drrowsiness Detector的完整代碼在頁面末尾給出。在這里,我們將解釋代碼的一些重要部分,以便更好地理解。
因此,像往常一樣,通過包含所有必需的庫來啟動代碼。
?
導入人臉識別 導入簡歷2 將 numpy 導入為 np 進口時間 導入簡歷2 導入 RPi.GPIO 作為 GPIO 導入 eye_game
?
之后,創(chuàng)建一個實例以從 pi 相機獲取視頻源。如果您使用多個攝像頭,則在cv2.VideoCapture(0)函數(shù)中將零替換為一個。
?
video_capture = cv2.VideoCapture(0)
?
現(xiàn)在在接下來的幾行中,輸入文件的文件名和路徑。就我而言,代碼和文件都在同一個文件夾中。然后使用人臉編碼得到圖片中的人臉位置。
?
img_image = face_recognition.load_image_file("img.jpg") img_face_encoding = face_recognition.face_encodings(img_image)[0]
?
之后創(chuàng)建兩個數(shù)組來保存人臉及其名稱。我只使用一張圖片;您可以在代碼中添加更多圖像及其路徑。
?
known_face_encodings = [ img_face_encoding ] known_face_names = [ “阿什” ]
?
然后創(chuàng)建一些變量來存儲面部部位的位置、面部名稱和編碼。
?
face_locations = [] face_encodings = [] 面名 = [] process_this_frame = True
?
在while函數(shù)中,從流中捕獲視頻幀并將幀調整為更小的尺寸,并將捕獲的幀轉換為 RGB 顏色以進行人臉識別。
?
ret, frame = video_capture.read() small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25) rgb_small_frame = small_frame[:, :, ::-1]
?
之后,運行人臉識別過程,將視頻中的人臉與圖像進行比較。并獲得面部部位的位置。
?
如果 process_this_frame: face_locations = face_recognition.face_locations(rgb_small_frame) face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations) cv2.imwrite(文件,small_frame)
?
如果識別出的人臉與圖像中的人臉匹配,則調用eyegame函數(shù)跟蹤眼球運動。代碼會反復跟蹤眼球和眼球的位置。?
?
face_distances = face_recognition.face_distance(known_face_encodings, face_encoding) best_match_index = np.argmin(face_distances) 如果匹配[best_match_index]: 名稱 = known_face_names[best_match_index] 方向= eye_game.get_eyeball_direction(文件) 打?。ǚ较颍?/pre>?
如果代碼在 10 秒內沒有檢測到任何眼球運動,則會觸發(fā)警報將人叫醒。
?
別的: 計數(shù)=1+計數(shù) 打?。ㄓ嫈?shù)) 如果(計數(shù)>=10): GPIO.輸出(蜂鳴器,GPIO.HIGH) 時間.sleep(2) GPIO.輸出(蜂鳴器,GPIO.LOW) 打?。ā熬瘓螅【瘓?!檢測到駕駛員嗜睡”)?
然后使用 OpenCV 函數(shù)在面部周圍繪制一個矩形并在其上放置文本。此外,使用cv2.imshow函數(shù)顯示視頻幀。
?
cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2) cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 255, 0), cv2.FILLED) 字體 = cv2.FONT_HERSHEY_DUPLEX cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (0, 0, 255), 1) cv2.imshow('視頻', 幀) 設置鍵“S”以停止代碼。 如果 cv2.waitKey(1) & 0xFF == ord('s'): 休息?
測試駕駛員困倦檢測系統(tǒng)
代碼準備好后,將 Pi 攝像頭和蜂鳴器連接到Raspberry Pi并運行代碼。大約 10 秒后,將出現(xiàn)一個窗口,其中包含來自您的 Raspberry Pi 相機的實時流。當設備識別到人臉時,它會在框架上打印你的名字并開始跟蹤眼球運動?,F(xiàn)在閉上眼睛 7 到 8 秒來測試警報。當計數(shù)超過 10 時,它會觸發(fā)警報,提醒您有關情況。
?導入人臉識別
導入簡歷2
將 numpy 導入為 np
進口時間
導入簡歷2
導入 eye_game
導入 RPi.GPIO 作為 GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(假)
蜂鳴器= 23
GPIO.setup(蜂鳴器,GPIO.OUT)
以前的 =“未知”
計數(shù)=0
video_capture = cv2.VideoCapture(0)
#frame = (video_capture, 文件)
文件 = 'image_data/image.jpg'
# 加載示例圖片并學習如何識別它。
img_image = face_recognition.load_image_file("img.jpg")
img_face_encoding = face_recognition.face_encodings(img_image)[0]
# 創(chuàng)建已知人臉編碼及其名稱的數(shù)組
known_face_encodings = [
img_face_encoding
]
known_face_names = [
“阿什”
]
# 初始化一些變量
face_locations = []
face_encodings = []
面名 = []
process_this_frame = True
而真:
# 抓取單幀視頻
ret, frame = video_capture.read()
# 將視頻幀大小調整為 1/4 大小,以加快人臉識別處理
small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
# 將圖像從 BGR 顏色(OpenCV 使用)轉換為 RGB 顏色(face_recognition 使用)
rgb_small_frame = small_frame[:, :, ::-1]
# 只處理每隔一幀的視頻以節(jié)省時間
如果 process_this_frame:
# 查找當前視頻幀中的所有人臉和人臉編碼
face_locations = face_recognition.face_locations(rgb_small_frame)
face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)
cv2.imwrite(文件,small_frame)
面名 = []
對于 face_encodings 中的 face_encoding:
# 查看人臉是否與已知人臉匹配
匹配 = face_recognition.compare_faces(known_face_encodings, face_encoding)
名稱=“未知”
face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
best_match_index = np.argmin(face_distances)
如果匹配[best_match_index]:
名稱 = known_face_names[best_match_index]
方向= eye_game.get_eyeball_direction(文件)
打?。ǚ较颍?br /> #eye_game.api.get_eyeball_direction(cv_image_array)
如果前一個!=方向:
上一個=方向
別的:
print("老一樣")
計數(shù)=1+計數(shù)
打印(計數(shù))
如果(計數(shù)>=10):
GPIO.輸出(蜂鳴器,GPIO.HIGH)
時間.sleep(2)
GPIO.輸出(蜂鳴器,GPIO.LOW)
打?。ā熬瘓?!警報!檢測到駕駛員嗜睡”)
cv2.putText(frame, "睡意警報!", (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
face_names.append(名字)
process_this_frame = 不是 process_this_frame
# 顯示結果
對于(上、右、下、左),zip 中的名稱(face_locations,face_names):
# 縮放人臉位置,因為我們檢測到的幀被縮放到 1/4 大小
頂部 *= 4
對 *= 4
底部 *= 4
左 *= 4
# 在臉部周圍畫一個框
cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2)
# 在人臉下方繪制一個帶有名字的標簽
cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
字體 = cv2.FONT_HERSHEY_DUPLEX
cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (0, 0, 255), 1)
#cv2.putText(frame, frame_string, (left + 10, top - 10), font, 1.0, (255, 255, 255), 1)
# 顯示結果圖像
cv2.imshow('視頻', 幀)
# 按鍵盤上的“q”退出!
如果 cv2.waitKey(1) & 0xFF == ord('q'):
休息
# 釋放網(wǎng)絡攝像頭的句柄
video_capture.release()
cv2.destroyAllWindows()?
評論
查看更多