主頁 > 後端開發 > Python OpenCV --Drowsiness Detector 睡意檢測--專案記錄

Python OpenCV --Drowsiness Detector 睡意檢測--專案記錄

2020-12-10 18:06:51 後端開發

在這里插入圖片描述
睡意檢測是一項安全技術,可以防止駕駛員在駕駛中入睡而導致的事故,
目的是建立一個睡意檢測系統,該系統將檢測人的眼睛閉合幾秒鐘, 當檢測到困倦時,該系統將警告駕駛員,

睡意檢測版本1.0

睡眠檢測關鍵步驟

步驟1-從相機獲取影像作為輸入,
步驟2-檢測影像中的人臉并創建關注區域(ROI),
步驟3-從ROI中檢測眼睛并將其輸入分類器,
步驟4-分類器將對眼睛睜開還是閉眼進行分類,
步驟5-計算檢查該人是否困倦,

1.1睡眠檢測前期軟體配置

軟體1.OpenCV – pip安裝opencv-python (面部和眼睛檢測),
由于Tensorflow安裝到處采坑,我老老實實慢慢的確定版本號,
Windows 安裝OpenCV

  • 1.準備版本號查詢
    cmd->pip list

pycharm->File->setting->Project:檔案名->Project Interpreter->在左側Package找 python->對應Version即為版本號
即環境 python版本為3.8 tensorflow版本為2.3.1 Windows系統為64

  • 2.確定你是否已經安裝了numpy,

  • 3.opencv下載網站找對應python3.8版本下載.whl 檔案,

  python3.8:opencv_python?4.4.0?cp38?cp38?win_amd64.whl
  opencv下載網站:https://www.lfd.uci.edu/~gohlke/pythonlibs
  • 4.將這個opencv_python?4.4.0?cp38?cp38?win_amd64.whl檔案復制到D:\根目錄下即可**
  • 5.打開cmd,將路徑切換到D:,然后輸入:
pip install opencv_python?4.4.0?cp38?cp38?win_amd64.whl 回車

軟體2.TensorFlow – pip安裝tensorflow(keras使用TensorFlow作為后端),
軟體3.Keras – pip安裝keras(建立我們的分類模型),
軟體4.Pygame –點子安裝pygame(播放警報聲音),

1.2資料集

用于此模型的資料集由我們創建, 為了創建資料集,我們撰寫了一個腳本,可以捕獲相機的眼睛并將其存盤在本地磁盤, 我們將它們分成各自的標簽“打開”或’關閉’, 通過洗掉不需要的影像手動清除了資料,這對于構建模型不是必需的, 資料包括在不同的照明條件下,大約有7000張人眼影像,在資料集上訓練模型后,我們將最終權重和模型架構檔案“ models / cnnCat2.h5”,
現在,您可以使用此模型對人眼睜開或閉眼進行分類,

1.3模型架構

我們使用的模型是通過Keras使用卷積神經網路(CNN)構建的, 卷積神經網路是一種特殊的深度神經網路,在影像分類方面表現非常出色, CNN基本上由一個輸入層、一個輸出層和一個可以包含多個層的隱藏層組成, 使用在層和濾波器上執行2D矩陣乘法的濾波器對這些層執行卷積操作,

CNN模型架構包括以下幾層:

卷積層; 32個節點,內核大小為3
卷積層; 32個節點,內核大小為3
卷積層; 64個節點,內核大小3
全連接層; 128個節點
最后一層也是具有2個節點的完全連接的層, 在所有層,除了在輸出層中使用Relu激活功能,我們都使用Softmax,

2.Python專案執行駕駛員睡意檢測步驟

從zip下載Python專案源代碼,然后將檔案提取到系統中: Python Project Zip File
壓縮檔案的內容為:

“ haar級聯檔案”檔案夾包含從影像中檢測物件所需的xml檔案, 在我們的案例中,我們正在檢測人的臉部和眼睛,
models檔案夾包含我們的模型檔案“ cnnCat2.h5”,該檔案在卷積神經網路上進行了訓練,
我們有一個音頻剪輯“ alarm.wav”,當人昏昏欲睡時播放,
“ Model.py”檔案包含該程式,通過該程式,我們可以通過對資料集進行訓練來構建分類模型, 您可以在此檔案中看到卷積神經網路的實作,
“睡意檢測.py”是我們專案的主檔案, 要開始檢測程序,我們必須運行此檔案,
現在讓我們逐步了解我們的演算法,步驟1–將影像作為來自攝像機的輸入
使用網路攝像頭,我們將影像作為輸入, 因此,要訪問網路攝像頭,我們進行了無限回圈,將捕獲每個幀, 我們使用OpenCV提供的方法cv2.VideoCapture(0)訪問攝像機并設定捕獲物件(上限), cap.read()將讀取每一幀,然后將影像存盤在frame變數中,

