前言

在前兩篇文章裡,我們在樹莓派中建立了支援 OpenVINO 的 OpenCV 環境執行了幾個簡單的範例程式。接下來我將介紹如何利用 OpenVINO 來判斷性別與年紀。不過在那之前,我們先來看看在不利用 OpenVINO 的情況下,只使用 OpenCV 要如何達成性別的判斷,讓我們對利用人工智慧來判斷性別有一個基本的了解。

人工智慧與性別判斷

首先,既使對我們人類而言,正確判斷別人 (甚至是自己的?) 的性別一直都是看似簡單,但又隨時有可能誤判的事情。前一陣子我的女兒剪了一個超短的髮型,就不只一次被不認識的人誤認為是男生。我們除了根據長相來判斷一個人的性別,同時更會利用其他的輔助條件,如髮型、妝扮 、穿著、體型、聲音、甚至是體態等。嚴格來說,這些輔助條件雖然可以幫助我們判斷他人的性別,卻往往也是誤判的主要原因。男扮女裝或女扮男裝,不正是利用這類以偏概全的錯誤推論才有可能順利完成目的嗎?

目前我們看到人工智慧判斷性別的方式,是以臉孔為主,因此不會受到這些輔助條件的干擾。或許看起來不是那麼”聰明”,但是其實反而是有弊有利的。

一般而言,利用人工智慧來判斷性別通常會分成三個主要的步驟:

  1. 使用臉部辨識 (face detection) 的人工智慧網路找出影像 (圖片或影格) 中的臉孔。
  2. “切下”這些辨識出的臉孔並轉換成合適的格式,以方便使用於性別辨識的人工智慧網路。
  3. 使用性別辨識 (gender detection) 人工智慧網路針對這些臉孔一一分辨其性別。

這兩種辨識過程 (臉孔與性別) 擁有各自的人工智慧網路,因此可以嘗試使用不同的組合以達到更好的成效。甚至我們可以利用人工作業的方式取出影像中的臉孔 (真正的人工智慧) 並直接丟給性別辨識的網路。或是利用影像處理的方式來找出影像中的臉孔,而不需要依賴人工智慧。總而言之,這兩個辨識過程可各自獨立運作,沒有絕對必要的組合方式。不過不管使用甚麼樣的組合,步驟 2 都是很重要的一步。每一個人工智慧網路都有它適用的範圍與輸入格式,主要跟當初用於訓練的資料有關。所以我們在利用其進行推論時,也必須符合當初的訓練情境才能得到最佳的結果。

Gil Levi and Tal Hassner 的 CNN 性別辨識網路

在這次的範例中,我將利用由 Gil Levi 跟 Tal Hassner 兩位所發表的 CNN 辨識網路來進行性別的判斷。Gil Levi 跟 Tal Hassner  另外還提供已經訓練過的 Caffe 模型與範例程式,方便我們下載並直接用於推論。根據模型的定義檔,我們知道這個網路內部使用大小為 227×227 的彩色圖片資訊。為了簡化程式與說明,我在這裡先跳過臉部辨識的部分,直接從網路上下載類似大小的臉孔圖片進行判斷。此外,作者雖然提供了使用 caffe 套件的範例程式,但是因為在許多環境下 caffe 套件的安裝都有相當的難度,所以我們改用 OpenCV 來載入訓練過的 Caffe 模型,避免安裝 caffe 套件的複雜步驟。

執行範例程式

在這個 Python 範例程式中,我們僅使用到 OpenCV 這個額外的套件。而只要是 OpenCV 3.3 以上的版本,就可以載入 Caffe 網路,甚至不需要使用支援 OpenVINO 的特殊版本。當然,如果你安裝的是支援 OpenVINO 的特殊版 OpenCV 也是可以直接正常執行本範例程式,而不用改為一般的版本。

如果你還沒有安裝過 OpenCV,雖然並非絕對必要,但是仍強烈建議在虛擬環境下安裝 OpenCV 與執行範例程式。樹莓派下安裝 Python 虛擬環境與 OpenCV 的方法,可參考之前的文章。在這裡,我沿用之前已經安裝過的樹莓派 Python 虛擬環境來執行此範例程式

  1. 進入虛擬環境
  2. 建立所需目錄
  3. 啟用 OpenVINO 環境。再次強調 OpenVINO 並非此範例程式必要之環境,如果你安裝的是一般版的 OpenCV,可跳過此一步驟。
  4. 下載訓練過的 Caffe 模型與網路定義

  5. 下載範例程式
  6. 建立圖片目錄
  7. 下載或自行製作臉孔圖片至 images 目錄下,圖片大小在 250×250 左右。
  8. 利用下列指令執行範例程式 (使用 NCS/NCS2 神經運算棒)。

    或者利用下列指令執行範例程式 (無 NCS/NCS2 神經運算棒)。

