前言

一連幾篇文章都在討論如何利用 OpenCV 來進行性別與年紀的判斷,也使用了兩種不同的方式 (Haar Cascade 網路與 OpenVINO 內建網路) 來標示出圖片中的臉孔。不過之前都是針對靜態的圖片,而這次我們則將目標放在動態的影片以及攝影畫面上。在這篇文章中,我將介紹如何在樹莓派下利用 OpenCV 即時針對影片內容進行臉孔偵測,並做出性別與年紀的推論。在性別與年紀推論方面,我們一樣使用 OpenVINO 內建的辨識網路。至於臉孔偵測的部分,我們改用第三種作法,那就是 OpenCV 內建的 Caffe 網路。這個範例最好使用 Intel 神經運算棒 NCS/NCS2 來提升推論的速度,以達到即時的效果。

影像與圖片

雖然影片有很多種格式及壓縮方式,但是基本上為了播放的緣故,最後都是以一個畫面接著一個畫面的方式加以輸出。也就是說其實我們可以把影片看成是一堆連續的圖片,直接應用我們之前處理靜態圖片的方式來進行性別與年紀的辨識。這樣做雖然無法充分利用影像連續的好處,甚至會出現奇怪的判斷 (例如同一張臉孔忽男忽女),不過因為處理起來相當簡單,所以在一般情況下仍是相當不錯的選擇。

除了事先錄製好的影片,經由攝影機所擷取的即時畫面也可以應用一樣的處理方式。唯一不同的是,當程式處理速度不夠時,影片的處理時間會變長,但是攝影機的畫面就會變成跳格而錯失很多來不及處理的畫面。換句話說,如果我們希望即時處理攝影機抓取的畫面,就必須盡量提升程式的效能。對樹莓派來說,這樣的即時影像處理實在是蠻吃力的,而利用 Intel 神經運算棒 NCS/NCS2 來加速自然就是一個很合理的選擇囉。

執行範例程式

在這個 Python 範例程式中,我們僅使用到 OpenCV 這個額外的套件,而且必須是支援 OpenVINO 的特殊版本。

如果你還沒有安裝過 OpenVINO 與 OpenCV,雖然並非絕對必要,但是仍強烈建議在虛擬環境下安裝 OpenCV 與執行範例程式,而樹莓派下的安裝方法可參考之前的文章。在這裡,我沿用之前已經安裝過的樹莓派 Python 虛擬環境來執行此範例程式。不過這個程式不限於樹莓派的環境,包含 Windows 與 macOS 在內的作業系統,只要有安裝支援 OpenVINO 的 OpenCV 即可。而且程式還提供了是否使用 NCS/NCS2 的參數,因此即使手邊沒有 NCS/NCS2 也沒關係。不過如果使用樹莓派卻未搭配 NCS/NCS2,處理速度確實不是很理想,在此先提出善意的提醒。 好了,讓我們開始動手進行吧。

  1. 進入虛擬環境
  2. 建立所需目錄
  3. 啟用 OpenVINO 環境。
  4. 下載臉孔辨識的 Caffe 模型

  5. 下載訓練過的 IR 模型與網路定義 (For 樹莓派)


    下載訓練過的 IR 模型與網路定義 (For Windows 與 macOS)

  6. 下載範例程式
  7. 下載包含人物的影片。
  8. 利用下列指令執行範例程式讀取攝影機畫面 (使用 NCS/NCS2 神經運算棒)。

    或者利用下列指令執行範例程式讀取攝影機畫面 (無 NCS/NCS2 神經運算棒)。

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

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

程式執行後我們就可以持續看到程式對影片中畫面進行臉孔偵測以及性別/年紀的辨識,如下圖所示。依據程式的判斷結果,此為二十多歲的女性臉孔:

判斷影片中人物性別與年紀

判斷影片中人物性別與年紀