3.在影像中檢測人臉并創建關注區域(ROI)

要檢測影像中的人臉,我們首先需要將影像轉換為灰度,因為用于物件檢測的OpenCV演算法在輸入中獲取了灰度影像, 我們不需要顏色資訊來檢測物體, 我們將使用haar級聯分類器來檢測人臉, 該行用于設定分類器face = cv2.CascadeClassifier(‘我們的haar級聯xml檔案的路徑’) , 然后,我們使用faces = face.detectMultiScale(gray)執行檢測, 它回傳帶有x,y坐標的檢測陣列,高度為物件邊界框的寬度, 現在我們可以遍歷這些面并為每個面繪制邊界框,

for (x,y,w,h) in faces:
 
cv2.rectangle(frame, (x,y), (x+w, y+h), (100,100,100), 1 )

4. 從ROI中檢測眼睛并將其輸入分類器

檢測臉部的相同程序也用于檢測眼睛, 首先,我們分別在leye和reye中為眼睛設定級聯分類器,然后使用left_eye = leye.detectMultiScale(gray)來檢測眼睛, 現在,我們只需要從完整影像中提取眼睛資料即可, 這可以通過提取眼睛的邊界框來實現,然后我們可以使用此代碼從幀中提取眼睛影像,

I_eye = frame[ y : y+h, x : x+w ]
l_eye僅包含眼睛的影像資料, 這將被輸入到我們的CNN分類器中,該分類器將預測眼睛是睜著還是閉著, 同樣,我們將右眼提取到r_eye中 ,

5.分類器將對眼睛睜開還是閉眼進行分類

我們正在使用CNN分類器來預測眼睛狀態, 要將影像輸入到模型中,我們需要執行某些操作,因為模型首先需要正確的尺寸, 首先,我們使用r_eye = cv2.cvtColor(r_eye,cv2.COLOR_BGR2GRAY)將彩色影像轉換為灰度,

然后,當我們的模型在24 * 24像素影像cv2.resize(r_eye,(24,24))上訓練時,我們將影像調整為24 * 24像素, 我們對資料進行歸一化以獲得更好的收斂性r_eye = r_eye / 255 (所有值將在0-1之間), 擴展尺寸以輸入到我們的分類器中, 我們使用model = load_model('models / cnnCat2.h5')加載了模型, 現在我們用模型預測每只眼睛
lpred = model.predict_classes(l_eye) 如果lpred [0]的值= 1,則表明眼睛是張開的;如果lpred [0]的值= 0,則表明眼睛是張開的,

6.計算分數以檢查人是否困倦

分數基本上是一個值,我們將使用該值來確定該人閉上眼睛多長時間, 因此,如果兩只眼睛都閉合,我們將繼續增加得分,而當眼睛睜開時,我們將降低得分, 我們正在使用cv2.putText()函式在螢屏上繪制結果,該函式將顯示人員的實時狀態,

cv2.putText(frame, “Open”, (10, height-20), font, 1, (255,255,255), 1, cv2.LINE_AA )

例如,如果得分變得大于15,則定義一個閾值,這意味著該人的眼睛長時間閉合, 這是當我們使用sound.play()發出警報聲,

7.程式源代碼

7.1分塊部分

 import cv2
 import os
 from keras.models
 import load_model
 import numpy as np
 from pygame import mixer
 //匯入各個需要的庫
import time
mixer.init()
 //匯入聲音提示部分
sound = mixer.Sound('alarm.wav')
face = cv2.CascadeClassifier('haar cascade files\haarcascade_frontalface_alt.xml')
leye = cv2.CascadeClassifier('haar cascade files\haarcascade_lefteye_2splits.xml')
reye = cv2.CascadeClassifier('haar cascade files\haarcascade_righteye_2splits.xml')
//檔案路徑錄入
lbl=['Close','Open']
model = load_model('models/cnncat2.h5')
path = os.getcwd()
cap = cv2.VideoCapture(0)
font = cv2.FONT_HERSHEY_COMPLEX_SMALL
count=0
score=0
thicc=2
rpred=[99]
lpred=[99]
 //引數賦初值