程式執行後我們就可以依序看到各個圖片的判斷結果,如下圖就是當程式判斷出圖片中的臉孔為女性時的結果畫面:

利用 Gil Levi and Tal Hassner 模型判斷性別 (女性)

利用 Gil Levi and Tal Hassner 模型判斷性別 (女性)

範例程式說明

  1. 首先我們一樣先載入程式所需的套件 (第 4-6 行)。載入的 OpenCV (第 6 行) 套件不需要支援 OpenVINO,僅需一般版本即可。
  2. 接著程式利用 argparse 套件讀入所需參數 (第 9~14 行):
    • prototxt: 人工智慧網路的定義
    • model: 訓練過後的人工智慧網路模型
    • path: 存放推論用圖片的目錄
    • target: 是否使用 NCS/NCS2。當指定為 vpu 時,表示使用 NCS/NCS2 進行推論,使用時須搭配支援 OpenVINO 的 OpenCV。
  3. 第 17 行定義模型訓練時的平均值。此數值由計算 https://github.com/GilLevi/AgeGenderDeepLearning/raw/master/models/mean.binaryproto 的內容所得。
  4. 第 19 行定義模型所能識別的性別 (Male 或 Female),此模型的輸出順序為男生 (Male) 機率在前,女生 (Female) 機率在後。
  5. 第 21 行載入網路定義與訓練結果。
  6. 第 23~26 行根據 target 參數的內容決定是否啟用 NCS/NCS2 或單純使用 CPU 進行推論。
  7. 第 30 行定義函式 detect_gender_by_caffe,也就是此範例程式的重頭戲。
  8. 因為  OpenCV 的 CNN 模組無法直接對圖片原始資訊進行處理,所以一樣透過 blobFromImage (第 32 行) 將圖片陣列轉為合適的格式。這裡的 (227, 227) 是指 CNN 網路的 Spatial Dimension,並帶入我們之前計算出的訓練資料平均值 (MODEL_MEAN_VALUES)。對 blobFromImage 有興趣深入了解的朋友,可參考 pyimagesearch.com 上的這篇文章
  9. 第 35 行開始進行預測。
  10. gender_detections[0] 依序包含圖像為男生、女生的機率,利用 gender_detections[0].argmax() 則可以取出機率較大的索引,並透過 GENDERS_FOR_CAFFE[gender_detections[0].argmax()] 轉換成性別的文字 (第 37 行)。
  11. 第 39~45 行根據性別指定不同的文字顏色,並將性別與機率標示在圖片中。
  12. 第 47 行回傳標示過的圖片。
  13. 第 51 行讀取參數 path 目錄下的所有檔案,並逐一加以處理。
  14. 第 52 行取得檔案名稱。
  15. 第 53 行載入圖片。
  16. 第 54 行呼叫性別辨識的函式 detect_gender_by_caffe。
  17. 第 55 行用來顯示標示過的圖片。
  18. 第 56 行等待使用者按下鍵盤後才繼續執行程式。

推論結果

我分別找了 10 張男性與女性的頭像,推論後的結果整理如下圖:

利用 Gil Levi and Tal Hassner 模型判斷性別結果

利用 Gil Levi and Tal Hassner 模型判斷性別結果

從結果來看,男性與女性各自誤判了一張 (紅色框線標示的頭像),算是不錯的成效,也應可滿足一般專案的需求。

Gil Levi 跟 Tal Hassner 兩位所發表的 CNN 網路除了可以用來辨識性別,其實也可以用來辨識年紀。在下一篇文章中,我們就來看看要如何利用 Python 進行年紀的判斷吧。

Facebook 留言
Print Friendly, PDF & Email
Summary
如何利用 OpenCV 判斷性別
Article Name
如何利用 OpenCV 判斷性別
Description
在本篇文章中,我們將介紹如何在樹莓派中使用 OpenCV 來進行影像中人物的性別判斷。
Author
Publisher Name
Everlearn Studio
Publisher Logo