基於OpenCV+dlib開發一個人臉識別應用

王平發表於2019-09-05

最近在做一個人臉識別的應用,Android系統的攝像頭檢測到人臉並識別出是誰。
這樣一個系統看似簡單,但架構比較複雜,移動裝置本身的計算能力太弱,不能負擔對計算力要求較高的人臉識別,因此,把人臉識別移到伺服器端進行,Android客戶端負責檢測人臉和拍照,把圖片傳到伺服器再進行人臉識別並返回結果。
架構清晰後就開始幹起來了!

開發一個人臉識別小應用

Android Studio開發基於OpenCV的人臉監測

注意,這裡是監測, 而不是檢測,因為要求攝像頭時刻開著,一有人臉跳進來就能馬上檢測到。
Android開發,俺也是做過的,五六年前吧。其實也只能說是小半隻腳沾了點邊兒,同事搭好的框架,我偶爾修改一些程式碼,對整個Android開發一知半解。那個時候開發工具都還是eclispe,Android的版本還是2或3吧。

而今,開發工具已經是Google自己釋出的Android Studio(當然,eclipse還是能用的),編譯工具是一個叫grable的東西。這個grable啊,給人的感覺真是慢啊,我的電腦24G記憶體,3.4GHZ的i7處理器,編譯起來還是很慢啊。

工具都是新工具(其實即使還是eclipse,多年前的一知半解也早已化為雲煙,跟新的又有神馬區別呢?),語言也是新語言——JAVA。用Java也是那時候接觸一點,基本上算是沒有經驗。還好有個OpenCV做Android開發的示例工程可以參考,謝天謝地,再這個基礎上改就省了很多學習的事情。

人臉檢測是在一個叫onCameraFrame()的方法裡面去實現。這個方法就是在攝像頭每一次獲得一幀的時候需要幹些什麼?等等,每一幀?正常電影的視訊好像是24幀每秒,攝像頭也差不多吧。要是每一幀都做檢測處理計算量很大啊,小小Android承受不起啊!於是每隔n幀做一次人臉檢測,即使這樣,出來的程式跑一會兒,手機就開始發燙了。

onCamerFrame()是在主執行緒另一個執行緒進行的,檢測到人臉後還不能直接在主執行緒上進行UI操作,比如顯示檢測到人臉的資訊。執行緒之間用訊息傳遞來完成這個操作。一涉及到UI就很繁瑣,不只是Android這樣。

檢測到人臉就拍個照片(當然是不經過磨皮的)傳給伺服器端進行識別。Android裡面http請求、Json解析的程式碼還是很多的,能找到很多很多。不過對於Java語言的不熟就很費時,比如Vector的使用都要現學現用。

根據人臉識別年齡、性別、表情

這也是一個小需求,但是要真實現起來就很難了。好在大公司有現成的線上API可以呼叫。一番研究以後選了騰訊的優圖。而且它還有Android上寫好的Java庫可用,值得一讚。但是那個例程比較亂。
識別出年齡、性別、表情等資訊就要顯示處理,那就彈個對話方塊吧。又遇到了執行緒和UI的問題。

伺服器端基於dlib的人臉識別

基於dlib自己實現個人臉識別的服務吧,資料庫記錄已經被記住的人臉特徵,來一張新臉時,先檢測人臉和計算人臉特徵,再與資料庫進行對比,如果發現是已經被記住的臉,就返回跟老熟人打個招呼的訊息。
Python用tornado開發個web服務很容易。基本上已經用tornado做了好多web伺服器了,返回json資料,連網頁都不用寫。
dlib用人工神經網路進行人臉識別,計算量還是很大的,純CPU計算一張人臉的特徵要1.35秒左右,後來加了些編譯引數,減小到1.2秒多。這點兒時間,反應到Android客戶端上就是——感覺有點反應遲鈍。以後實施還是上GPU好。

成品-Android應用(可試用)

以上開發已經完成,挑了些引數做了優化,隨便起了個名字——哈哈看臉,請試用:
APP下載:http://ebuinfo.com/apk/app-face.apk
可選安裝:訊飛語音+ , 百度搜尋“訊飛語音+ 下載” 可以進行下載。安裝後可以使得本應用能夠語音播報。功能:

  • 啟動APP後全屏顯示前置攝像頭的拍攝畫面
  • 當有人臉被檢測到時,會向伺服器驗證是否是老熟人(以前被記住過)
  • 如果不是熟人就向騰訊請求判別並顯示年齡、性別、表情等資訊
  • 如果是熟人就顯示”您好,XXX”的文字,並語音問好(如果安裝了訊飛語音+)

最後,記得不要玩這個太久,手機會發熱的。

猿人學banner宣傳圖

我的公眾號:猿人學 Python 上會分享更多心得體會,敬請關注。

***版權申明:若沒有特殊說明,文章皆是猿人學 yuanrenxue.com 原創,沒有猿人學授權,請勿以任何形式轉載。***

相關文章