06.26 教程|如何構建自定義人臉識別數據集

選自pyimagesearch

作者:Adrian Rosebrock

機器之心編譯

參與:Geek AI、路

本文介紹了構建自定義人臉識別數據集的三種方法:使用 OpenCV 和 webcam 工具收集人臉圖像數據;以編程的方式下載人臉圖像;手動收集人臉圖像。

在接下來的幾篇博文中,作者將帶領大家訓練一個「計算機視覺+深度學習」的模型來執行人臉識別任務。但是,要想訓練出能夠識別圖像或視頻流中人臉的模型,我們首先得收集人臉圖像的數據集。

如果你使用的是「Labeled Faces in the Wild」(LFW)這樣預先準備好的數據集,那麼你可以不用進行這項困難的工作了。你可以使用我們下一篇博文中的方法創建自己的人臉識別應用。

然而,對於大多數人來說,我們希望識別出的人臉往往不包含在任何現有數據集中,例如:我們自己的、朋友的、家人或者同事的人臉圖像。

為了完成這個任務,我們需要收集我們想要識別的人臉樣本,並且以某種方式量化它們。

這個過程通常被稱為「人臉識別註冊」(facial recognition enrollment)。我們稱之為「註冊」是因為在這個過程中,我們會將用戶註冊、登記為我們的數據集和應用中的一個真人樣本。

本文將介紹註冊過程的第一步:創建自定義人臉識別數據集。

如何創建自定義人臉識別數據集

本教程中,我們將介紹 3 種創建自定義人臉識別數據集的方法。第一種方法使用 OpenCV 和 webcam 工具完成兩個任務:(1)在視頻中檢測出人臉;(2)將人臉圖像或視頻幀的樣本保存到磁盤上。

第二種方法將討論如何以編程的方式下載人臉圖像。

最後,我們將討論如何手動收集人臉圖像,以及這種方法何時是適用的。

讓我們開始構建人臉識別數據集吧!

方法 1:通過 OpenCV 和 webcam 進行人臉註冊

教程|如何構建自定義人臉識別數據集

圖 1:通過使用 OpenCV 和 webcam,我們可以檢測出視頻流中的人臉,並且將樣本存儲到磁盤上。這個過程可用於創建一個本地人臉識別數據集。

這種方法適用於以下情況:

1. 你要創建一個」能現場使用的」人臉識別系統;

2. 你需要擁有接觸特定人的物理途徑,以收集他們的人臉圖像數據。

這樣的系統尤其適用於公司、學校或者其他人們每天親自出現在現場的組織。

為了收集這些人的人臉圖像樣本,我們可能需要將他們置於一個特殊的房間中,房間中事先安裝好了視頻攝影機,用於:(1)檢測視頻流中人臉的 (x, y) 座標;(2)將包含用戶人臉的視頻幀寫入磁盤。我們可能甚至需要好幾天或者幾周的時間執行上述操作,以收集下列幾種情況下的人臉樣本:

  • 不同的光照條件
  • 一天中不同的時間
  • 不同的情緒和情感狀態

通過收集不同情況下的人臉樣本,我們可以創建一個更加多樣化、更具代表性的特定用戶人臉圖像數據集。

接下來,我們使用一個簡單的 Python 腳本構建自定義人臉識別數據集。這個 Python 腳本可以完成以下任務:

1. 連接到我們的 webcam;

2. 檢測人臉;

3. 將包含人臉的視頻幀寫入磁盤。

想要獲取本文中使用的代碼,請滾動到本文的「Downloads」部分。

準備好之後,請打開 build_face_dataset.py 文件,然後我們來一步一步解讀這份代碼:

教程|如何構建自定義人臉識別數據集

