天天看點

人臉檢測進階:更快的5點面部标志檢測器人臉檢測進階:更快的5點面部标志檢測器使用 dlib、OpenCV 和 Python 實作面部标志dlib 的 5 點比68 點面部标志檢測器更快嗎?5 點面部标志檢測器的局限性總結

人臉檢測進階:更快的5點面部标志檢測器

今天在這裡的目标是向您介紹新的 dlib 面部标志檢測器,它比原始版本更快(提高 8-10%)、更高效、更小(10 倍)。

在這篇博文的第一部分,我們将讨論 dlib 的新的、更快、更小的 5 點面部标志檢測器,并将其與随庫分發的原始 68 點面部标志檢測器進行比較。

然後我們将使用 Python、dlib 和 OpenCV 實作面部标志檢測,然後運作它并檢視結果。

最後,我們将讨論使用 5 點面部标志檢測器的一些限制,并重點介紹一些您應該使用 5 點版本的 68 點面部标志檢測器的場景。

68 點檢測器定位沿眼睛、眉毛、鼻子、嘴巴和下颌線的區域共68個點,5 點面部标志檢測器将此資訊簡化為:

  • 左眼2分
  • 右眼2分
  • 鼻子1分

5 點面部标志檢測器最合适的用例是面部對齊。

在加速方面,我發現新的 5 點檢測器比原始版本快 8-10%,但這裡真正的勝利是模型大小:為 9.2MB 。

同樣重要的是要注意面部标志檢測器開始時往往非常快(特别是如果它們被正确實作,就像它們在 dlib 中一樣)。

dlib的安裝教程:

https://wanghao.blog.csdn.net/article/details/121470556

人臉檢測器模型:

https://download.csdn.net/download/hhhhhhhhhhwwwwwwwwww/50939290

使用 dlib、OpenCV 和 Python 實作面部标志

打開一個新檔案,将其命名為 fast_facial_landmarks.py ,并插入以下代碼:

# import the necessary packages
from imutils.video import VideoStream
from imutils import face_utils
import argparse
import imutils
import time
import dlib
import cv2           

導入了必要的包,特别是 dlib 和 imutils 中的兩個子產品。

imutils 包已更新以處理 68 點和 5 點面部标志模型。 確定通過以下方式在您的環境中更新它:

pip install --upgrade imutils           

同樣,更新 imutils 将允許您使用 68 點和 5 點面部标志。

解析指令行參數:

# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-p", "--shape-predictor", required=True,
    help="path to facial landmark predictor")
args = vars(ap.parse_args())           

我們有一個指令行參數:--shape-predictor。 此參數允許我們更改将在運作時加載的面部标志預測器的路徑。

然後,讓我們加載形狀預測器并初始化我們的視訊流:

# 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"])
# initialize the video stream and sleep for a bit, allowing the
# camera sensor to warm up
print("[INFO] camera sensor warming up...")
vs = VideoStream(src=1).start()
# vs = VideoStream(usePiCamera=True).start() # Raspberry Pi
time.sleep(2.0)           

初始化 dlib 的預訓練 HOG + 線性 SVM 人臉檢測器并加載 shape_predictor 檔案。

通路相機,我們使用 imutils 中的 VideoStream 類。

您可以選擇(通過注釋/取消注釋第 25 和 26 行)是否使用:

​ 1、内置/USB 網絡攝像頭

​ 2、或者,如果您将在 Raspberry Pi 上使用 PiCamera

從那裡,讓我們周遊幀并做一些工作:

# loop over the frames from the video stream
while True:
    # grab the frame from the threaded video stream, resize it to
    # have a maximum width of 400 pixels, and convert it to
    # grayscale
    frame = vs.read()
    frame = imutils.resize(frame, width=400)
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
 
    # detect faces in the grayscale frame
    rects = detector(gray, 0)
    # check to see if a face was detected, and if so, draw the total
    # number of faces on the frame
    if len(rects) > 0:
        text = "{} face(s) found".format(len(rects))
        cv2.putText(frame, text, (10, 20), cv2.FONT_HERSHEY_SIMPLEX,
            0.5, (0, 0, 255), 2)           

首先,我們從視訊流中讀取一幀,調整其大小,然後轉換為灰階。

然後讓我們使用我們的 HOG + 線性 SVM 檢測器來檢測灰階圖像中的人臉。

