當前位置:
首頁 > 科技 > 照片解鎖手機不能忍?教你用OpenCV做活體檢測

照片解鎖手機不能忍?教你用OpenCV做活體檢測

圓栗子 編譯整理

量子位 出品 | 公眾號 QbitAI

來自蝦米媽咪

小朋友用媽媽的一寸照片通過了人臉識別,打擊了小度音箱的家長監督機制。

活體檢測沒做好。

公交車身廣告上的董明珠頭像,被寧波交警系統拍了照,判定成「違法闖紅燈」。

活體檢測沒做好。

所以,活體檢測要怎麼做?

名叫Adrian Rosebrock的程序猿,寫了份事無巨細的教程,從構建數據集開始,一步步教大家用AI分辨真人和照片,精細到每行代碼的用途。

川川是假的,光頭是真的

這個識別方法,用到了OpenCVKeras,打開攝像頭就可以實時檢測

重要的是,有源碼提供,受到了推特用戶的踴躍比心。

活體檢測,可以檢測些什麼?

AI可以用哪些技巧,來區分真人和照片?

一是紋理分析(Texture Analysis) 。皮膚的紋理特徵是重要的依據,給2D照片拍照,比起給3D真人拍照,會損失一些紋理。

二是頻率分析(Frequency Analysis) 。照片臉部的頻率組成,也不像真人那樣豐富。

三是可變聚焦分析(Variable focusing Analysis) 。連拍兩張照片,聚焦在不同位置,查看像素值 (Pixel Value) 的變化。

四是啟發式演算法(Heuristic-Based Algorithms) 。眼動、唇動、眨眼這些動作,照片是不會有的。

五是光流演算法(Optical Flow Algorithms) 。在相鄰兩幀之間,檢測物體運動的方向和幅度,查出2D和3D物體之間的差別。

……

不過這裡,就把活體檢測看成一個粗暴的二分類問題,這些複雜的分析先拋到一邊。

自製數據集

程序猿把問題又簡化了一下:這裡說的「假臉」,只是「屏幕里的人臉」而已。

現在,可以開始造數據集了。

他用手機的前攝像頭拍了一段25秒的視頻;又舉著手機、對著電腦攝像頭,把視頻播了一遍。

這樣,一段真人視頻,和一段「假臉」視頻,就準備好了。

程序猿拍下的這兩條視頻,都提供下載。不過,他還是建議大家多收集一些數據,不同的人臉,甚至不同的人種,幫助演算法茁壯成長。

下一步,要用OpenCV的人臉檢測演算法處理兩段視頻,把有用的區域 (ROI) ,就是人臉部分框出來。

這步用了80多行代碼,每一行在做些什麼,教程里都寫清了。

最後,按照真假兩個類別,把框好的臉部提取出來,就有了數據集。

溫馨提示,需要平衡一下真圖和假圖的數量。比如,程序猿發現真實視頻比假視頻長,就用更大的間隔來提取。於是,他收穫了真圖161張,假圖150張。

這數據集還是顯得有些貧乏,所以後面需要擴增:旋轉、翻轉之類的操作,可以增加圖片數量。

活體檢測模型

數據集做好了,就要餵給做活體檢測的神經網路。

程序猿給網路起名LivenessNet,大體長這樣:

他說,這其實只是一個簡單的CNN。而且,已經努力讓網路保持在最淺參數最少的狀態。

這樣做有兩個原因:一是為避免模型在小數據集上發生過擬合,二是為保證模型快到可以實時推理,就算在樹莓派上也能運行。


搭個網路

現在,就來實現一下這個網路。打開livenessnet.py,再寫這一段代碼:

然後,一層一層加上去:

程序猿說,這個網路有點像VGGNet,很淺,過濾器 (Filter) 很少。只是判斷真假,不用深度網路。

最後,再加一個FC層RELU層的組合。

CNN搭好了,該訓練了。

訓練腳本長這樣

大致的訓練過程,就像這張圖:

打開train_liveness.py,寫下這段代碼:

1# set the matplotlib backend so figures can be saved in the background

2importmatplotlib

3matplotlib.use("Agg")

4

5# import the necessary packages

6frompyimagesearch.livenessnetimportLivenessNet

7fromsklearn.preprocessingimportLabelEncoder

8fromsklearn.model_selectionimporttrain_test_split

9fromsklearn.metricsimportclassification_report

10fromkeras.preprocessing.imageimportImageDataGenerator

11fromkeras.optimizersimportAdam

12fromkeras.utilsimportnp_utils

13fromimutilsimportpaths

14importmatplotlib.pyplotasplt

15importnumpyasnp

16importargparse

17importpickle

18importcv2

19importos

20

21# construct the argument parser and parse the arguments

22ap = argparse.ArgumentParser()

23ap.add_argument("-d","--dataset", required=True,

24help="path to input dataset")

25ap.add_argument("-m","--model", type=str, required=True,

26help="path to trained model")

27ap.add_argument("-l","--le", type=str, required=True,

28help="path to label encoder")

29ap.add_argument("-p","--plot", type=str, default="plot.png",

30help="path to output loss/accuracy plot")

31args = vars(ap.parse_args())

導入,不停地導入

裡面包含了許多的導入

有matplotlib,是可視化工具;

有LivenessNet,就是剛才搭好的CNN;

有train_test_split,這是scikit-learn里的函數,把數據集拆成訓練集和測試集;

有classification_report,也是scikit-learn裡面的工具,用來生成簡短統計報告的;

有ImageDataGenerator,做數據擴增用的;

有Adam,適合這個任務的優化器,當然也可以用SGD、RMSprop等等代替;

有paths,這個模塊是用來收集圖片路徑的;

有pyplot,也是美麗的可視化工具;

有numpy,是Python數學庫,也是OpenCV必需品;

有argparse,用來處理命令行參數;

有pickle,可以把標籤編碼器序列化到盤上;

有cv2,這是一組OpenCV Binding;

還有os,這個模塊用處很多,但這裡只用到了它的操作系統路徑分隔符而已。

梳理好這些,再看餘下的代碼,就會清晰很多了。

後面,是一系列的初始化,以及訓練前的各種準備活動。此處略去,詳見教程原文。


訓練正式啟動

準備就緒,運行這段命令,就可以訓練了:


成果斐然

訓練完結,LivenessNet在驗證集上拿到了99%的準確度。

當然,驗證集只是熱身,後面還要打開攝像頭,讓AI去看更多沒見過的人,和沒見過的「假人」。

(這一部分代碼,也有詳盡的解讀,參見教程原文。)

就像開頭展示的那樣,AI能清楚地判斷,它眼前的川川不是真人,而程序猿是真人。

那麼,你也可以訓練一隻這樣的AI了。

不過,不用局限於簡單的二分類,可以用上前面講到的那些複雜的分析方法,比如頻率分析,比如光流法,大有可為。

教程原文傳送門:

https://www.pyimagesearch.com/2019/03/11/liveness-detection-with-opencv/

源碼下載入口,和無微不至的代碼解析,都在裡面了。

訂閱AI內參,獲取AI行業資訊

購買AI書籍

誠摯招聘

量子位正在招募編輯/記者,工作地點在北京中關村。期待有才氣、有熱情的同學加入我們!相關細節,請在量子位公眾號(QbitAI)對話界面,回復「招聘」兩個字。

喜歡就點「好看」吧 !


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 量子位 的精彩文章:

吳恩達有套路:試點項目、內外PR、取信CEO……AI轉型,如何得人心?
圍棋AI ELF OpenGo全面開源,田淵棟揭秘訓練過程

TAG:量子位 |