while(True): 
ret, frame = cap.read() 
height,width = frame.shape[:2]
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face.detectMultiScale(gray,minNeighbors=5,scaleFactor=1.1,minSize=(25,25))
left_eye = leye.detectMultiScale(gray)
right_eye = reye.detectMultiScale(gray) 
cv2.rectangle(frame, (0,height-50) , (200,height) , (0,0,0) , thickness=cv2.FILLED )
for (x,y,w,h) in faces:
cv2.rectangle(frame, (x,y) , (x+w,y+h) , (100,100,100) , 1 ) 
 //彩色影像變灰色影像,ROI選取,影像基礎處理
for (x,y,w,h) in right_eye:
r_eye=frame[y:y+h,x:x+w]
 count=count+1
r_eye = cv2.cvtColor(r_eye,cv2.COLOR_BGR2GRAY) 
r_eye = cv2.resize(r_eye,(24,24))
r_eye= r_eye/255
r_eye= r_eye.reshape(24,24,-1)
r_eye = np.expand_dims(r_eye,axis=0)
rpred = model.predict_classes(r_eye)
if(rpred[0]==1):
 lbl='Open'
if(rpred[0]==0):
 lbl='Closed'
 break
for (x,y,w,h) in left_eye:
l_eye=frame[y:y+h,x:x+w]
count=count+1
l_eye = cv2.cvtColor(l_eye,cv2.COLOR_BGR2GRAY)
 l_eye = cv2.resize(l_eye,(24,24))
 l_eye= l_eye/255
 l_eye=l_eye.reshape(24,24,-1)
 l_eye = np.expand_dims(l_eye,axis=0)
 lpred = model.predict_classes(l_eye)
if(lpred[0]==1):
lbl='Open'
if(lpred[0]==0):
lbl='Closed'
break
//判斷左、右眼睜開閉合
if(rpred[0]==0 and lpred[0]==0):
score=score+1
cv2.putText(frame,"Closed",(10,height-20), font, 1,(255,255,255),1,cv2.LINE_AA)
# if(rpred[0]==1 or lpred[0]==1): 
else:
score=score-1
cv2.putText(frame,"Open",(10,height-20), font, 1,(255,255,255),1,cv2.LINE_AA)
if(score<0):
score=0
cv2.putText(frame,'Score:'+str(score),(100,height-20), font, 1,(255,255,255),1,cv2.LINE_AA)
if(score>15):
#person is feeling sleepy so we beep the alarm
cv2.imwrite(os.path.join(path,'image.jpg'),frame)
//對影像打上標簽,表上分數
try: 
sound.play()
//聲音警報
except: # isplaying = False 
pass
if(thicc<16):
thicc= thicc+2
else: 
thicc=thicc-2 
if(thicc<2):
thicc=2
cv2.rectangle(frame,(0,0),(width,height),(0,0,255),thicc)
cv2.imshow('frame',frame)
//界面美觀處理
if cv2.waitKey(1) & 0xFF == ord('q'):
break 
cap.release()
cv2.destroyAllWindows()
//銷毀視窗

7.2代碼細解

import cv2
 //匯入cv2庫
import os
 //匯入os庫
from keras.models
 //匯入keras模型
import load_model
 //匯入load
import numpy as np
 //匯入numpy庫并賦予別名np
from pygame import mixer
 //匯入pygame包中mixer函式
import time
 //匯入庫time
mixer.init()
 //初始化混音器
sound = mixer.Sound('alarm.wav')
//從檔案緩沖區物件創建新的sound物件
face = cv2.CascadeClassifier('haar cascade files\haarcascade_frontalface_alt.xml')
//檢測capture檔案是否在路徑下面
leye = cv2.CascadeClassifier('haar cascade files\haarcascade_lefteye_2splits.xml')
//檢測capture檔案是否在路徑下面
reye = cv2.CascadeClassifier('haar cascade files\haarcascade_righteye_2splits.xml')
//檢測capture檔案是否在路徑下面
lbl=['Close','Open']
//串列b包含兩個標簽
model = load_model('models/cnncat2.h5')
path = os.getcwd()
//回傳當前所在目錄路徑
cap = cv2.VideoCapture(0)
//獲得攝像頭
font = cv2.FONT_HERSHEY_COMPLEX_SMALL
//font=文本字體
count=0
score=0
thicc=2
rpred=[99]
lpred=[99]
 while(True):
 //開始回圈
