活體檢測 使用OpenCV進行 運動檢測

原文鏈接 活體檢測 使用OpenCV進行 運動檢測

在 2019年7月19日 上張貼 由 hotdog發表回覆

活體檢測 使用OpenCV進行 運動檢測


在本教程中,您將學習如何使用OpenCV執行 活體檢測。您將創建一個能夠在面部識別系統中發現假面並執行反面部欺騙的 活體檢測 器。
在過去的一年中,我撰寫了許多人臉識別教程,包括:

但是,我通過電子郵件和麪部識別帖子的評論部分提出的一個常見問題是:
我如何發現真假面孔?
考慮如果一個邪惡的用戶試圖故意繞過你的人臉識別系統會發生什麼。
這樣的用戶可能試圖拿起另一個人的照片。也許他們甚至在他們的智能手機上有一張照片或視頻,他們可以拿起負責進行人臉識別的相機(例如在本文頂部的圖像中)。
在這些情況下,完全有可能正確識別照相機的臉部……但最終會導致未經授權的用戶繞過您的人臉識別系統!
你會如何發現這些“假”與“真實/合法”的面孔?你怎麼能在你的面部識別應用程序中應用反面部欺騙算法?
答案是使用OpenCV 應用 活動檢測 ,這正是我今天要介紹的內容。
要了解如何將OpenCV的活體檢測結合到您自己的人臉識別系統中,請繼續閱讀!
尋找這篇文章的源代碼?
跳到下載部分。
使用OpenCV進行 活動檢測
在本教程的第一部分中,我們將討論實時檢測,包括它是什麼以及爲什麼我們需要它來改進我們的面部識別系統。
從那裏我們將審查我們將用於執行活動檢測的數據集,包括:

  • 如何構建數據集以進行活動檢測
  • 我們的示例真實與假面部圖像

我們還將審查我們的活體探測器項目的項目結構。
爲了創建活體檢測器,我們將訓練一個能夠區分真實面部和假面部的深度神經網絡。
因此,我們需要:

  1. 構建圖像數據集本身。
  2. 實現能夠執行活躍度檢測器的CNN(我們稱之爲“LivenessNet”網絡)。
  3. 訓練活體探測器網絡。
  4. 創建一個Python + OpenCV腳本,能夠採用我們訓練有素的實時檢測器模型並將其應用於實時視頻。

讓我們繼續吧!
什麼是活體檢測,爲什麼需要它?


人臉識別系統正變得比以往任何時候都更加普遍。從iPhone /智能手機上的人臉識別到中國大規模監控的人臉識別,人臉識別系統正在各地得到應用。
然而,面部識別系統很容易被“欺騙”和“非真實”面孔所欺騙。
僅通過將人的照片(無論是在智能手機上打印,等等)保持到面部識別相機,就可以規避面部識別系統。
爲了使人臉識別系統更安全,我們需要能夠檢測到這樣的假/非真實面部 – 活躍度檢測是用於指代此類算法的術語。
有許多活體檢測方法,包括:

  • 紋理分析,包括計算面部區域上的局部二進制模式(LBP)並使用SVM將面部分類爲真實或欺騙。
  • 頻率分析,例如檢查面部的傅里葉域。
  • 可變聚焦分析,例如檢查兩個連續幀之間的像素值的變化。
  • 基於啓發式的算法,包括眼球運動,嘴脣運動眨眼檢測 這些算法試圖跟蹤眼睛運動和眨眼以確保用戶沒有拿起另一個人的照片(因爲照片不會眨眼或移動它的嘴脣)。
  • 光流算法,即檢查從3D對象和2D平面生成的光流的差異和屬性。
  • 3D臉部形狀,類似於Apple的iPhone臉部識別系統所使用的臉部形狀,使臉部識別系統能夠區分真人臉部和其他人的打印輸出/照片/圖像。
  • 上述的組合使得面部識別系統工程師能夠挑選和選擇適合於其特定應用的活體檢測模型。

