上一篇我們討論如何使用 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)
測試檔案 | HOG | CNN |
---|---|---|
孫藝珍-t1.jpeg | 0.18s | 3.47s |
孫藝珍-t2.jpeg | 0.16s | 3.19s |
孫藝珍-t3.jpeg | 0.19s | 3.93s |
玄彬+孫藝珍.jpeg | 0.41s | 10.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.jpg | 5 | 李 | 0.4014 | 0.4467 | 0.0453 |
68 | 李 | 0.3777 | 0.4614 | 0.0837 | |
lee-t2.jpg | 5 | 李 | 0.3171 | 0.5330 | 0.2159 |
68 | 李 | 0.3033 | 0.5545 | 0.2512 | |
pan-t1.jpg | 5 | 潘 | 0.4501 | 0.3395 | 0.1106 |
68 | 潘 | 0.4679 | 0.2946 | 0.1733 | |
pan-t2.jpg | 5 | 李 | 0.3822 | 0.3957 | 0.0135 |
68 | 李 | 0.3897 | 0.4047 | 0.0150 |
試試看這些方法來調教你的人臉辨識系統吧!如果你也有什麼好方法來調教的話歡迎在下面留言讓我知道。如果覺得我文章內容對你有幫助的話,請在文章後面幫我按 5 個讚!讓我知道大家都喜歡什麼內容哦!
範例原始碼在此下載:github
延伸閱讀:
使用 Face Recognition 套件快速建立自己的人臉辨識系統!
用 MotionEye + Raspberry pi 做一個網路監控系統吧!