亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Python人臉檢測(cè)實(shí)戰(zhàn)之疲勞檢測(cè)

 更新時(shí)間:2021年12月09日 14:59:56   作者:AI浩  
本文主要介紹了實(shí)現(xiàn)疲勞檢測(cè):如果眼睛已經(jīng)閉上了一段時(shí)間,我們會(huì)認(rèn)為他們開始打瞌睡并發(fā)出警報(bào)來(lái)喚醒他們并引起他們的注意。感興趣的朋友可以了解一下

今天我們實(shí)現(xiàn)疲勞檢測(cè)。 如果眼睛已經(jīng)閉上了一段時(shí)間,我們會(huì)認(rèn)為他們開始打瞌睡并發(fā)出警報(bào)來(lái)喚醒他們并引起他們的注意。我們測(cè)試一段視頻來(lái)展示效果。同時(shí)代碼中保留開啟攝像頭的的代碼,取消注釋即可使用。

使用 OpenCV 構(gòu)建犯困檢測(cè)器

要開始我們的實(shí)現(xiàn),打開一個(gè)新文件,將其命名為 detect_drowsiness.py ,并插入以下代碼:

# import the necessary packages
from scipy.spatial import distance as dist
from imutils.video import VideoStream
from imutils import face_utils
from threading import Thread
import numpy as np
import playsound
import argparse
import imutils
import time
import dlib
import cv2

導(dǎo)入們所需的 Python 包。

我們還需要 imutils 包,我的一系列計(jì)算機(jī)視覺和圖像處理功能,以便更輕松地使用 OpenCV。

如果您的系統(tǒng)上還沒有安裝 imutils,您可以通過(guò)以下方式安裝/升級(jí) imutils:

pip install --upgrade imutils

還將導(dǎo)入 Thread 類,以便我們可以在與主線程不同的線程中播放我們的警報(bào),以確保我們的腳本不會(huì)在警報(bào)響起時(shí)暫停執(zhí)行。

為了真正播放我們的 WAV/MP3 鬧鐘,我們需要 playsound 庫(kù),這是一個(gè)純 Python 的跨平臺(tái)實(shí)現(xiàn),用于播放簡(jiǎn)單的聲音。

playsound 庫(kù)可以通過(guò) pip 方便地安裝:

pip install playsound

但是,如果您使用的是 macOS(就像我為這個(gè)項(xiàng)目所做的那樣),您還需要安裝 pyobjc,否則當(dāng)您實(shí)際嘗試播放聲音時(shí),您將收到與 AppKit 相關(guān)的錯(cuò)誤:

pip install pyobjc

接下來(lái),我們需要定義 sound_alarm 函數(shù),該函數(shù)播放音頻文件:

def sound_alarm(path):
	# play an alarm sound
	playsound.playsound(path)

定義 eye_aspect_ratio 函數(shù),該函數(shù)用于計(jì)算垂直眼睛界標(biāo)之間的距離與水平眼睛界標(biāo)之間的距離之比:

def eye_aspect_ratio(eye):
	# compute the euclidean distances between the two sets of
	# vertical eye landmarks (x, y)-coordinates
	A = dist.euclidean(eye[1], eye[5])
	B = dist.euclidean(eye[2], eye[4])
	# compute the euclidean distance between the horizontal
	# eye landmark (x, y)-coordinates
	C = dist.euclidean(eye[0], eye[3])
	# compute the eye aspect ratio
	ear = (A + B) / (2.0 * C)
	# return the eye aspect ratio
	return ear

由于OpenCV不能直接繪制中文,我們還需定義繪制中文的方法:

def cv2ImgAddText(img, text, left, top, textColor=(0, 255, 0), textSize=20):
    if (isinstance(img, np.ndarray)):  # 判斷是否OpenCV圖片類型
        img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    # 創(chuàng)建一個(gè)可以在給定圖像上繪圖的對(duì)象
    draw = ImageDraw.Draw(img)
    # 字體的格式
    fontStyle = ImageFont.truetype(
        "font/simsun.ttc", textSize, encoding="utf-8")
    # 繪制文本
    draw.text((left, top), text, textColor, font=fontStyle,stroke_width=2)
    # 轉(zhuǎn)換回OpenCV格式
    return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)

接下來(lái),定義命令行參數(shù):

# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-p", "--shape-predictor", required=True,
	help="path to facial landmark predictor")
ap.add_argument("-v", "--video", type=str, default="",
                help="path to input video file")
ap.add_argument("-a", "--alarm", type=str, default="",
	help="path alarm .WAV file")
ap.add_argument("-w", "--webcam", type=int, default=0,
	help="index of webcam on system")
args = vars(ap.parse_args())

犯困檢測(cè)器需要一個(gè)命令行參數(shù),后跟兩個(gè)可選參數(shù),每個(gè)參數(shù)的詳細(xì)信息如下:

–shape-predictor :這是 dlib 的預(yù)訓(xùn)練面部標(biāo)志檢測(cè)器的路徑。 您可以使用本博文底部的“下載”部分將檢測(cè)器和本教程的源代碼一起下載。