有關活體檢測算法的完整評論可以在Chakraborty和Das的2014年論文“面部活體檢測概述 ”中找到。。
出於今天教程的目的,我們將活體檢測視爲二元分類問題
給定一個輸入圖像,我們將訓練一個卷積神經網絡,能夠區分真實面部僞造/欺騙面部
但在我們開始訓練我們的活體檢測模型之前,讓我們首先檢查一下我們的數據集。
我們的活動檢測視頻

爲了讓我們的例子簡單明瞭,我們在這篇博客文章中構建的實時檢測器將側重於區分真實面部屏幕上的欺騙面部。
該算法可以很容易地擴展到其他類型的欺騙面,包括打印輸出,高分辨率打印等。
爲了構建活躍度檢測數據集,我:

  1. 拿起我的iPhone並將其置於縱向/自拍模式。
  2. 錄製了一段約25秒的自己在辦公室裏走來走去的視頻
  3. 重播了同樣的25秒視頻,這次是我的iPhone面向我的桌面,我錄製了視頻重播。
  4. 這導致了兩個示例視頻,一個用於“真實”面部,另一個用於“假/欺騙”面部。
  5. 最後,我將面部檢測應用於兩組視頻,以提取兩個類的單個面部ROI。

我在下載”中爲您提供了我的真假視頻文件在帖子部分爲。
您可以將這些視頻用作數據集的起點,但我建議您收集更多數據,以幫助您的實時檢測器更加健壯和準確。
通過測試,我確定模型略微偏向我自己的臉,這是有道理的,因爲這是所有模型都經過訓練。此外,由於我是白人/白人,我不希望這個相同的數據集與其他膚色一起工作。
理想情況下,你將培訓與模型 的面孔的人,並包括面孔 多個民族。 請務必參考下面的 “限制和進一步工作”部分,瞭解有關改善實時檢測模型的其他建議。
在本教程的其餘部分中,您將學習如何獲取我記錄的數據集,並將其轉換爲具有OpenCV和深度學習的實際活動檢測器。
項目結構
繼續使用下載獲取代碼,數據集和活動模型 部分,然後解壓縮存檔。
導航到項目目錄後,您會注意到以下結構

我們的項目中有四個主要目錄:

  • dataset / :我們的數據集目錄包含兩類圖像:
    • 在播放我的臉部視頻時,我用相機瞄準我的屏幕拍攝的假像。
    • 我的真實圖像從我的手機自拍視頻中捕獲。

 

  • face_detector / :由我們的預訓練Caffe面部探測器組成, 用於定位面部ROI。
  • pyimagesearch / :這個模塊包含我們的LivenessNet類。
  • videos / :我提供了兩個用於培訓LivenessNet分類器的輸入視頻。

今天我們將詳細回顧三個Python腳本。在帖子結束時,您將能夠在自己的數據上運行它們並輸入視頻源。按照本教程中的出現順序,這三個腳本是:

  1. gather_examples .py :此腳本從輸入視頻文件中獲取面對ROI,並幫助我們創建深度學習面部活動數據集。
  2. train_liveness .py :如文件名所示,此腳本將訓練我們的LivenessNet分類器。我們將使用Keras和TensorFlow來訓練模型。培訓過程會產生一些文件:
  • le .pickle :我們的班級標籤編碼器。
  • liveness.model :我們的序列化Keras模型,可檢測面部活力。
  • plot .png :訓練歷史圖顯示準確度和損失曲線,因此我們可以評估我們的模型(即過度/不足)。

 

  1. liveness_demo .py :我們的演示腳本將啓動您的網絡攝像頭以抓取幀以實時進行面部活體檢測。

從我們的訓練(視頻)數據集中檢測和提取面部ROI


現在我們已經有機會審查我們的初始數據集和項目結構,讓我們看看我們如何從輸入視頻中提取真實和假面部圖像。
最終目標,如果此腳本將填充兩個目錄:

  1. dataset / fake /:包含假.mp4文件中的面部ROI
  2. dataset / real /:保存來自真實.mov文件的面部ROI 。

鑑於這些幀,我們稍後將在圖像上訓練基於深度學習的活動檢測器。
打開 gather_examples .py