在 2-7 行中,我們導入了所需程序包。尤其是我們所需要的 Opencv 和 imutils 包。安裝 Opencv 的方法請參考我提供的這篇安裝指南(https://www.pyimagesearch.com/opencv-tutorials-resources-guides/)。而 imutils 包則可以很容易地通過 pip 工具進行安裝或升級:

$ pip install --upgrade imutils

如果你使用的是 Python 虛擬環境,請不要忘記使用 workon 命令!

環境安裝好之後,我們接下來將討論兩個需要用到的命令行參數:

教程|如何構建自定義人臉識別數據集

命令行參數會在運行時被一個名為 argparse 的程序包(這個程序包會在安裝 Python 環境時被自動安裝)解析。如果你對於 argparse 和命令行參數不太熟悉,我強烈推薦你迅速瀏覽這篇博文(https://www.pyimagesearch.com/2018/03/12/python-argparse-command-line-arguments/)。

我們有兩個需要用到的命令行參數:

  • --cascade:哈爾級聯(Haar cascade)文件在磁盤上的路徑。
  • --output:輸出文件夾的路徑。人臉圖像會被存儲在這個文件夾中,因此我推薦你用人臉主人的名字來命名這個文件夾。例如,如果你收集的是「John Smith」的人臉圖像,你可以將所有的圖片存放在 dataset/john_smith 文件夾中。

下面,我們將加載人臉的哈爾級聯文件並且初始化視頻流:

教程|如何構建自定義人臉識別數據集

在第 18 行中,我們加載了 OpenCV 的哈爾級聯 detector。這個 detector 會在接下來的逐幀循環中完成繁重的任務。

我們在第 24 行初始化並開始我們的視頻流。

注意:如果你使用的是樹莓派,請註釋掉第 24 行,並且取消第 25 行的註釋。

為了讓攝像頭預熱,我們簡單地將程序暫停 2 秒(第 26 行)。

我們還初始化了一個計數器 total,用於表示在磁盤上存儲的人臉圖像數量(第 27 行)。

現在讓我們在視頻流上進行逐幀循環:

教程|如何構建自定義人臉識別數據集

在第 30 行中,我們開始循環(按下「q」鍵則退出循環)。

從這一行起,我們獲取了一個視頻幀 frame,創建了該幀的一個副本,並且改變了圖像的尺寸(第 34-36 行)。

現在,是時候執行人臉檢測了!

我們可以使用 detectMultiScale 方法檢測視頻幀 frame 中的人臉。該函數需要用到下列參數:

  • image:一個灰度圖;
  • scaleFactor:指定在每個尺度上,圖像縮小多少;
  • minNeighbor:為了保證檢測的有效性,該參數指定每一個候選矩形邊界框需要有多少相鄰的檢測點;
  • minSize:可能的最小圖片尺寸。

不幸的是,有時我們需要對這種方法進行調優,以消除誤判或者檢測出一張完整的人臉,但是對於「近距離」拍攝的人臉圖像的檢測來說,這些參數是一個很好的起點。

話雖如此,你是否也在尋找一種更加先進、更加可靠的方法呢?在之前的博文中(https://www.pyimagesearch.com/2018/02/26/face-detection-with-opencv-and-deep-learning/),我用 OpenCV 和深度學習實現了人臉檢測。你可以通過文章中使用了預訓練模型的深度學習方法很容易地更新本文中的腳本。該方法的好處是,不用調參並且訓練十分快。

這種人臉識別方法的結果是一個 rects(矩形邊界框)列表。在第 44、45 行中,我們在 rects 上進行循環,並且在幀上畫出矩形邊框,以方便展示。

最後一步,我們將在循環中進行兩個工作:(1)在屏幕上展示視頻幀;(2)處理按鍵響應。具體代碼如下:

教程|如何構建自定義人臉識別數據集

在第 48 行中,我們在屏幕上展示了視頻幀,接下來在第 49 行中獲取了鍵入值。

根據按下的是「k」還是「q」,我們會:

  • 如果按下「k」鍵,我們將保留視頻幀並將它存儲到磁盤上(第 53-56 行),並且增加表示獲取到的總幀數的計數器 total(第 58 行)。我們需要在想保留的每一幀處按下「k」鍵。我建議保留不同角度、不同的幀區域、戴/不戴眼鏡等不同情況下拍攝的人臉圖像。
  • 如果按下「q」鍵,則退出循環,準備退出腳本(quit)。

如果沒有按下任何鍵,我們就回到循環的開頭,從視頻流中獲取一幀。

最終我們將在終端上打印出最終存儲的圖像數量,並進行清理:

教程|如何構建自定義人臉識別數據集

現在讓我們運行腳本,收集人臉圖像吧!

請確保你已經從本文的「Downloads」部分下載了代碼和哈爾級聯。

在你的終端設備中執行下列命令:

$ python build_face_dataset.py --cascade haarcascade_frontalface_default.xml \\
--output dataset/adrian
[INFO] starting video stream...
[INFO] 6 face images stored
[INFO] cleaning up...

在運行完腳本之後,我們發現有 6 張圖像被存儲到了 dataset 文件夾的 adrian 子文件夾中:

$ ls dataset/adrian
00000.png 00002.png 00004.png
00001.png 00003.png 00005.png

我建議將人臉圖像樣本存在以圖像所屬人的名字命名的子文件夾中。

通過這種方式可以強化你的自定義人臉識別數據集的組織結構。

方法 2:通過編程下載人臉圖像

教程|如何構建自定義人臉識別數據集

圖 2:另一種構建人臉識別數據集的方法(如果此人是公眾人物,或者在網絡上出現過),是通過一個腳本在谷歌上進行圖像搜索,或者使用一個利用了 Bing 圖像搜索 API 的 Python 腳本。

如果你不能在現場拍攝一個人的圖像,或者他們是在網絡上存在感很強的公眾人物(在某種程度上),你可以通過各種平臺上的 API 以編程的方式下載他們的人臉圖像樣本。選擇哪種 API 很大程度上取決於你想要收集的是誰的人臉圖像。

例如,如果一個人一直在 Twitter 或 Instagram 上發帖,你可能想要用其中一種(或者其他的)社交網絡 API 獲取人臉圖像。

另一種選擇是,使用像谷歌或 Bing 這樣的搜索引擎:

  • 使用這篇文章中的方法(https://www.pyimagesearch.com/2017/12/04/how-to-create-a-deep-learning-dataset-using-google-images/),你可以使用谷歌圖像「Google Images」手動+編程地為給定的查詢下載示例圖像。
  • 在我看來,一個更好的選擇可能是,使用 Bing 的圖像搜索 API,它是完全自動化的且不需要手動干預。我在這篇文章中實現了這個全自動化方法(https://www.pyimagesearch.com/2018/04/09/how-to-quickly-build-a-deep-learning-image-dataset/)。

使用後一種方法,我可以從《侏羅紀公園》和《侏羅紀世界》中下載 218 張人臉圖像。

通過 Bing 圖像搜索 API 下載 Owen Grady 的人臉圖像的命令示例如下:

$ mkdir dataset/owen_grady
$ python search_bing_api.py --query "owen grady" --output dataset/owen_grady

現在讓我們來看整個數據集(刪除不包含該人物人臉的圖像後):

$ tree jp_dataset --filelimit 10
jp_dataset
├── alan_grant [22 entries]
├── claire_dearing [53 entries]
├── ellie_sattler [31 entries]
├── ian_malcolm [41 entries]
├── john_hammond [36 entries]
└── owen_grady [35 entries]
6 directories, 0 files

在短短 20 多分鐘內(包括刪除誤判樣本的時間),我就能收集到《侏羅紀公園》/《侏羅紀世界》的自定義人臉數據集:

教程|如何構建自定義人臉識別數據集

圖 3:通過 Python 和 Bing 圖像搜索 API 以編程的方式創建出的人臉識別數據集示例。圖中是《侏羅紀公園》系列電影中的六個人物。

方法 3:手動收集人臉圖像

教程|如何構建自定義人臉識別數據集

圖 4:手動下載人臉圖像是最不可取的選項,但你不該忘記它。當一個人並不經常在網絡上出現,或者圖像沒有標籤時,你可以使用這種方法。

最後一種創建自定義人臉識別數據集的方法也是最不可取的一種,是手動尋找並存儲人臉圖像樣本。

這種方法顯然是最乏味的,且需要耗費最多的人工工作時間——通常我們更喜歡「自動化」的解決方案,但是在某些情況下,你不得不付諸人工。

使用此方法,你需要手動檢查:

  • 搜索引擎的搜索結果(例如,谷歌和 Bing)
  • 社交網絡資料(Facebook、Twitter、Instagram、SnapChat 等)
  • 圖片分享服務(Google Photos、Flickr 等)

然後手動將這些圖像存儲到磁盤上。

在這些場景下,用戶通常具備某種類型的公開資料,但是比以編程的方式用爬蟲爬到的圖像要少得多。

PyImageSearch Gurus(免費)示範課程

教程|如何構建自定義人臉識別數據集

圖 5:在 PyImageSearch Gurus 課程(https://www.pyimagesearch.com/pyimagesearch-gurus/)中,你將學會構建人臉識別安防系統。當一個未經授權的入侵者坐在你的桌前時,它會通過文本消息(包含圖像)提醒你。

總結

本文介紹了三種為人臉識別任務創建自定義人臉數據集的方法。

你具體會選擇哪種方法完全取決於你自己的人臉識別應用。

如果你正在構建一個「現場」的人臉識別系統,例如用於教室、公司或其他組織的人臉識別系統,你可能會讓用戶進入專門用於收集示例人臉圖像的房間,然後在那裡繼續從視頻流中捕獲人臉圖像 (方法 1)。

另一方面,如果你正在構建一個包含公眾人物、名人、運動員等的人臉識別系統,那麼在網上可能有他們足夠多的人臉圖像樣本。在這種情況下,你可以利用現有的 API 以編程方式下載人臉圖像樣本 (方法 2)。

最後,如果你試圖識別的面孔在網上沒有公開的個人資料(或者個人資料非常有限),你可能需要手動收集和管理人臉數據集 (方法 3)。這顯然是最人工、最繁瑣的方法,但在某些情況下,如果你想識別某些面孔,可能需要使用這種方法。


分享到:


相關文章: