如何優化 Face Recognition 套件的人臉辨識?

上一篇我們討論如何使用 Face Recognition 快速做一個人臉辨識系統,但使用預設參數的情況下可能無法完全符合實際需求,這邊分享一些參數調教的方法,讓大家的辨識系統可以更完美!

如何儲存 Face Encoding 加速載入?

以先前的做法,每次要辨識人臉前,我們都必須把已知人臉的圖片載入後做 encoding,如果程式跑在如 Raspberry pi 等效能較差的終端設備是相當浪費資源的!其實我們可以直接把已知人臉的 encoding 存起來,需要時再讀入使用。 python 內建的 pickle 模組就可以達成這個需求!

我們引入 pickle,把上一篇我們得到的特徵向量資料直接送入 dump,就能將其存入根目錄下的 face.dat 檔。

import pickle

with open('faces.dat', 'wb') as f:
    pickle.dump(known_face_list, f)

下次需要使用時,直接透過 pickle.load() 就能還原!比 json 還方便啊!

with open('faces.dat', 'rb') as f:
    known_face_list = pickle.load(f)

發現有時會誤判人臉?改用 CNN 模型

Face Recognition 預設辨識人臉位置的模型是 HOG (Histograms of Oriented Gradients),原理是透過梯度資訊反應影象目標的邊緣資訊,並透過區域性梯度的大小將影象區域性的外觀和形狀特徵化。相對於 CNN 模型,實測發現 HOG 不太能抓到較小的人臉,或是因光影關係而誤判。此時可以考慮使用 CNN 來做偵測。

CNN 的缺點是需要較大的運算量,純 CPU 計算會比 HOG 慢相當多,建議在有 CUDA 的平台上使用(Face Recognition 支援 CUDA 加速)。

# 辨識臉部位址時,給定 model = 'cnn' 即可
cur_face_locs = face_recognition.face_locations(img, model='cnn')

簡單用以下 code 測試一下在 CPU 跑的速度差異

import time

for fn in test_fn_list:
    img = cv2.imread(fn)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    
    _t = time.time()
    
    face_recognition.face_locations(img) # use HOG model to detect face locations
    
    _t1 = time.time()
    
    face_recognition.face_locations(img, model='cnn') # use CNN model to detect face locations
    
    print(f'HOG: {round(_t1 - _t, 2)} secs, CNN: {round(time.time() - _t1, 2)} secs') 

結果如下 (Macbook 2020 / i5 2Ghz)

測試檔案HOGCNN
孫藝珍-t1.jpeg0.18s3.47s
孫藝珍-t2.jpeg0.16s3.19s
孫藝珍-t3.jpeg0.19s3.93s
玄彬+孫藝珍.jpeg0.41s10.14s

準確度不夠?增加特徵點數量

如果發現誤判未知人臉的機率太高,可以增加 encoding 時使用的特徵點數量。

Face Recognition 預設使用 small(5 個特徵點),可以改用 large(68 個特徵點)測試看看。

# 取得臉部特徵向量時,給定 model = 'large' 即可
cur_face_encodes = face_recognition.face_encodings(img, cur_face_locs, model='large')

驗證一下是否有差,我們來讓電腦辨識 李帝勳 和 潘瑋柏 看看!

辨識圖片如下(照片取自李帝勳 or 潘瑋柏 facebook or 官網):

已知人臉圖片組:

左:lee.jpg,右:pan.jpg

未知人臉測試圖片組:

左:lee-t1.jpg, 右:lee-t2.jpg

左:pan-t1.jpg,右:pan-t2.jpg

結果如下表,pan-t1.jpg 雖然拉高了特徵值數量,演算法還是判斷錯誤,敗給長相相似。不過如果從「區分」人臉的角度來看,拉高特徵值數量時與正確已知人臉距離變近,同時距離差上升,所以還是有增加辨識能力。

測試檔案特徵值數量辨識結果與李帝勳距離與潘瑋柏距離距離差
lee-t1.jpg50.40140.44670.0453
680.37770.46140.0837
lee-t2.jpg50.31710.53300.2159
680.30330.55450.2512
pan-t1.jpg50.45010.33950.1106
680.46790.29460.1733
pan-t2.jpg50.38220.39570.0135
680.38970.40470.0150

試試看這些方法來調教你的人臉辨識系統吧!如果你也有什麼好方法來調教的話歡迎在下面留言讓我知道。如果覺得我文章內容對你有幫助的話,請在文章後面幫我按 5 個讚!讓我知道大家都喜歡什麼內容哦!

範例原始碼在此下載:github

延伸閱讀:
使用 Face Recognition 套件快速建立自己的人臉辨識系統!
用 MotionEye + Raspberry pi 做一個網路監控系統吧!

Written by J
雖然大學唸的是生物,但持著興趣與熱情自學,畢業後轉戰硬體工程師,與宅宅工程師們一起過著沒日沒夜的生活,做著台灣最薄的 intel 筆電,要與 macbook air 比拼。 離開後,憑著一股傻勁與朋友創業,再度轉戰軟體工程師,一手扛起前後端、雙平台 app 開發,過程中雖跌跌撞撞,卻也累計不少經驗。 可惜不是那 1% 的成功人士,於是加入其他成功人士的新創公司,專職開發後端。沒想到卻在採前人坑的過程中,拓寬了眼界,得到了深層的領悟。