第2-5行導入我們所需的包。除了內置的Python模塊之外,此腳本僅需要OpenCV和NumPy。
從那裏 第8-19行 解析我們的命令行參數

  • – input :輸入視頻文件的路徑。
  • – output :輸出目錄的路徑,其中將存儲每個裁剪的面。
  • – detector :人臉探測器的路徑。我們將使用OpenCV的深度學習人臉檢測器。爲方便起見,此Caffe型號包含在今天的 下載中。
  • – confidence 置信度 :過濾弱臉檢測的最小概率。默認情況下,此值爲50%。
  • – skip :我們不需要檢測和存儲每個圖像,因爲相鄰的幀會相似。相反,我們將在檢測之間跳過 N幀。您可以使用此參數更改默認值16。

讓我們繼續加載面部檢測器並初始化我們的視頻流

第23-26行加載OpenCV的深度學習面部檢測器
從那裏我們在30行打開我們的視頻流 。
我們還初始化了兩個變量,用於讀取的幀數以及循環執行時保存的幀數(第31和32行))。
讓我們繼續創建一個循環來處理幀

我們的 while 循環從第35行開始 。
從那裏我們抓住並驗證一個 框架 (第37-42行)。
此時,由於我們已經讀取了一個 幀 ,我們將增加 讀取 計數器(第48行)。如果我們正在跳過這個特定的框架,我們將繼續進行無需進一步處理(第48和49行))。
讓我們繼續探測面孔

爲了執行面部檢測,我們需要從圖像中創建一個斑點第53和54行)。這個 斑點 有300×300的寬度和高度,以適應我們的Caffe面部探測器。稍後需要縮放邊界框,因此 第52行抓取框架尺寸。
線58和59 通過深度學習面部檢測器執行斑點的 正向 通過 。
我們的腳本假設視頻的每一幀只有一個面第62-65行)。這有助於防止誤報。如果您正在處理包含多個臉部的視頻,我建議您相應地調整邏輯。
因此, 第65行獲得最高概率的面部檢測指數。 第66行使用索引提取檢測的置信度。
讓我們過濾弱檢測並將面部ROI寫入磁盤

第71行確保我們的面部檢測ROI滿足最小閾值以減少誤報。
從那裏我們提取面部ROI邊界 框 座標並面對ROI本身(第74-76行))。
我們爲面部ROI生成路徑+文件名,並將其寫入第79-81行的磁盤。此時,我們可以增加 保存的 面數。
處理完成後,我們將在第86和87行進行清理 。
構建我們的活動檢測圖像數據集

圖4:我們的OpenCV面部活體檢測數據集。我們將使用Keras和OpenCV來訓練和演示實時模型。
現在我們已經實現了 gather_examples .py腳本,讓我們把它付諸實踐。
確保使用下載本教程部分來獲取源代碼和示例輸入視頻。
從那裏,打開一個終端並執行以下命令來提取我們的“假/欺騙”類的面
$ python gather_examples.py --input videos/fake.mp4 --output dataset/fake \ --detector face_detector --skip 1同樣,我們也可以爲“真正的”類做同樣的事
$ python gather_examples.py --input videos/real.mov --output dataset/real \ --detector face_detector --skip 4由於“真實”視頻文件比“假”視頻文件長,我們將使用更長的跳幀值來幫助平衡每個類的輸出面ROI數。
執行腳本後,您應該具有以下圖像計數:

  • 假: 150張圖片
  • 真實: 161張圖片
  • 總計: 311張圖片

實施“LivenessNet”,我們的深度學習活力檢測器

下一步是實施“LivenessNet”,這是我們基於深度學習的實時檢測器。
在覈心, LivenessNet 實際上只是一個簡單的卷積神經網絡。
我們將故意保持這個網絡儘可能, 參數儘可能少,原因兩個:

  1. 減少過度擬合我們的小數據集的可能性。
  2. 確保我們的活動檢測器快速,能夠實時運行(即使在資源受限的設備上,例如Raspberry Pi)。

