iT邦幫忙

2021 iThome 鐵人賽

DAY 11
1
AI & Data

[Computer Vision] 電腦視覺下的人臉系列 第 11

[Day11] Face Detection - 使用OpenCV & Dlib:Dlib HOG + Linear SVM

  • 分享至 

  • xImage
  •  

不要被標題一堆名詞嚇到;當你用過它後,你會驚訝它的易用以及,最重要的,無縫接軌辨識人臉關鍵點

本文開始

Dlib套件,一個你可能覺得陌生,但在聽到Facial Landmark或是Face Alignment時,卻幾乎一定會用到的強大套件。

以我自己在進行Computer Vision相關功能或專案時,下面幾個套件一定是先裝好裝滿:

  • OpenCV
  • Dlib
  • imutils (圖片處理常用工具)

再來才會看要做哪一種影像分析,或是訓練模型... (訓練模型的圖片預處理有其他方便的工具,如kerasscikit-learn等)

當你了解如何使用基本工具 (OpenCV & Dlib)來進行人臉分析後,FaceNet、VGGFace、DeepFace等等這些人臉識別模型的使用才會更得心應手。


前面提到過,使用OpenCV & Dlib來做人臉偵測,大概可以分為四種方式:

  1. OpenCV Haar cascades
  2. OpenCV deep neural networks (DNNs)
  3. Dlib HOG + Linear SVM <-- 今天說這個
  4. Dlib max-margin object detector (MMOD)

今天要介紹第三種方式。

Dlib HOG + Linear SVM

習慣上我喜歡稱呼這個方法叫Dlib特徵檢測,其實從名稱其實可以看出一二,

Dlib HOG + Linear SVM與OpenCV Haar cascades其實都是透過檢測(滑動視窗)的特徵來辨識物體與位置

今天介紹的方法其背後原理大概可以分成兩步驟:

  1. 提取特徵:透過方向梯度直方圖(HOG)來取得正面臉部的特徵
  2. 訓練模型:透過支援向量機(SVM)來做線性的類別區分

最終訓練出來的模型就是我們今天要使用的方法。

在辨識準確度上相比,Dlib特徵檢測要比哈爾特徵檢測高,也不太需要調整參數來提高辨識度。

話不多說,Let's code!

  1. Day9的專案下,同樣在face_detection目錄下新增一個Python檔案dlib_hog_svm.py
    dlib_hog_1
  2. 在新增的Python檔案內輸入以下內容 (相關程式碼說明在註解內):
    # 匯入必要套件
    import time
    
    import cv2
    import dlib
    import imutils
    import numpy as np
    from imutils.face_utils import rect_to_bb
    from imutils.video import WebcamVideoStream
    
    # 初始化模型
    detector = dlib.get_frontal_face_detector()
    
    
    # 定義人臉偵測函數方便重複使用
    def detect(img):
        rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        # 偵測人臉,將辨識結果轉為(x, y, w, h)的bounding box
        results = detector(rgb, 0)
        rects = [rect_to_bb(rect) for rect in results]
        return rects
    
    
    def main():
        # 啟動WebCam
        vs = WebcamVideoStream().start()
        time.sleep(2.0)
        start = time.time()
        fps = vs.stream.get(cv2.CAP_PROP_FPS)
        print("Frames per second using cv2.CAP_PROP_FPS : {0}".format(fps))
    
        while True:
            # 取得當前的frame,變更比例為寬300,並且轉成RGB圖片
            frame = vs.read()
            img = frame.copy()
            img = imutils.resize(img, width=300)
    
            # 取得frame的大小(高,寬)
            ratio = frame.shape[1] / img.shape[1]
    
            # 呼叫偵測函數,取得結果
            rects = detect(img)
    
            # loop所有預測結果
            for rect in rects:
                # 計算bounding box(邊界框)與準確率 - 取得(左上X,左上Y,右下X,右下Y)的值 (記得轉換回原始frame的大小)
                box = np.array(rect) * ratio
                (x, y, w, h) = box.astype("int")
    
                # 畫出邊界框
                cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
    
            # 標示FPS
            end = time.time()
            cv2.putText(frame, f"FPS: {str(int(1 / (end - start)))}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7,
                        (0, 0, 255), 2)
            start = end
    
            # 顯示影像
            cv2.imshow("Frame", frame)
    
            # 判斷是否案下"q";跳離迴圈
            key = cv2.waitKey(1) & 0xff
            if key == ord('q'):
                break
    
    
    if __name__ == '__main__':
        main()
    
    
  3. 在terminal輸入python face_detection/dlib_hog_svm.py,跑出來的範例結果會是這樣:
    dlib_hog_2

結論

  1. 我知道有些人看到這邊會覺得不想實作,只想看結論;相信我,即使你是複製貼上程式碼,實際跑看看,學到的東西跟直接看結論是完全不同的
  2. Dlib特徵檢測會對臉部面向鏡頭的角度很敏感 (你可以看出我在範例結果中"刻意"把臉轉一個角度與把口罩稍微往下移 -- 為了能夠辨識到"戴口罩的人臉");其實你從程式碼第12行get_frontal_face_detector函數名稱就可以看出來了,這個功能對正面臉的準確度比較好
  3. Dlib特徵檢測基本上不需要調整參數。唯一可能會調整的是程式碼第19行detector(rgb, 0)中的第二個參數:
    • upsample_num_times:表示在進行偵測之前,要將圖片"放大"幾次;次數越多越能偵測到比較小的人臉,但花費的時間也更長
  4. 很重要所以再說一次,你要用Dlib做人臉關鍵點檢測,今天這個方法是你其中一個不會多走遠路的選擇
  5. 辨識速度基本上對300px的影像可以有30 fps以上,實際在使用上大概跟哈爾特徵檢測的速度差不多

參考程式碼在這

好了,今天就到這邊,

對程式碼有疑問的歡迎留言囉。


上一篇
[Day10] Face Detection - 使用OpenCV & Dlib:OpenCV DNNs
下一篇
[Day12] Face Detection - 使用OpenCV & Dlib:Dlib MMOD
系列文
[Computer Vision] 電腦視覺下的人臉30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
joujg
iT邦新手 5 級 ‧ 2022-01-27 15:08:13

不過我用這個也會有超出的問題xd
但我dlib是19.22.1版的
https://drive.google.com/file/d/1lJX8KfGEvn93ZeAzUzrdNn-UNzvPBw6F/view?usp=sharing
這給您參考看看,範圍正常時是黑框,超過範圍變紅框

感謝分享~

我要留言

立即登入留言