什麼是活體檢測,為什麼需要它?
隨著時代的發展,人臉識別系統的應用也正變得比以往任何時候都更加普遍。從智慧型手機上的人臉識別解鎖、到人臉識別打卡、門禁系統等,人臉識別系統正在各行各業得到應用。然而,人臉識別系統很容易被「非真實」的面孔所欺騙。比如將人的照片放在人臉識別相機,就可以騙過人臉識別系統,讓其識別為人臉。為了使人臉識別系統更安全,我們不僅要識別出人臉,還需要能夠檢測其是否為真實面部,這就要用到活體檢測了。
圖1:左邊的是真實臉,右邊是假臉
目前有許多活體檢測方法,包括:
紋理分析(Texture analysis),包括計算面部區域上的局部二進位模式(LBP)並使用SVM將面部分類為真臉或假臉;頻率分析(Frequency analysis),例如檢查面部的傅立葉域;可變聚焦分析(ariable focusing analysis),例如檢查兩個連續幀之間的像素值的變化。基於啟發式的算法(Heuristic-based algorithms),包括眼球運動、嘴唇運動和眨眼檢測;光流算法(Optical Flow algorithms),即檢查從3D對象和2D平面生成的光流的差異和屬性;3D臉部形狀,類似於Apple的iPhone臉部識別系統所使用的臉部形狀,使臉部識別系統能夠區分真人臉部和其他人的列印輸出的照片圖像;面部識別系統工程師可以組合上述方法挑選和選擇適合於其特定應用的活體檢測模型。但本教程將採用圖像處理中常用方法——卷積神經網絡(CNN)來構建一個能夠區分真實面部和假面部的深度神經網絡(稱之為「LivenessNet」網絡),將活體檢測視為二元分類問題。首先檢查一下數據集。
活動檢測視頻
圖2:收集真實與虛假/欺騙面孔的示例
為了讓例子更加簡單明了,本文構建的活體檢測器將側重於區分真實面孔與屏幕上的欺騙面孔。且該算法可以很容易地擴展到其他類型的欺騙面孔,包括列印輸出、高解析度列印等。活體檢測數據集來源:
iPhone縱向/自拍;錄製了一段約25秒在辦公室裡走來走去的視頻;重播了相同的25秒視頻,iPhone重錄視頻;獲得兩個示例視頻,一個用於「真實」面部,另一個用於「假/欺騙」面部。最後,將面部檢測應用於兩組視頻,以提取兩個類的單個面部區域。項目結構
項目中主要有四個目錄:*
dataset /
:數據集目錄,包含兩類圖像:在播放臉部視頻時,手機錄屏得到的假臉;
手機自拍視頻中真臉;face_detector /:由預訓練Caffe面部檢測器組成,用於定位面部區域;pyimagesearch /:模塊包含LivenessNet類函數;video/:提供了兩個用於訓練了LivenessNet分類器的輸入視頻;另外還有三個Python腳本:
gather_examples.py:此腳本從輸入視頻文件中獲取面部區域,並創建深度學習面部數據集;train_liveness.py:此腳本將訓練LivenessNet分類器。訓練會得到以下幾個文件:1.le .pickle:類別標籤編碼器;2.liveness.model:訓練好的Keras模型;3.plot.png:訓練歷史圖顯示準確度和損失曲線;liveness_demo.py:該演示腳本將啟動網絡攝像頭以進行面部實時活體檢測;從訓練數據集中檢測和提取面部區域
圖3:構建活體檢測數據集,檢測視頻中的面部區域;
數據目錄:
1.dataset / fake /:包含假.mp4文件中的面部區域;2.dataset / real /:保存來自真實.mov文件的面部區域;打開
gather_examples.py
文件並插入以下代碼:
首先導入所需的包:第8-19行解析命令行參數:
input:輸入視頻文件的路徑;output:輸出目錄的路徑;detector:人臉檢測器的路徑;confidence:人臉檢測的最小概率。默認值為0.5;skip:檢測時略過的幀數,默認值為16;之後加載面部檢測器並初始化視頻流:
此外還初始化了兩個變量,用於讀取的幀數以及循環執行時保存的幀數。創建一個循環來處理幀:
下面進行面部檢測:
為了執行面部檢測,需要從圖像中創建一個區域,該區域有300×300的寬度和高度,以適應Caffe面部檢測器。此外腳本假設視頻的每一幀中只有一個面部,這有助於防止誤報。獲得最高概率的面部檢測指數,並使用索引提取檢測的置信度,之後將低概率的進行過濾,並將結果寫入磁碟:
提取到面部區域後,就可以得到面部的邊界框坐標。然後為面部區域生成路徑+文件名,並將其寫入磁碟中。
構建活體檢測圖像數據集
圖4:面部活體檢測數據集
打開終端並執行以下命令來提取「假/欺騙」類別的面部圖像:
同理也可以執行以下命令獲得「真實」類別的面部圖像:
注意,這裡要確保數據分布均衡。執行腳本後,統計圖像數量:
假:150張圖片真:161張圖片總計:311張圖片實施「LivenessNet」深度學習活體檢測模型
圖5:LivenessNet的深度學習架構
LivenessNet實際上只是一個簡單的卷積神經網絡,儘量將這個網絡設計的儘可能淺,參數儘可能少,原因有兩個:
減少過擬合可能性;確保活體檢測器能夠實時運行;打開
livenessnet .py
並插入以下代碼:
創建活體檢測器訓練腳本
圖6:訓練LivenessNet
打開
train_liveness .py
文件並插入以下代碼:
此腳本接受四個命令行參數:
dataset:輸入數據集的路徑;model:輸出模型文件保存路徑;le:輸出序列化標籤編碼器文件的路徑;plot:訓練腳本將生成一個圖;下一個代碼塊將執行初始化並構建數據:
之後對標籤進行獨熱編碼並對將數據劃分為訓練數據(75%)和測試數據(25%):
之後對數據進行擴充並對模型進行編譯和訓練:
模型訓練後,可以評估效果並生成仿真曲線圖:
訓練活體檢測器
執行以下命令開始模型訓練:
圖6:使用OpenCV、Keras和深度學習訓練面部活體模型
從上述結果來看,在測試集上獲得99%的檢測精度!
合併起來:使用OpenCV進行活體檢測
圖7:使用OpenCV和深度學習進行面部活體檢測
最後一步是將所有部分組合在一起:
訪問網絡攝像頭/視頻流;對每個幀應用面部檢測;對於檢測到的每個臉部,應用活體檢測器模型;打開`liveness_demo.py並插入以下代碼:
上述代碼導入必要的包,並加載模型。下面初始化人臉檢測器、LivenessNet模型以及視頻流:
之後開始循環遍歷視頻的每一幀以檢測面部是否真實:
使用OpenCV blobFromImage函數生成一個面部數據,然後將其傳遞到面部檢測器網絡繼續進行推理。核心代碼如下:
首先過濾掉弱檢測結果,然後提取面部圖像並對其進行預處理,之後送入到活動檢測器模型來確定面部是「真實的」還是「假的/欺騙的」。最後,在原圖上繪製標籤和添加文本以及矩形框,最後進行展示和清理。
將活體檢測器應用到實時視頻上
打開終端並執行以下命令:
可以看到,活體檢測器成功地區分了真實和偽造的面孔。下面的視頻作為一個更長時間的演示:視頻地址
進一步的工作
本文設計的系統還有一些限制和缺陷,主要限制實際上是數據集有限——總共只有311個圖像。這項工作的第一個擴展之一是簡單地收集額外的訓練數據,比如其它人,其它膚色或種族的人。此外,活體檢測器只是通過屏幕上的惡搞攻擊進行訓練,它並沒有經過列印出來的圖像或照片的訓練。因此,建議添加不同類型的圖像源。最後,我想提一下,活體檢測沒有最好的方法,只有最合適的方法。一些好的活體檢測器包含多種活體檢測方法。
總結
在本教程中,學習了如何使用OpenCV進行活動檢測。使用此活體檢測器就可以在自己的人臉識別系統中發現偽造的假臉並進行反面部欺騙。此外,創建活動檢測器使用了OpenCV、Deep Learning和Python等領域的知識。整個過程如下:
第一步是收集真假數據集。數據來源有:智慧型手機錄製自己的視頻(即「真」面);手機錄播(即「假」面);對兩組視頻應用面部檢測以形成最終數據集。第二步,獲得數據集之後,實現了「LivenessNet」網絡,該網絡設計的比較淺層,這是為了確保:減少了過擬合小數據集的可能性;該模型本身能夠實時運行;總的來說,本文設計的活體檢測器能夠在驗證集上獲得99%的準確度。此外,活動檢測器也能夠應用於實時視頻流。