ret, frame = cap.read()
 //引數ret為T或F表示有沒有讀到圖片,frame表示截取到一幀的圖片
height,width = frame.shape[:2]
 //每一幀圖片的長、寬賦值給heigh、weight
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
 //將每一幀影像變為灰度影像
faces = face.detectMultiScale(gray,minNeighbors=5,scaleFactor=1.1,minSize=(25,25))
 //灰度圖片minNeighbors-表示構成目標的相鄰矩陣的最小個數為5個 scaleFactor--表示在前后兩次相繼的掃描中,搜索視窗的比例系數,默認為1.1即每次搜索視窗依次擴大10%  minsize:限制得到的目標區域的范圍為2525
left_eye = leye.detectMultiScale(gray)
 //檢測左人臉灰度圖片
right_eye = reye.detectMultiScale(gray)
 //檢測右人臉灰度圖片
cv2.rectangle(frame, (0,height-50) , (200,height) , (0,0,0) , thickness=cv2.FILLED )
 //對每一幀frame影像進行影像剪切,左上角坐標為(0,height-50) ,右下角坐標為(200,height)邊框顏色為(0,0,0),邊框填充整個矩形
for (x,y,w,h) in faces:
cv2.rectangle(frame, (x,y) , (x+w,y+h) , (100,100,100) , 1 )
  //對每一幀frame影像進行影像剪切,左上角坐標為(x,y)  ,右下角坐標為(x+w,y+h)邊框顏色為(100,100,100),邊框為1
for (x,y,w,h) in right_eye:
 //進行判斷左眼是否睜開閉合
r_eye=frame[y:y+h,x:x+w]
// 提取眼睛的邊界框來實作,幀中提取左眼睛影像資料
count=count+1
r_eye = cv2.cvtColor(r_eye,cv2.COLOR_BGR2GRAY)
 //將顏色轉換函式將r_eye圖片BGR圖片轉換為灰度圖片(單通道、八整型)
r_eye = cv2.resize(r_eye,(24,24))
 //將影像尺寸變為24*24像素
r_eye= r_eye/255
 //為了資料收斂性,將數值歸在0-1之間
r_eye= r_eye.reshape(24,24,-1)
 //將r_eye的矩陣/陣列重組,以2424串列示,
r_eye = np.expand_dims(r_eye,axis=0)
 //這個資料在axis這個軸0位置就是在axis的那一個軸把資料加上去
rpred = model.predict_classes(r_eye)
//keras模型-樣本所屬類別標簽 
if(rpred[0]==1):
 //判斷是否睜眼閉眼
lbl='Open'
 //睜眼
if(rpred[0]==0):
lbl='Closed'
 //閉眼
break
 //退出
for (x,y,w,h) in left_eye:
 //進行判斷右眼是否睜開閉合
l_eye=frame[y:y+h,x:x+w]
 // 提取眼睛的邊界框來實作,幀中提取左眼睛影像資料
count=count+1
l_eye = cv2.cvtColor(l_eye,cv2.COLOR_BGR2GRAY)
  //將顏色轉換函式將r_eye圖片BGR圖片轉換為灰度圖片(單通道、八整型)
l_eye = cv2.resize(l_eye,(24,24))
 //將影像尺寸變為24*24像素
l_eye= l_eye/255
 //為了資料收斂性,將數值歸在0-1之間
l_eye=l_eye.reshape(24,24,-1)
  //將l_eye的矩陣/陣列重組,以2424串列示,
l_eye = np.expand_dims(l_eye,axis=0)
  //這個資料在axis這個軸0位置就是在axis的那一個軸把資料加上去
lpred = model.predict_classes(l_eye)
 //keras模型-樣本所屬類別標簽 
if(lpred[0]==1):
 //判斷是否睜眼閉眼
lbl='Open'
 //睜眼
if(lpred[0]==0):
lbl='Closed'
 //閉眼
break 
if(rpred[0]==0 and lpred[0]==0):
score=score+1
cv2.putText(frame,"Closed",(10,height-20), font, 1,(255,255,255),1,cv2.LINE_AA)
 //frame圖片打上closed標簽,帶上左上角數值為(10,height-20)的坐標,字體為font,字號為1字體顏色(255,255,255),字體粗細為1 
