各位好,這次小弟又要來分享一下一些有趣的東東了~因為一些因緣際會,小弟有了人臉辨識系統的開發機會,後續又因為一些因緣際會停止開發了。根據開源的精神,有些內容小弟就拿來當作這次的知識分享嘍~因為這是個算有點規模的開發案,一次的篇題肯定是不夠的,所以小弟打算分成4個Part來做分享,也希望幫助到遭遇相關開發問題的朋友喔!
- Part.1 實現MVC:Qt Designer與PyQt5的完美接軌
- Part.2 人臉辨識核心:SCRFD + ArcFace + YOLOFace
- Part.3 人員管理系統:PyQt5應用
- Part.4 騷包的花邊功能:語音與音效提示功能
首先,這個人臉辨識程序的核心,可以拆解成三個步驟[1]:SCRFD(檢測出人臉位置與關鍵點),ArcFace(人臉對齊以獲取人臉特徵向量),YOLOFace(識別出屬於哪張人臉)。人臉檢測的演算法非常多,可以參照利用資料[1]裡面的程式碼,對人臉識別的開發上應該會有很大的幫助。
[1] GitHub - 10种轻量级人脸检测算法的比拼
https://github.com/hpc203/10kinds-light-face-detector-align-recognition
SCRFD
人臉識別最大的關鍵,也是目前大多數研究比拚的內容,在於能夠快速而輕量地抓出臉部的ROI區域與關鍵點(最常使用的是抓出5點特徵點)。小弟在研究人臉辨識的時候,看到SCRFD(Sample and Computation Redistribution for Efficient Face Detection)的人臉抓取的速度相當快速,而且他的onnx model檔案也不大,所以當時開發決定使用這套人臉特徵點偵測的方式。
[2] 知乎 - 详细记录insightface的SCRFD人脸检测ncnn实现
https://zhuanlan.zhihu.com/p/372332267
ArcFace
得到臉部的關鍵特徵點後,接下來就是用ArcFace獲取人臉特徵向量,並生成一個已知身分的人臉特徵向量的pkl檔。一個pkl檔可以儲存不同人的人臉特徵向量,例如說100張A先生的臉部照片與100張B小姐的臉部照片,會再經過特徵向量擷取後,一起儲存到pkl檔裡,並用不同的ID來分別這是A先生的特徵向量、還是B小姐的特徵向量。產生pkl檔的過程,我們這邊可以籠統地稱之為"人臉特徵訓練",也就是讓電腦訓練出可以識別誰是誰的能力。
經過測試,一張人臉的各個角度加總訓練200張,識別的效果還不錯,如果繼續增加訓練人臉量,只會徒增訓練時間,雖然只要訓練一次pkl檔,即可進行無數次的人臉識別,但為了訓練時的效率考量,不建議一個人擷取太多張人臉(ex:1000張以上)。另外,因為小弟所設計的程序,不會刪除過於相似的人臉訓練照片,所以可能會累積過多冗餘的相同特徵向量,如果程序需要進一步改良,可以從這邊著手試著改良看看。
[3] 知乎 - 人脸识别合集 | 10 ArcFace解析
https://zhuanlan.zhihu.com/p/76541084
YOLOFace
最後一步,便是透過YOLOFace,將實際抓到的人臉ROI區域的人臉特徵,與pkl裡面的人臉特徵做比對,便可知道目前畫面上的這張臉,與訓練檔內的臉譜是否相符。
ONNX Model
上面提到的ONNX model也是一個關鍵。ONNX可以讓使用者直接在存儲數據的地方使用深度學習模型[4],這個好處使我們可以直接在python裡面匯入ONNX model進行運用。網路上教了很多可以將PyTorch model轉換成ONNX model的方法,不過因為過程繁雜、需要設定大量參數等等,小弟其實在PyTorch轉換成ONNX之後都沒辦法正常使用ONNX檔,所以最保險的方式,是直接使用別人轉好的ONNX model,中間便可省略示例數據點、定義模型的骨架、推理部分等繁瑣的轉換過程。ONNX model在上述的參考資料[1]當中便可下載取得。
[4] Medium - Transform a PyTorch model to onnx
https://medium.com/analytics-vidhya/transform-a-pytorch-model-to-onnx-90e581258997
程序撰寫上,小弟利用了PyQt5的多執行緒功能(QThread)來進行編寫,例如攝影機在實時抓取圖片、實時辨識人臉特徵點、訓練pkl檔的過程、與資料庫比對以識別人臉等等,全部都用多執行緒來寫,執行時會更加順暢(否則會"非常"容易看到UI介面當機)。寫法範例可以參照參考資料[5],一定會對您開發視窗系統有非常大的幫助。
[5] QThread 多執行緒
https://steam.oxxostudio.tw/category/python/pyqt5/qthread.html
基本上,網路上的大神已經把最繁雜的部分都寫完了。小弟也只是把這些功能拼貼在一起,也沒有什麼特別貢獻的地方。小弟能做的,便是把有用的資訊過濾出來,把資訊彙整在一起,以及分享自己的code,讓開發者能夠少走一點冤枉路而已。
沒有留言:
張貼留言