–video:視頻文件。本文用視頻文件測(cè)試。

–alarm :您可以在此處選擇指定要用作警報(bào)的輸入音頻文件的路徑。

–webcam :此整數(shù)控制內(nèi)置網(wǎng)絡(luò)攝像頭/USB 攝像頭的索引。

定義了命令行參數(shù),我們還需要定義幾個(gè)重要的變量:

# define two constants, one for the eye aspect ratio to indicate
# blink and then a second constant for the number of consecutive
# frames the eye must be below the threshold for to set off the
# alarm
EYE_AR_THRESH = 0.3
EYE_AR_CONSEC_FRAMES = 48
# initialize the frame counter as well as a boolean used to
# indicate if the alarm is going off
COUNTER = 0
ALARM_ON = False

定義了 EYE_AR_THRESH。如果眼睛縱橫比低于此閾值,我們將開始計(jì)算人閉上眼睛的幀數(shù)。

如果該人閉上眼睛的幀數(shù)超過(guò) EYE_AR_CONSEC_FRAMES,我們將發(fā)出警報(bào)。

在實(shí)驗(yàn)中,我發(fā)現(xiàn) 0.3 的 EYE_AR_THRESH 在各種情況下都能很好地工作(盡管您可能需要為自己的應(yīng)用程序自己調(diào)整它)。

我還將 EYE_AR_CONSEC_FRAMES 設(shè)置為 48 ,這意味著如果一個(gè)人連續(xù)閉眼 48 幀,我們將播放警報(bào)聲。

您可以通過(guò)降低 EYE_AR_CONSEC_FRAMES 來(lái)使疲勞檢測(cè)器更敏感——同樣,您可以通過(guò)增加它來(lái)降低疲勞檢測(cè)器的敏感度。

定義了 COUNTER,即眼睛縱橫比低于 EYE_AR_THRESH 的連續(xù)幀的總數(shù)。

如果 COUNTER 超過(guò) EYE_AR_CONSEC_FRAMES ,那么我們將更新布爾值 ALARM_ON。

dlib 庫(kù)附帶了一個(gè)基于定向梯度的人臉檢測(cè)器的直方圖以及一個(gè)人臉地標(biāo)預(yù)測(cè)器——我們?cè)谝韵麓a塊中實(shí)例化了這兩個(gè):

# initialize dlib's face detector (HOG-based) and then create
# the facial landmark predictor
print("[INFO] loading facial landmark predictor...")
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(args["shape_predictor"])

dlib 產(chǎn)生的面部標(biāo)志是一個(gè)可索引的列表,見下圖:

因此,要從一組面部標(biāo)志中提取眼睛區(qū)域,我們只需要知道正確的數(shù)組切片索引:

# 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"]

使用這些索引,我們將能夠通過(guò)數(shù)組切片輕松提取眼睛區(qū)域。

我們現(xiàn)在準(zhǔn)備啟動(dòng)我們的睡意檢測(cè)器的核心:

# start the video stream thread
print("[INFO] starting video stream thread...")
vs = VideoStream(src=args["webcam"]).start()
time.sleep(1.0)
# loop over frames from the video stream
while True:
	# grab the frame from the threaded video file stream, resize
	# it, and convert it to grayscale
	# channels)
	frame = vs.read()
	frame = imutils.resize(frame, width=450)
	gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
	# detect faces in the grayscale frame
	rects = detector(gray, 0)

實(shí)例化 VideoStream。

暫停一秒鐘,讓相機(jī)傳感器預(yù)熱。

開始遍歷視頻流中的幀。

讀取下一幀,然后我們通過(guò)將其大小調(diào)整為 450 像素的寬度并將其轉(zhuǎn)換為灰度進(jìn)行預(yù)處理。

應(yīng)用 dlib 的人臉檢測(cè)器來(lái)查找和定位圖像中的人臉。

下一步是應(yīng)用面部標(biāo)志檢測(cè)來(lái)定位面部的每個(gè)重要區(qū)域:

	# loop over the face detections
	for rect in rects:
		# determine the facial landmarks for the face region, then
		# convert the facial landmark (x, y)-coordinates to a NumPy
		# array
		shape = predictor(gray, rect)
		shape = face_utils.shape_to_np(shape)
		# extract the left and right eye coordinates, then use the
		# coordinates to compute the eye aspect ratio for both eyes
		leftEye = shape[lStart:lEnd]
		rightEye = shape[rStart:rEnd]
		leftEAR = eye_aspect_ratio(leftEye)
		rightEAR = eye_aspect_ratio(rightEye)
		# average the eye aspect ratio together for both eyes
		ear = (leftEAR + rightEAR) / 2.0

循環(huán)遍歷檢測(cè)到的每個(gè)人臉——在我們的實(shí)現(xiàn)中(特別與司機(jī)睡意有關(guān)),我們假設(shè)只有一張臉——司機(jī)——但我把這個(gè) for 循環(huán)留在這里以防萬(wàn)一你想應(yīng)用多張臉視頻的技術(shù)。