從那裡,我們首先確定至少檢測到一張人臉,進而在原始幀上繪制圖像中的人臉總數。

接下來,讓我們循環面部檢測并繪制标記:

# loop over the face detections
    for rect in rects:
        # compute the bounding box of the face and draw it on the
        # frame
        (bX, bY, bW, bH) = face_utils.rect_to_bb(rect)
        cv2.rectangle(frame, (bX, bY), (bX + bW, bY + bH),
            (0, 255, 0), 1)
        # 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)
 
        # loop over the (x, y)-coordinates for the facial landmarks
        # and draw each of them
        for (i, (x, y)) in enumerate(shape):
            cv2.circle(frame, (x, y), 1, (0, 0, 255), -1)
            cv2.putText(frame, str(i + 1), (x - 10, y - 10),
                cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 255), 1)           

循環周遊 rects 。

我們使用 imutils 中的 face_utils 子產品在原始架構上繪制人臉邊界框(您可以在此處閱讀更多資訊)。

然後我們将面部傳遞給預測器以确定面部标志,随後我們将面部标志坐标轉換為 NumPy 數組。

現在是有趣的部分。 為了可視化标記,我們将使用 cv2.circle 繪制小點并對每個坐标進行編号。

周遊标記坐标。 然後我們在原始幀上繪制一個小的實心圓圈以及标記編号。

讓我們完成我們的面部标記腳本:

# 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 fast_facial_landmarks.py --shape-predictor shape_predictor_5_face_landmarks.dat           
人臉檢測進階:更快的5點面部标志檢測器人臉檢測進階:更快的5點面部标志檢測器使用 dlib、OpenCV 和 Python 實作面部标志dlib 的 5 點比68 點面部标志檢測器更快嗎?5 點面部标志檢測器的局限性總結

dlib 的 5 點比68 點面部标志檢測器更快嗎?

在我自己的測試中,我發現 dlib 的 5 點面部标志檢測器比原來的 68 點面部标志檢測器快 8-10%。

8-10% 的加速是顯着的; 然而,這裡更重要的是模型的大小。

原來的68點人臉标記檢測器将近100MB。

5 點面部标志檢測器不到 10MB,隻有 9.2MB——這是一個小 10 倍以上的模型!

當您建構自己的使用面部标志的應用程式時,您現在擁有一個小得多的模型檔案,可以與應用程式的其餘部分一起分發。

5 點面部标志檢測器的局限性

對于面部對齊,可以将 5 點面部标志檢測器視為 68 點檢測器的直接替代品——适用相同的通用算法:

計算 5 點面部标志

分别根據每隻眼睛的兩個界标計算每隻眼睛的中心

利用眼睛之間的中點計算眼睛質心之間的角度

通過應用仿射變換獲得人臉的規範對齊

雖然 68 點面部标志檢測器可能會為我們提供更好的眼睛中心近似值,但在實踐中您會發現 5 點面部标志檢測器也能正常工作。

5 點面部标志檢測器肯定更小(分别為 9.2MB 和 99.7MB),但它不能在所有情況下使用。比如睡意檢測時,我們需要計算眼睛縱橫比 (EAR),它是眼睛界标寬度與眼睛界标高度的比率。

當使用 68 點面部标志檢測器時,我們每隻眼睛有六個點,使我們能夠執行此計算。

然而,使用 5 點面部标志檢測器,我們每隻眼睛隻有兩個點——這不足以計算眼睛縱橫比。

如果您的計劃是建構一個睡意檢測器或任何其他需要面部更多點的應用程式,包括沿以下方向的面部标志:

眼睛

眉毛

鼻子

下颌線

總結

在今天的部落格文章中,我們讨論了 dlib 新的、更快、更緊湊的 5 點面部标志檢測器。

這個 5 點面部标志檢測器可以被認為是最初與 dlib 庫一起分發的 68 點标志檢測器的替代品。

在讨論了兩個面部标志檢測器之間的差異後,我提供了一個應用 5 點版本來檢測我面部的眼睛和鼻子區域的示例腳本。

在我的測試中,我發現 5 點面部标志檢測器比 68 點版本快 8-10%,同時小 10 倍。

完整的代碼:

https://download.csdn.net/download/hhhhhhhhhhwwwwwwwwww/57183149