使用OpenCV,Python和dlib進行眨眼檢測

因爲某些原因需要眨眼識別,看到這個第一個想到的就是python,但是沒接觸過這個語言,所以我先看的java的寫法,發現挺少。於是開始下載python開始了下載各種軟件的道路。。。

原網址

雖然開始是在CSDN上花45積分下載的,但是發現這只是國外大佬寫的。在這裏給出國外大佬的原網址,就不給CSDN的了(明明人家免費,還在CSDN上賣45積分(小聲BB))。

https://www.pyimagesearch.com/2017/04/24/eye-blink-detection-opencv-python-dlib/

問題

原網址上相關配置已經很詳細了。在這裏我就寫我自己碰到的坑。。。

主要是這些opencvnumpy,以及dlib庫scipy庫

除了dlib庫其他都是直接按照網上教程直接成功的。

在這就說一下這個安裝吧,找了無數的方法。最後成功了,而且還是個超級簡單的。。。

首先下載dlib-19.17.0-cp37-cp37m-win_amd64.whl我已經把這個文件放在了藍奏雲。

然後直接安裝,在解壓好的文件夾的cmd窗口輸入下面的就可以了。

pip install 文件名.whl

這裏就不配安裝好的圖了。

wink.py的代碼貼出來(原文並沒有中文,中文是我機翻的)

# Command line parameters
# python Wink.py --shape-predictor shape_predictor_68_face_landmarks.dat --video your videoname.mp4
# python Wink.py --shape-predictor shape_predictor_68_face_landmarks.dat

# import the necessary packages
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 winsound


def eye_aspect_ratio(eye):
    # compute the euclidean distances between the two sets of vertical eye landmarks (x, y)-coordinates
    # 計算兩組垂直眼界標(x,y)座標之間的歐幾里得距離
    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
    # 計算水平眼界標(x,y)座標之間的歐幾里得距離
    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


# 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")
args = vars(ap.parse_args())

# 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
# 定義兩個常數,一個常數表示眼睛的縱橫比以指示眨眼,然後定義第二個常數表示眼睛的連續幀數必須低於閾值
EYE_AR_THRESH = 0.25
EYE_AR_CONSEC_FRAMES = 2

# initialize the frame counters and the total number of blinks 初始化幀計數器和閃爍總數
COUNTER = 0
TOTAL = 0

# initialize dlib's face detector (HOG-based) and then create the facial landmark predictor
# 初始化dlib的面部檢測器(基於HOG),然後創建面部界標預測器
print("[INFO] loading facial landmark predictor...")
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(args["shape_predictor"])

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

# start the video stream thread 啓動視頻流線程
print("[INFO] starting video stream thread...")
# vs = FileVideoStream(args["video"]).start()
fileStream = True
vs = VideoStream(src=0).start()

fileStream = False
time.sleep(1.0)

# loop over frames from the video stream 循環播放視頻流中的幀
while True:
    # if this is a file video stream, then we need to check if there any more frames left in the buffer to process
    # 如果這是文件視頻流,那麼我們需要檢查緩衝區中是否還有剩餘的幀要處理
    if fileStream and not vs.more():
        break

    # 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)

    # 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
        # 確定面部區域的面部界標,然後將面部界標(x,y)座標轉換爲NumPy數組
        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

        # 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)

        # 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

        # otherwise, the eye aspect ratio is not below the blink threshold
        # 否則,眼睛縱橫比不低於眨眼閾值
        else:
            # if the eyes were closed for a sufficient number of then increment the total number of blinks
            # 如果閉上眼睛的次數足夠多,則增加眨眼的總數
            if COUNTER >= EYE_AR_CONSEC_FRAMES:
                TOTAL += 1

            # reset the eye frame counter 重置眼框計數器
            COUNTER = 0

        # draw the total number of blinks on the frame along with the computed eye aspect ratio for the frame
        # 繪製幀上眨眼的總數以及計算出的幀的眼睛縱橫比
        cv2.putText(frame, "Blinks: {}".format(TOTAL), (10, 30),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
        cv2.putText(frame, "EAR: {:.2f}".format(ear), (300, 30),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
        cv2.putText(frame, "COUNTER: {}".format(COUNTER), (140, 30),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)

    # show the frame 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()

使用

python Wink.py --shape-predictor shape_predictor_68_face_landmarks.dat --video your videoname.mp4

python Wink.py --shape-predictor shape_predictor_68_face_landmarks.dat

效果圖

這個可以檢測攝像頭也可以檢測視頻裏的,我都試過了可以,下面來個視頻(周董的說好不哭的MV)的效果圖(滑稽圖)。

在這裏插入圖片描述

文章原網址:

使用OpenCV,Python和dlib進行眨眼檢測

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章