else:
score=score-1
cv2.putText(frame,"Open",(10,height-20), font, 1,(255,255,255),1,cv2.LINE_AA)
 //frame圖片列印上open標簽,帶上左上角數值為(10,height-20)的坐標,字體為font,字號為1顏色為(255,255,255),字體粗細為1
if(score<0): 
score=0
cv2.putText(frame,'Score:'+str(score),(100,height-20), font, 1,(255,255,255),1,cv2.LINE_AA)
 //frame圖片列印上'Score:'+str(score)標簽,帶上左上角數值為(100,height-20)的坐標,字體為font,字號為1顏色為(255,255,255),字體粗細為1 
if(score>15): 
cv2.imwrite(os.path.join(path,'image.jpg'),frame)
 //將圖片保存并將path和image.jpg的路徑組合,圖片保存型別為frame幀
try:
sound.play()
 //播放警告音樂
except: # isplaying = False 
pass
if(thicc<16):
thicc= thicc+2
else:
thicc=thicc-2
if(thicc<2):
thicc=2
cv2.rectangle(frame,(0,0),(width,height),(0,0,255),thicc)
 //frame影像以(00)為左上角(width,height)為右下角兩點rgb為(00255)矩形厚度為thicc
cv2.imshow('frame',frame)
 //輸出圖片
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
#需要放置在while回圈體外,釋放Camera,
cv2.destroyAllWindows()
#需要放置在while回圈體外,銷毀所有視窗,

8.源代碼語法決議補充

detectMultiScale函式引數
引數1:image–待檢測圖片,一般為灰度影像加快檢測速度;
引數2:objects–被檢測物體的矩形框向量組;
引數3:scaleFactor–表示在前后兩次相繼的掃描中,搜索視窗的比例系數,默認為1.1即每次搜索視窗依次擴大10%;
引數4:minNeighbors–表示構成檢測目標的相鄰矩形的最小個數(默認為3個),
如果組成檢測目標的小矩形的個數和小于 min_neighbors - 1 都會被排除,
如果min_neighbors 為 0, 則函式不做任何操作就回傳所有的被檢候選矩形框,
這種設定值一般用在用戶自定義對檢測結果的組合程式上;
引數5:flags–要么使用默認值,要么使用CV_HAAR_DO_CANNY_PRUNING,如果設定為
CV_HAAR_DO_CANNY_PRUNING,那么函式將會使用Canny邊緣檢測來排除邊緣過多或過少的區域,
因此這些區域通常不會是人臉所在區域;
引數6、7:minSize和maxSize用來限制得到的目標區域的范圍

os 模塊中常用的屬性和函式
1.os.getcwd():查看當前所在目錄(路徑);
2.os.chdir():切換目錄(路徑);
3.os.curdir、os.pardir:回傳當前目錄字串名、回傳當前目錄的父目錄的字串名;
4.os.makedirs():生成一個多層遞回目錄
5.os.removedirs():若目錄為空,則洗掉,并遞回到上一級目錄,如若也為空,則洗掉,依次類推;
6.os.mkdir():創建一個目錄;
7.os.rmdir():洗掉一個目錄,若目錄不為空則無法洗掉,報錯;
8.os.listdir():顯示指定目錄下,所有的檔案和子目錄,包括隱藏檔案;

cv2.CascadeClassifier()函式
CascadeClassifier,是Opencv中做人臉檢測的時候的一個級聯分類器,并且既可以使用Haar,也可以使用LBP特征,
Haar特征是一種反映影像的灰度變化的,像素分模塊求差值的一種特征,它分為三類:邊緣特征、線性特征、中心特征和對角線特征,用黑白兩種矩形框組合成特征模板,在特征模板內用 黑色矩形像素和 減去 白色矩形像素和來表示這個模版的特征值,例如:臉部的一些特征能由矩形模塊差值特征簡單的描述,如:眼睛要比臉頰顏色要深,鼻梁兩側比鼻梁顏色要深,嘴巴比周圍顏色要深等,但矩形特征只對一些簡單的圖形結構,如邊緣、線段較敏感,所以只能描述在特定方向(水平、垂直、對角)上有明顯像素模塊梯度變化的影像結構,這樣就可以進行區分人臉,