對(duì)于每個(gè)檢測(cè)到的人臉,我們應(yīng)用 dlib 的面部標(biāo)志檢測(cè)器并將結(jié)果轉(zhuǎn)換為 NumPy 數(shù)組。

使用 NumPy 數(shù)組切片,我們可以分別提取左眼和右眼的 (x, y) 坐標(biāo)。

給定雙眼的 (x, y) 坐標(biāo),我們?nèi)缓笥?jì)算它們的眼睛縱橫比。

Soukupová 和 ?ech 建議將兩個(gè)眼睛的縱橫比平均在一起以獲得更好的估計(jì)。

然后,我們可以使用下面的 cv2.drawContours 函數(shù)可視化框架上的每個(gè)眼睛區(qū)域——這在我們嘗試調(diào)試腳本并希望確保正確檢測(cè)和定位眼睛時(shí)通常很有幫助:

		# compute the convex hull for the left and right eye, then
		# visualize each of the eyes
		leftEyeHull = cv2.convexHull(leftEye)
		rightEyeHull = cv2.convexHull(rightEye)
		cv2.drawContours(frame, [leftEyeHull], -1, (0, 255, 0), 1)
		cv2.drawContours(frame, [rightEyeHull], -1, (0, 255, 0), 1)

最后,我們現(xiàn)在準(zhǔn)備檢查視頻流中的人是否出現(xiàn)犯困的癥狀:

		# check to see if the eye aspect ratio is below the blink
		# threshold, and if so, increment the blink frame counter
		if ear < EYE_AR_THRESH:
			COUNTER += 1
			# if the eyes were closed for a sufficient number of
			# then sound the alarm
			if COUNTER >= EYE_AR_CONSEC_FRAMES:
				# if the alarm is not on, turn it on
				if not ALARM_ON:
					ALARM_ON = True
					# check to see if an alarm file was supplied,
					# and if so, start a thread to have the alarm
					# sound played in the background
					if args["alarm"] != "":
						t = Thread(target=sound_alarm,
							args=(args["alarm"],))
						t.deamon = True
						t.start()
				# draw an alarm on the frame
                frame=cv2ImgAddText(frame,"醒醒,別睡!",10,30,(255, 0, 0),30)
		# otherwise, the eye aspect ratio is not below the blink
		# threshold, so reset the counter and alarm
		else:
			COUNTER = 0
			ALARM_ON = False

檢查眼睛縱橫比是否低于“眨眼/閉合”眼睛閾值 EYE_AR_THRESH 。

如果是,我們?cè)黾?COUNTER ,即該人閉上眼睛的連續(xù)幀總數(shù)。

如果 COUNTER 超過(guò) EYE_AR_CONSEC_FRAMES,那么我們假設(shè)此人開始打瞌睡。

進(jìn)行了另一次檢查,以查看警報(bào)是否已打開——如果沒有,我們將其打開。

處理播放警報(bào)聲音,前提是在執(zhí)行腳本時(shí)提供了 --alarm 路徑。我們特別注意創(chuàng)建一個(gè)單獨(dú)的線程來(lái)負(fù)責(zé)調(diào)用 sound_alarm 以確保我們的主程序在聲音播放完畢之前不會(huì)被阻塞。

繪制文本 DROWSINESS ALERT!在我們的框架上——同樣,這通常有助于調(diào)試,尤其是當(dāng)您不使用 playsound 庫(kù)時(shí)。

最后,第 136-138 行處理眼睛縱橫比大于 EYE_AR_THRESH 的情況,表示眼睛是睜開的。如果眼睛是睜開的,我們重置計(jì)數(shù)器并確保警報(bào)關(guān)閉。

我們的睡意檢測(cè)器中的最后一個(gè)代碼塊處理將輸出幀顯示到我們的屏幕上:

		# draw the computed eye aspect ratio on the frame to help
		# with debugging and setting the correct eye aspect ratio
		# thresholds and frame counters
		cv2.putText(frame, "EAR: {:.2f}".format(ear), (300, 30),
			cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
 
	# show the frame
	cv2.imshow("Frame", frame)
	key = cv2.waitKey(1) & 0xFF
 
	# if the `q` key was pressed, break from the loop
	if key == ord("q"):
		break
# do a bit of cleanup
cv2.destroyAllWindows()
vs.stop()

到這里編碼完成!??!

測(cè)試疲勞檢測(cè)器

運(yùn)行指令:

python detect_drowsiness.py --shape-predictor shape_predictor_68_face_landmarks.dat --video 12.mp4  --alarm alarm.mp3

運(yùn)行結(jié)果:

檢測(cè)到打瞌睡就會(huì)發(fā)出提示,并將提醒打印在視頻上面?

以上就是Python人臉檢測(cè)實(shí)戰(zhàn)之疲勞檢測(cè)的詳細(xì)內(nèi)容,更多關(guān)于Python 人臉疲勞檢測(cè)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論