範例程式說明

  1. 首先我們一樣先載入程式所需的套件 (第 3-6 行),當中載入的 OpenCV (第 6 行) 套件需要支援 OpenVINO。
  2. 接著程式利用 argparse 套件讀入所需參數 (第 9~12 行)。我們將模型的相關檔案名稱都直接設定成變數,以減少參數的使用。
    • video: 推論用的影片檔案名稱,未指定則改從攝影機抓取即時畫面。
    • target: 是否使用 NCS/NCS2。當指定為 vpu 時,表示使用 NCS/NCS2 進行推論。
  3. 第 16~17 行定義 OpenVINO 內建的年紀與性別辨識網路的檔案名稱。
  4. 第 19~20 行定義 OpenCV 內建的臉孔偵測網路的檔案名稱。
  5. 第 22 行定義模型的性別結果輸出。這個模型的性別推論輸出為女生機率在前、男生機率在後。而年紀的推論必須乘上 100 才是網路實際推論的年紀。
  6. 第 26 行載入年紀與性別辨識網路,並指定為 age_gender_net。
  7. 第 26 行載入臉孔偵測的 Caffe 網路,並指定為 opencv_face_net。
  8. 第 29~34 行根據 target 參數的內容決定是否啟用 NCS/NCS2 或單純使用 CPU 進行推論。
  9. 第 38 行定義偵測臉孔的函式 get_faces_from_opencv,也就是此範例程式的重頭戲之一。此段程式與使用 OpenVINO 內建之臉孔偵測程式類似,主要差別在於網路的 dimension 為 (300, 300),而訓練資料平均值則為 (104.0, 177.0, 123.0)。
  10. 第 49 行判斷偵測到區域為臉孔的可靠度是否超過 50%,是的話才當作加入臉孔清單 (faces)。
  11. 第 50~53 行分別算出臉孔區域的左上 (x_min, y_min) 與右下 (x_max, y_max) 角落座標。
  12. 第 57 行傳回所有找到的臉孔區域。
  13. 第 61 行定義推論年紀與性別的函式 detect,是此範例程式的另一個重頭戲。
  14. 第 63 行針對所有偵測出的臉孔進行處理。
  15. 第 65 行使用綠色框線標示出辨識出的臉孔。
  16. 第 67 行則切下辨識出的臉孔。
  17. 因為  OpenCV 的 CNN 模組無法直接對圖片原始資訊進行處理,所以一樣透過 blobFromImage (第 69 行) 將圖片陣列轉為合適的格式,而此網路的 Spatial Dimension 則為 (62, 62)。隨後則將轉換過的資料輸入辨識網路 (第 70 行)。
  18. 第 72 行開始進行預測。之前我們一直使用 forward() 來取得推論結果,但是在這裡卻必須改用 forwardAndRetrieve()。原因在於性別與年紀為兩組不同的推論輸出,所以必須透過 forwardAndRetrieve 並指定輸出的名字,才能夠同時得到兩組的輸出結果。而 prob 與 age_conv3 分別為性別與年紀的輸出名稱,可以在原始文件中找到。如果我們依舊使用 forward() 來取得結果,將只會得到性別的推論。
  19. 第 74 行利用類似之前的方式取得代表性別的文字。
  20. 第 76 行計算推論的年紀。前面提到,網路輸出乘上 100 即為推測出的年紀。
  21. 第 80~84 行根據性別指定不同的文字顏色,並將性別與年紀標示在圖片中。
  22. 第 86 行回傳標示過的圖片。
  23. 第 90~95 行根據是否傳入 video 參數決定由 USB 攝影機或影片讀取畫面進行處理。如果你使用的是樹莓派的攝影機模組,請將 src=0 改成 usePiCamera=True。
  24. 第 98 行開始不斷讀取畫面。
  25. 影片與攝影機畫面的讀取方式有些不同,攝影機的畫面必須額外處理 (第 100 行)。
  26. 當影片結束或攝影機有問題而導致抓不到畫面時就中斷迴圈 (第 102~103 行)。
  27. 第 105 行呼叫函示找出畫面中的臉孔。
  28. 第 107 呼叫函示針對找到的臉孔臉孔進行年紀與性別的推論,並加以標示。
  29. 第 109 顯示標示後的畫面。
  30. 當使用者按下 q 鍵時提前中斷迴圈 (第 111~113 行)。
  31. 第 116~120 行在程式結束前釋放相關資源。

利用搭配 Intel 神經運算棒 NCS/NCS2 的樹莓派,我們完成了即時辨識性別與年紀的程式。快把身邊的朋友找來,看看電腦到底有多聰明,能夠正確猜到多少人的性別與年紀吧。

Facebook 留言
Print Friendly, PDF & Email
Summary
利用樹莓派與 Intel 神經運算棒 NCS/NCS2 進行性別與年紀辨識
Article Name
利用樹莓派與 Intel 神經運算棒 NCS/NCS2 進行性別與年紀辨識
Description
在這篇文章中,我們將利用樹莓派以及 Intel 神經運算棒 NCS/NCS2 來開發可以即時偵測人臉並進行性別與年紀的 Python 程式。
Author
Publisher Name
Everlearn Studio
Publisher Logo