def getfacefromcamera(outdir):
    createdir(outdir)
    #獲取攝像頭
    camera = cv2.VideoCapture(0)
    #要檢測cascade檔案是否在路徑下,最后一般使用絕對路徑,
    haar = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
    n = 1
    while 1:
        if (n <= 200):
            print('It`s processing %s image.' % n)
            # 讀幀(從攝像頭當中讀取照片)
            success, img = camera.read()
            # 將圖片進行轉灰
            gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            faces = haar.detectMultiScale(gray_img, 1.3, 5)
            for f_x, f_y, f_w, f_h in faces:
                face = img[f_y:f_y+f_h, f_x:f_x+f_w]
                face = cv2.resize(face, (IMGSIZE, IMGSIZE))
                #could deal with face to train
                face = relight(face, random.uniform(0.5, 1.5), random.randint(-50, 50))
                cv2.imwrite(os.path.join(outdir, str(n)+'.jpg'), face)
 
                cv2.putText(img, 'haha', (f_x, f_y - 20), cv2.FONT_HERSHEY_SIMPLEX, 1, 255, 2)  #顯示名字
                img = cv2.rectangle(img, (f_x, f_y), (f_x + f_w, f_y + f_h), (255, 0, 0), 2)
                n+=1
            cv2.imshow('img', img)
            key = cv2.waitKey(30) & 0xff
            if key == 27:
                break
        else:
            break
    camera.release()
    cv2.destroyAllWindows()

cv2.putText()

cv2.putText(img, str(i), (123,456), font, 2, (0,255,0), 3)

各引數依次是:圖片、添加的文字,左上角的坐標、字體、字體大小、顏色、字體粗細,
#img – 想要列印上文字的影像
#text – 想要列印的文字
#fontScale – 字號
#color – 顏色
#org – 文字的左下角坐標
#fontFace – 字體,可選的有:
FONT_HERSHEY_SIMPLEX,
FONT_HERSHEY_PLAIN, FONT_HERSHEY_DUPLEX,
FONT_HERSHEY_COMPLEX, FONT_HERSHEY_TRIPLEX,
以及 FONT_HERSHEY_SCRIPT_COMPLEX, 其中任意一種字體
都可加上 FONT_ITALIC 使其變為斜體

os.path,join()路徑拼接函式
join()函式
1. ‘sep’.join(seq)
引數:
sep:分隔符,可以為空
seq:要連接的元素序列、字串、元組、字典
上面的語法即:以sep作為分隔符,將seq所有的元素合并成一個新的字串
回傳值:回傳一個以分隔符sep連接各個元素后生成的字串
2.os.path.join()函式
語法: os.path.join(path1[,path2[,……]])
回傳值:將多個路徑組合后回傳
3.os.path.join()函式:連接兩個或更多的路徑名組件
如果各組件名首字母不包含’/’,則函式會自動加上
如果有一個組件是一個絕對路徑,則在它之前的所有組件均會被舍棄
如果最后一個組件為空,則生成的路徑以一個’/’分隔符結尾
注意:若出現”./”開頭的引數,會從”./”開頭的引數的上一個引數開始拼接

