前言

在上一篇文章中,我們利用 Gil Levi 跟 Tal Hassner 所發表的 CNN 網路來判斷性別時得到不錯的效果,同時我們也提到此網路亦可用於年紀的判斷。如果說性別的判斷已是一件不容易的事情,那年紀的判斷絕對是一件更加困難的任務。扣除一些”先老起來放”的情況,大多數人 (尤其是女性) 都會想辦法讓自己看起來更為年輕。甚至我們也很難得知他人的真實年紀,使得我們不容易評估自己 (或人工智慧) 的推論是否正確。儘管如此,我們還是看看如何利用 Python 與 OpenCV 來判斷年紀吧。

與判斷性別時的流程相似,利用人工智慧來判斷年紀通常會分成三個主要的步驟:

  1. 使用臉部辨識 (face detection) 的人工智慧網路找出影像 (圖片或影格) 中的臉孔。
  2. “切下”這些辨識出的臉孔並轉換成合適的格式,以方便使用於年紀辨識的人工智慧網路。
  3. 使用年紀辨識 (age 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 神經運算棒)。

程式執行後我們就可以依序看到各個圖片的判斷結果,如下圖就是其中一幅圖片的結果畫面。依據程式判斷的結果,其年紀為 38~43 歲之間,機率則為 0.3829:

利用 Gil Levi and Tal Hassner 模型判斷年紀

利用 Gil Levi and Tal Hassner 模型判斷年紀

範例程式說明

  1. 此程式與前一篇文章中進行性別辨識的程式幾乎完全一樣,除了輸出的結果由性別變成年紀 (第 19 行)。
  2. 首先我們一樣先載入程式所需的套件 (第 4-6 行)。載入的 OpenCV (第 6 行) 套件不需要支援 OpenVINO,僅需一般版本即可。
  3. 接著程式利用 argparse 套件讀入所需參數 (第 9~14 行):
    • prototxt: 人工智慧網路的定義
    • model: 訓練過後的人工智慧網路模型
    • path: 存放推論用圖片的目錄
    • target: 是否使用 NCS/NCS2。當指定為 vpu 時,表示使用 NCS/NCS2 進行推論,使用時須搭配支援 OpenVINO 的 OpenCV。
  4. 第 17 行定義模型訓練時的平均值。此數值由計算 https://github.com/GilLevi/AgeGenderDeepLearning/raw/master/models/mean.binaryproto 的內容所得。
  5. 第 19 行定義模型所能識別的年紀,從小到大共分為 8 個年紀區間。等等,對人工智慧稍有了解的朋友應該知道年紀其實是連續的數值,所以年紀預測理應屬於回歸分析 (Regression) 的應用,而不是這裡所使用的分類 (Classification)。不過在這個模型中,為了簡化年紀推論的複雜度,將年紀劃分為幾個固定的區間,也讓問題由迴歸分析變成了分類。這是此模型用於年紀推論時比較特殊的部分。
  6. 第 21 行載入網路定義與訓練結果。
  7. 第 23~26 行根據 target 參數的內容決定是否啟用 NCS/NCS2 或單純使用 CPU 進行推論。
  8. 第 30 行定義函式 detect_age_by_caffe,也就是此範例程式的重頭戲。
  9. 因為  OpenCV 的 CNN 模組無法直接對圖片原始資訊進行處理,所以一樣透過 blobFromImage (第 32 行) 將圖片陣列轉為合適的格式。這裡的 (227, 227) 是指 CNN 網路的 Spatial Dimension,並帶入我們之前計算出的訓練資料平均值 (MODEL_MEAN_VALUES)。對 blobFromImage 有興趣深入了解的朋友,可參考 pyimagesearch.com 上的這篇文章
  10. 第 35 行開始進行預測。
  11. age_detections[0] 依序包含圖像中臉孔在各年紀區間的機率,利用 age_detections[0].argmax() 則可以取出機率較大的索引,並透過 AGES_FOR_CAFFE[age_detections[0].argmax()] 轉換成年紀區間的文字 (第 37 行)。
  12. 第 39~40 行將年紀與機率標示在圖片中。
  13. 第 42 行回傳標示過的圖片。
  14. 第 46 行讀取參數 path 目錄下的所有檔案,並逐一加以處理。
  15. 第 47 行取得檔案名稱。
  16. 第 48 行載入圖片。
  17. 第 49 行呼叫年紀辨識的函式 detect_age_by_caffe。
  18. 第 50 行用來顯示標示過的圖片。
  19. 第 51 行等待使用者按下鍵盤後才繼續執行程式。

推論結果

在此我們針對之前性別判斷的頭像圖片進行年紀推論,其結果整理如下:

利用 Gil Levi and Tal Hassner 模型判斷年紀結果

利用 Gil Levi and Tal Hassner 模型判斷年紀結果

如我在文章一開始中所述,除非我們使用熟識的人當作圖像來源,否則我們很難知道判斷的結果是否準確。不過以我個人的看法,判斷結果似乎並不是很正確。不過大家也別太失望,畢竟我們的新武器 OpenVINO 也內建了性別與年紀的辨識網路。在下一篇文章中,我們就來看看 OpenVINO 的辨識網路是不是會有更好的表現。

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