讓我們現在實現LivenessNet – 打開 livenessnet .py

我們所有的進口都來自Keras(2-10行)。要深入審查每個層和功能,請務必參考 使用Python進行計算機視覺的深度學習
我們的 LivenessNet 類在第12行定義 。它由一個靜態方法 build (第14行)組成。該 構建 方法接受四個參數:

  • width :圖像/體積的寬度。
  • height :圖像的高度。
  • depth :圖像的通道數(在本例中爲3,因爲我們將使用RGB圖像)。
  • classes :類的數量。我們有兩個類:“真實”和“虛假”。

我們的 模型 在第17行初始化 。
我們模型的 inputShape在第18行 定義, 而通道排序在第23-25行確定 
讓我們開始爲我們的CNN添加圖層

我們的CNN展示了VGGNet特有的品質。只有少量學習過濾器,它非常淺。理想情況下,我們不需要深層網絡來區分真實和欺騙的面孔。
第28-36行 指定了一個 CONV => RELU => CONV => RELU => POOL圖層集 ,其中還添加了批量標準化和丟失。
另一個 CONV => RELU => CONV => RELU => POOL 圖層集附加在 第39-46行
最後,我們將添加 FC => RELU 圖層

49-57行由完全連接和ReLU激活層組成,帶有softmax分級頭。
該模型返回到第60行的訓練腳本 。
創建活體檢測器培訓腳本

鑑於我們的真實/欺騙圖像數據集以及LivenessNet的實施,我們現在已準備好訓練網絡。
打開 train_liveness .py

我們的面部活體訓練腳本包含許多進口(第2-19行)。我們現在回顧一下:

  • matplotlib :用於生成訓練圖。我們指定 “Agg” 後端,以便我們可以輕鬆地將我們的繪圖保存到第3行的磁盤上 。
  • LivenessNet :我們在上一節中定義的CNN活躍度。
  • train_test_split :scikit-learn中的一個函數,用於構建用於訓練和測試的數據拆分。
  • classification_report :同樣來自scikit-learn,該工具將生成關於模型性能的簡要統計報告。
  • ImageDataGenerator :用於執行數據擴充,爲我們提供批量隨機突變的圖像。
  • Adam :一個適用於此模型的優化器。(替代方案包括SGD,RMSprop等)。
  • paths :從我的imutils包中,這個模塊將幫助我們收集磁盤上所有圖像文件的路徑。
  • pyplot :用於生成一個很好的訓練圖。
  • numpy :Python的數字處理庫。這也是OpenCV的要求。
  • argparse :用於處理命令行參數
  • pickle :用於將我們的標籤編碼器序列化爲磁盤。
  • cv2 :我們的OpenCV綁定。
  • os :這個模塊可以做很多事情,但我們只是將它用於它的操作系統路徑分隔符。

現在您知道導入的內容,查看腳本的其餘部分應該更直截了當。
此腳本接受四個命令行參數:

  • – dataset :輸入數據集的路徑。在帖子的前面,我們使用 gather_examples .py 腳本創建了數據集 。
  • – model :我們的腳本將生成一個輸出模型文件 – 在這裏你提供它的路徑。
  • – le :還需要提供輸出序列化標籤編碼器文件的路徑。
  • – plot :訓練腳本將生成一個圖。如果要覆蓋默認值 “plot.png” ,則應在命令行中指定此值。

下一個代碼塊將執行許多初始化並構建我們的數據

第35-37行上設置訓練參數,包括初始學習率,批量大小和時期數 。
從那裏,我們的 imagePaths 被抓住了。我們還初始化了兩個列表來保存我們的 數據 和類標籤 (第42-44行)。
第46-55行的循環 構建了我們的 數據 和 標籤 列表。該 數據 由我們的被裝載和大小調整爲圖像的32×32像素。每個圖像都有一個存儲在標籤 列表中的相應標籤 。
所有像素強度都縮放到範圍 [0,1],而列表通過第59行被製作成NumPy數組 。
現在讓我們對標籤進行編碼並對數據進行分區

第63-65行單熱編碼標籤。
我們利用scikit-learn來劃分數據 – 75%用於培訓,25%用於測試(第69和70行)。
接下來,我們將初始化我們的數據擴充對象並編譯+訓練我們的面部活動模型

第73-75行構造了一個數據增強對象,它將生成具有隨機旋轉,縮放,移位,剪切和翻轉的圖像。要閱讀有關數據擴充的更多信息,請閱讀我以前的博文
我們的 LivenessNet 模型是在79-83線上構建和編譯的 。
然後我們開始訓練87-89號 。考慮到我們的淺網絡和小數據集,這個過程相對較快。
訓練模型後,我們可以評估結果並生成訓練圖

預測在測試裝置上進行(第93行)。從那裏 生成classification_report並將其打印到終端(第94和95行)。
該 LivenessNet 模型與標籤上的編碼器一起被序列化到磁盤99-104行。
剩餘的 第107-117行生成訓練歷史圖以供以後檢查。
訓練我們的活力探測器
我們現在準備訓練我們的活體探測器。
確保您已使用教程的下載部分下載源代碼和數據集 – 從中​​執行以下命令
$ python train.py --dataset dataset --model liveness.model --le le.pickle

正如我們的結果所示,我們能夠在驗證集上獲得99%的活躍度檢測精度!
將各個部分組合在一起:使用OpenCV進行實時檢測

圖7:使用OpenCV和深度學習進行面部活躍度檢測。
最後一步是將所有部分組合在一起:

  1. 我們將訪問我們的網絡攝像頭/視頻流
  2. 對每個幀應用面部檢測
  3. 對於檢測到的每個臉部,應用我們的活力檢測器模型

打開 liveness_demo .py

第2-11行導入我們所需的包。值得注意的是,我們將使用

  • VideoStream 訪問我們的相機Feed。
  • img_to_array 使我們的幀將採用兼容的數組格式。
  • load_model 加載我們的序列化 Keras模型。
  • imutils 爲其便利功能。
  • cv2 用於我們的OpenCV綁定。

讓我們通過第14-23行解析命令行參數 

  • – model :我們預先訓練的Keras模型用於活體檢測的路徑。
  • – le :我們的標籤編碼器路徑。
  • – detector 探測器 :OpenCV深度學習人臉探測器的路徑,用於查找人臉ROI。
  • – confidence 置信度 :濾除弱檢測的最小概率閾值。

現在讓我們繼續初始化人臉檢測器,LivenessNet模型+標籤編碼器和我們的視頻流

OpenCV人臉檢測器通過27-30行加載 。
從那裏我們加載我們的序列化,預訓練模型( LivenessNet )和標籤編碼器(第34和35行)。
我們的 VideoStream 對象被實例化,我們的相機允許兩秒鐘預熱(第39和40行)。
此時,是時候開始循環遍歷幀以檢測真實與虛假/欺騙的面部

線43將打開一個無限 循環塊,其中我們開始通過拍攝+調整各個幀(線46和47)。
調整大小後,抓取框架的尺寸,以便稍後執行縮放(第50行)。
使用="https://www.pyimagesearch.com/2017/11/06/deep-learning-opencvs-blobfromimage-works/">OpenCV blobFromImage函數, 我們生成一個 blob (第51和52行),然後通過將其傳遞到面部檢測器網絡(第56和57行)繼續進行推理。
現在我們已準備好迎接有趣的部分 – 使用OpenCV進行實時檢測和深度學習

在 第60行,我們開始循環檢測面部

  • 過濾掉弱檢測(第63-66行))。
  • 提取面部邊界 框 座標並確保它們不會超出框架的尺寸(第69-77行)。
  • 提取面部ROI並以與我們的訓練數據相同的方式對其進行預處理第81-85行)。
  • 使用我們的活動檢測器模型來確定面部是“真實的”還是“假的/欺騙的” (第89-91行)。
  • 第91行是您插入自己的代碼以執行人臉識別的地方, 但僅限於真實圖像。僞代碼類似於if = =“real”:run_face_reconition() 直接在第91行之後 )
  • 最後(對於本演示),我們繪製 標籤 文本和 面部周圍的矩形(第94-98行)。