cv2.imwrite函式
cv2.imwrite(1.“圖片名字.格式”,2.Mat型別的影像資料,3.特定格式保存的引數編碼,默認值std::vector() 所以一般可以不寫,

pygame函式方法
pygame.mixer.Sound():播放音頻

方法含義
play()播放音頻
stop()停止播放
fadeout()淡出
set_volume()設定音量
get_volume()獲取音量
get_num_channels()計算該音效播放了多少次
get_length()獲得該音效的長度
get_raw()將該音效以二進制格式的字串回傳

cv2.rectangle 引數含義

 https://blog.csdn.net/sinat_41104353/article/details/85171185?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160437362219724836764895%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=160437362219724836764895&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v28-2-85171185.first_rank_ecpm_v3_pc_rank_v2&utm_term=cv2.rectangle&spm=1018.2118.3001.4449

本文借鑒網站:

https://blog.csdn.net/dfsgwe1231/article/details/105993294?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160370033719724822515506%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=160370033719724822515506&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v28-1-105993294.first_rank_ecpm_v3_pc_rank_v2&utm_term=%E7%9D%A1%E6%84%8F%E6%A3%80%E6%B5%8B&spm=1018.2118.3001.4187

由于該版本源代碼包無法下載 ,本人換了一個開源代碼,睡意檢測版本2.0開始

睡意檢測版本2.0

通過預測司機開車狀態來預防交通事故事故利用cnn和LSTMs檢測睡意的分類,使用維奧拉·瓊斯人臉檢測器進行人臉檢測后,我們進行跟蹤眼睛,這些資訊被輸入到一個預先訓練好的CNN序列然后將CNN提取的特征賦給LSTM檢測嗜睡,

睡眠檢測簡單思路

  • 1.利用Haar Cascades和CamShift演算法,通過視頻中實時眼球跟蹤,建立司機睡意檢測模型,
  • 2.使用CNN從最終池化層中提取的每個視頻幀的顯著特征作為連續幀的特征向量序列進行縫合,
  • 3.這個序列(2048-D)作為長短期記憶(LSTM)遞推神經網路(RNN)的輸入,根據視頻序列預測司機的瞌睡,并在這種情況下發出警報,
  • 4.通過Adam優化演算法優化網路權值,

1.1睡眠檢測前期軟體配置

  • 軟體1:Python 2.7(本人用的3.8,python2與python3并不兼容,版本不同,代碼有微小區別)
  • 軟體2:OpenCV 3.3.0, (本人用的4.4.0,與python對應版本)
  • 軟體3:Tensorflow2.2.0
  • 各種包: Keras, CNN, RNN, LSTM

1.2資料集

  • 資料收集
    8名被試(男6名,女2名)模仿視頻警覺和困倦的跡象被記錄下來在環境記錄條件下,在錄音在這些視頻中,受試者被要求表演一些特定的動作模仿睡意的動作,如緩慢地閉上眼皮眼睛下垂,緊接著頭部姿勢迅速恢復模仿微睡眠,為了模仿警覺性,受試者被要求看不同的方向有/沒有頭運動,
  • 資料集:由16個訓練和3個測驗組成視頻,都包含類:Alert-Eyes和DrowsyEyes,視頻是用CMOS前置網路攝像頭錄制的
    1280x720p,頻率30fps,閃爍減少50hz,
  • 人臉ROI檢測和眼睛檢測模塊:我們使用基于Viola-Jones haar特征的級聯分類器[6]用于人臉檢測,為了避免錯誤陽性,我們首先檢測到感興趣的面部區域(fROI)然后對該ROI進行眼檢測,得到a包含一雙眼睛的矩形區域貼片,后在第一幀中檢測人臉和眼睛,我們跟蹤他們使用CAMShift(連續自適應Mean-shift),下面的圖表顯示了關閉的檢測以及
    睜開眼睛,

1.3模型結構

  • 卷積神經網路(incep -v3)模塊我們手動創建一個影像資料集用于特征提取,用大約120幅影像制作了兩個類它們分別是醒眼和倦眼,提取重要從這些影像的視覺特征,我們使用卷積神經網路(CNNs),這是最先進的影像分類和特征提取,我們適應了預先訓練模型,v3[12],這是訓練包含1000個類的大型資料集Scale Visual Recognition Challenge(2012)[10],使用轉移學習程序中,我們重新訓練了這個模型的最后一層資料集與Tensorflow[11],完成4000個訓練步驟后,我們的模型驗證集的準確率達到了96.5%,
    我們運行了每個視頻的每一幀(影像)建模并保存來自最終池化層的輸出(pool-3:0),這將得到一個2048維的向量特征,我們傳遞給順序神經模型,最后,我們將這些提取的特征轉化為序列提取的特征,
  • 長期記憶網路是一種特殊的記憶網路回圈神經網路,能夠長期學習依賴,同時避免消失和爆發梯度問題,每個塊遞回地包含一個或多個連接記憶細胞和三乘法單元,輸入,輸出和遺忘門,控制資訊在記憶體塊內部流動,
  • LSTM框架支持預測(文本描述)用于視覺時間序列問題,在昏昏欲睡的驅動檢測,拼接特征(16個視頻x 26幀x1024個特征向量)用于訓練序列模型,我們使用了一個4096寬的LSTM層,然后厚層1024層,中間有一些空隙我們對模型進行了10個epoch的訓練,批量為4個,使用Keras和Tensorflow作為后端,我們使用[13]Adam優化器配置的學習率為0.00005訓練和優化我們的網路權值,下面的圖4顯示了我們的LSTM模型的體系結構,

2.Python專案執行駕駛員睡意檢測源代碼

源代碼網站:https://github.com/TejasNaikk/DriverDrowsiness_Detection

代碼報錯問題記錄

TabError: inconsistent use of tabs and spaces in indentation
問題原因:混用了Tab和4個空格造成的,要么全用Tab,要么全用4個空格,
解決方法
在這里插入圖片描述
在這里插入圖片描述
SyntaxError:invalid syntax
問題原因:語法錯誤,
解決方法

  • 版本問題:python2與python3是不兼容的,python2 print無括號,python3 print有括號,
  • 粗心問題:if,elif,else,for,while,class,def宣告末尾添加冒號( : ) 誤將=當作==使用,
  • 縮進未對齊,混用了Tab和4個空格,

return SyntaxError: return outside function
問題原因:原因是return關鍵字只能在def自定義函式里面使用,在while回圈中只能使用break關鍵字來結束回圈!這里沒有自定義函式,所以不能出現return這樣的關鍵字
解決方法:j將return改成break或調整縮進將return調整到def中,

pycharm 中import 代碼塊 呈現灰色
問題:pycharm中單個py檔案匯入包時呈灰色,而別的檔案卻能正常顯示
解決辦法
將滑鼠移動到那行代碼,點擊出現提示“Unused import statement”表示import宣告不可用,左邊同時出現黃色小燈泡,將滑鼠移動至黃色小燈泡那里,會出現向下箭頭,點擊箭頭出現下拉選單,繼續點擊第一條“Optimize imports”(切記要點擊的是最右邊的三角號,不是這一整行,否則會出錯),右面選擇第四個“Suppress for statement”,
在這里插入圖片描述
解決效果
在這里插入圖片描述

train.py 檔案原始碼

rom keras.callbacks import TensorBoard, ModelCheckpoint, EarlyStopping, CSVLogger
from models import ResearchModels
from data import Dataset
import time
import os
import os.path
import numpy as np


def train(batch_size=4, nb_epoch=10):

	checkpointer = ModelCheckpoint(
		filepath=os.path.join('data', 'checkpoints', 'lstm' + '-' + 'features' + \
			'.{epoch:03d}-{val_loss:.3f}.hdf5'),
		verbose=1,
save_best_only=True)

	tb = TensorBoard(log_dir=os.path.join('data', 'logs', 'lstm'))

	early_stopper = EarlyStopping(patience=5)

	timestamp = time.time()

	csv_logger = CSVLogger(os.path.join('data', 'logs', 'lstm' + '-' + 'training-' + \
										str(timestamp) + '.log'))
	data = Dataset(
			seq_length=26,
			class_limit=2,
		)
	steps_per_epoch = 4
	X, y = data.get_all_sequences_in_memory('training')
	X_test, y_test = data.get_all_sequences_in_memory('testing')
	rm = ResearchModels(len(data.classes),'lstm',data.seq_length, None)
	print("##################################################")
	X=np.ravel(X)
	X=X.reshape(16,26,-1)
	X_test=np.ravel(X_test)
	X_test=X_test.reshape(3,26,-1)
	#print "X", X[0:10]
	print ("X.shape", X.shape)
	print ("y.shape", y.shape)
	print ("X_test.shape" ,X_test.shape)
	print ("y_test.shape" ,y_test.shape)
	print ("##################################################")
	rm.model.fit(
			X,
			atch_size=batch_size,
			validation_data=(X_test, y_test),
			verbose=1,
			callbacks=[tb, early_stopper, csv_logger],
			epochs=nb_epoch);
	rm.model.fit(
			y,
			atch_size=batch_size,
			validation_data=(X_test, y_test),
			verbose=1,
			callbacks=[tb, early_stopper, csv_logger],
			epochs=nb_epoch);
	predictions = rm.model.predict(X_test)
	loss,accuracy = rm.model.evaluate(X_test, y_test)
	#print 'Loss:',loss*100,'%'
	for j in predictions:
		if j[0]>j[1]:
			print ("Driver is alert with the confidence of",(j[0]*100),"%")
		else:
			print("Driver is drowsy with the confidence of",(j[1]*100),"%")
			print("Sounding the alarm now....");
			duration = 10# second
			freq = 440# Hz
			os.system('play --no-show-progress --null --channels 1 synth %s sine %f' % (duration, freq))
			
def main():
	# model can be one of lstm, lrcn, mlp, conv_3d, c3d
		batch_size = 4
		nb_epoch = 10

		# Chose images or features and image shape based on network.

		train(batch_size=batch_size, nb_epoch=nb_epoch)

		if __name__ == '__main__':
			main()

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/232588.html

標籤:python

上一篇:【Python資料分析與處理 實訓05】--- 探索虛擬姓名資料(資料合并)

下一篇:【Python】實訓5:使用pandas進行資料預處理( lagrange插值、merge合并、標準化)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more