讓我們顯示我們的結果並清理

在捕獲按鍵的同時,在循環的每次迭代中顯示輸出幀(第101-102行)。每當用戶按下“q”(“退出”)時,我們將跳出循環並釋放指針並關閉窗口(第105-110行)。
將我們的活動檢測器部署到實時視頻
要關注我們的實時檢測演示,請確保您已使用下載”博客文章部分下載源代碼和預先訓練的活動檢測模型。
從那裏,打開一個終端並執行以下命令
$ python liveness_demo.py --model liveness.model --le le.pickle \ --detector face_detector


在這裏你可以看到我們的活體探測器成功地區分了真實和僞造的面孔。
限制,改進和進一步的工作
我們的活體檢測器的主要限制實際上是我們有限的數據集 – 總共只有311個圖像 (161個屬於“真實”類,150個屬於“假”類)。
這項工作的第一個擴展之一就是簡單地收集額外的訓練數據,更具體地說,是不僅僅是我或你自​​己的圖像/幀
請記住,今天使用的示例數據集僅包含一個 人(我自己)的面孔 。我也是白人/白人 – 你應該爲其他種族和膚色收集訓練面孔 。
我們的活體探測器只是通過屏幕上的惡搞攻擊進行訓練- 它 沒有經過打印的圖像或照片的訓練。因此,我的第三個建議是在簡單的屏幕錄製回放之外投入額外的圖像/面部源
最後,我想提一下,活體檢測沒有完美的。
一些最好的活體檢測器包含多種活體檢測方法(請務必參考“什麼是活體檢測以及我們爲什麼需要它?”部分)。
花些時間考慮和評估您自己的項目,指南和要求 – 在某些情況下,您可能需要的只是基本的眨眼檢測啓發式方法。
在其他情況下,您需要將基於深度學習的活動檢測與其他啓發式檢測相結合。
不要急於進行人臉識別和活體檢測 – 花時間和紀律來考慮自己獨特的項目要求。這樣做可確保您獲得 更好,更準確的 結果。
摘要
在本教程中,您學習瞭如何使用OpenCV執行活動檢測。
使用此活體檢測器,您現在可以在您自己的人臉識別系統中發現僞造的假貨並進行反面部欺騙。
爲了創建我們的活動檢測器,我們使用了OpenCV,Deep Learning和Python。
第一步是收集我們的真假數據集。爲完成此任務,我們:

  1. 首先使用我們的智能手機錄製自己的視頻(即“真實”面孔)。
  2. 將我們的智能手機放到我們的筆記本電腦/臺式機上,重播相同的視頻,然後使用我們的網絡攝像頭記錄重播(即“假”面)。
  3. 對兩組視頻應用面部檢測以形成我們的最終活動檢測數據集。

在構建我們的數據集之後,我們實施了“LivenessNet”,一個Keras +深度學習CNN。
該網絡故意淺爲了確保:

  1. 我們減少了過度擬合小數據集的可能性。
  2. 該模型本身能夠實時運行(包括在Raspberry Pi上)。

總的來說,我們的活性檢測器能夠在我們的驗證集上獲得99%的準確度
爲了演示完整的活動檢測管道,我們創建了一個Python + OpenCV腳本,它加載了我們的活動檢測器並將其應用於實時視頻流。
正如我們的演示所示,我們的活力檢測器能夠區分真假面部。
我希望你喜歡今天關於OpenCV活動檢測的帖子。
代碼下載
源代碼下載


原文鏈接 活動檢測 使用OpenCV進行 運動檢測



文章轉自 Adrian Rosebrock ,OpenCV Face Recognition,PyImageSearch,https://www.pyimagesearch.com/OpenCV OCR and text recognition with TesseractLiveness Detection with OpenCV/,2009年7月19日訪問



相關文章

 

張貼在技術博客opencv標籤:opencv深度學習活動檢測運動檢測編輯

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章