用OpenCV和深度學習進行年齡識別

用OpenCV和深度學習進行年齡識別

在本教程中,您將學習如何使用OpenCV,深度學習和Python執行年齡的自動識別/預測。


學完本教程後,您將能夠以相當高的精確度去自動預測靜態圖像文件和實時視頻中的人物年齡。


要了解如何使用OpenCV和深度學習進行年齡識別,請繼續閱讀!


用OpenCV和深度學習進行年齡識別


在本教程的第一部分中,您將學習年齡識別,這包括從圖片或視頻中自動預測人的年齡需要的步驟(以及為什麼應該將年齡識別當做分類問題而不是迴歸問題)。


下面,我們將介紹這個基於深度學習的年齡識別模型,然後學習如何使用這兩種模型:

1.靜態圖像中的年齡識別

2.實時視頻中的年齡識別


然後,我們將分析我們所做的年齡預測工作的結果。


什麼是年齡識別?


用OpenCV和深度學習進行年齡識別

圖1:在本教程中,我們使用OpenCV和預先訓練的深度學習模型來預測給定人臉的年齡。

(圖片來源:
https://www.researchgate.net/publication/336955775_Age_Estimation_in_Make-up_Cosmetics_Using_Color_and_Depth_Images)。


年齡識別是僅用人臉的照片去自動識別其年齡的過程


通常,您會看到年齡識別可分為兩個階段進行實現:

1.階段1:檢測輸入圖像/視頻中的人臉

2.階段2:提取人的面部(感興趣區域,ROI),並通過年齡檢測器的算法去預測人物的年齡


對於階段1,能夠為圖片中的人臉生成邊框的人臉檢測器都是可用的,這些檢測器包括但不限於Haar cascades,HOG+線性SVM,單杆檢測器(SSD)等。


使用哪種人臉檢測器取決於您的項目:

·Haar cascades速度很快,並且能夠在嵌入式設備上實時運行,存在的問題是它們的準確度較低並且極易出現假陽性檢測。

·HOG+線性SVM模型比Haar cascades更精確,但速度較慢。它們對遮擋(即部分面部可見)或視角變化(即面部的不同視圖)的容錯性也較低。

·基於深度學習的人臉檢測器功能最為強大,它提供了最高的準確度,但比Haar cascades和HOG+線性SVM需要更多的計算資源。


在為您的應用選擇人臉檢測器時,請花點時間考慮您的項目需求——速度或準確性,哪個對您更加重要?我還建議對每個面部檢測器進行一些試驗,以便讓這些結果來指導您做決定。


一旦您的面部檢測器在圖像/視頻中生成了人臉的邊界框座標,您就可以進入第2階段——識別人的年齡。


確定了臉部的邊界框座標(x,y)後,您首先提取面部ROI,而忽略圖像(幀)的其餘部分。這樣做可以使年齡檢測器僅將注意力放在人臉上,而不是圖像中其他不相關的“噪點”。


然後將面部ROI傳遞給模型,從而得到實際的年齡預測。


年齡檢測器的算法有很多,但是最受歡迎的是基於深度學習的年齡檢測器——在本教程中,我們將使用這種基於深度學習的年齡檢測器。


我們基於深度學習的年齡檢測器模型


用OpenCV和深度學習進行年齡識別

圖2:用深度學習進行年齡識別是一個活躍的研究領域。在本教程中,我們使用由Levi和Hassner在其2015年論文中構建和訓練的模型(圖像來源
https://talhassner.github.io/home/projects/cnn_agegender/CVPR2015_CNN_AgeGenderEstimation.pdf)。


我們在這裡使用的深度學習年齡檢測器模型是Levi和Hassner在其2015年發表的《使用卷積神經網絡進行年齡和性別分類》(
https://talhassner.github.io/home/publication/2015_CVPR)中構建和訓練的。


在這篇論文裡,作者提出了一個類似AlexNet的簡單體系,該體系總共學習了8個年齡段:

1 0-2

2 4-6

3 8-12

4 15-20

5 25-32

6 38-43

7 48-53

8 60-100


您可能會注意到這些年齡段是不連續的——這是有意而為的,因為用於訓練模型的Adience數據集(


https://talhassner.github.io/home/projects/Adience/Adience-data.html#agegender)定義了年齡段(我們將在下一節中介紹為什麼這樣做)。


在這篇文章中,我們將使用預先訓練的年齡檢測器模型。但是如果您有興趣學習如何從頭開始訓練它,請務必閱讀《用Python進行計算機視覺深度學習》(
https://www.pyimagesearch.com/deep-learning-computer-vision-python-book/),在那裡我將向您展示如何訓練。


我們為什麼不將年齡預測看做迴歸問題?


用OpenCV和深度學習進行年齡識別

圖3:用深度學習進行年齡預測可以被歸類為迴歸或分類問題。


您會在上面注意到,我們將年齡離散化為“不同的區間”,從而將年齡預測作為分類問題——為什麼不將它看做迴歸問題(我們在房價預測教程中所使用的方法:
https://www.pyimagesearch.com/2019/01/28/keras-regression-and-cnns/)?


從技術上講,沒有理由不能將年齡預測看做迴歸任務。甚至有一些模型可以通過迴歸來實現。


問題在於年齡預測本質上是主觀的,並且僅基於容貌。


一個五十多歲的人一生中從未吸菸,出門總是擦防曬霜,而且每天都要護理皮膚。而一個三十多歲的人一天要抽很多煙,不擦防曬霜去從事體力勞動,並且沒有適當的皮膚護理。這個五十歲的人很可能看起來比這個三十歲的人年輕。


而且不要忘記基因是衰老最重要的驅動因素——有些人就是比其他人衰老得慢。


例如,看看下面的Matthew Perry(在電視情景喜劇Friends中扮演Chandler Bing)的圖片,並將它與Jennifer Aniston(扮演Rachel Green)的圖片進行比較:

用OpenCV和深度學習進行年齡識別

圖4:許多名人和行業領袖努力使自己看起來更年輕。這對使用OpenCV深度學習進行年齡檢測提出了挑戰。


您能猜出Matthew Perry(50歲)實際上比Jennifer Aniston(51歲)小一歲嗎?


除非您事先了解了關於這些演員的情況,否則我不會相信。


但另一方面,您能猜到這些演員在48-53歲嗎?


我願意打賭您可能有這個能力。


雖然人類天生不擅長預測年齡的準確值,但我們實際上在預測年齡段方面還是不錯的。


當然,上面是一個示例。


Jennifer Aniston的基因近乎完美,再加上有非常優秀的整形外科醫生,她似乎青春不老。


但這印證了我的觀點——人們有意掩飾自己的年齡。


而且,如果人類準確地預測一個人的年齡很困難的話,那麼機器肯定也會同樣困難。


一旦你將年齡預測看做迴歸問題,那麼對於一個模型,要準確預測人的圖像中的年齡值是極困難的。


但是,如果您將其視為分類問題,為模型定義了年齡段,那麼我們的年齡預測模型將更容易訓練,通常會比基於迴歸的預測提供更高的準確性。


簡而言之:將年齡預測看做分類問題可以極大地“緩解”問題,使其更容易解決——通常我們不需要一個人的確切年齡;粗略的估計就足夠了。


項目結構


請確保從本文的“下載”部分中獲取代碼,模型和圖片。提取文件後,您的項目將如下所示:

用OpenCV和深度學習進行年齡識別

前兩個目錄由年齡預測器和麵部檢測器組成。這兩個深度學習模型都基於Caffe。


我提供了三張用於年齡預測的測試圖片;您也可以添加自己的圖片。


在本教程的其餘部分,我們將討論這兩個Python腳本:

·detect_age.py:圖片年齡預測

·detect_age_video.py:視頻年齡預測


這些腳本都會檢測圖片/幀中的人臉,然後使用OpenCV對它們進行年齡預測。


運行我們的OpenCV圖像年齡檢測器


讓我們開始在靜態圖像中使用OpenCV進行年齡檢測。


在您的目錄中打開detect_age.py文件,讓我們開始工作:

用OpenCV和深度學習進行年齡識別

為了啟動我們的年齡檢測器腳本,我們先導入NumPy和OpenCV。我建議查看我的pip install opencv教程(
https://www.pyimagesearch.com/2018/09/19/pip-install-opencv/)來配置您的系統。


此外,我們需要導入Python內置的os模塊,它可以添加模型所需的路徑。


最後,我們導入argparse來解析命令行參數(
https://www.pyimagesearch.com/2018/03/12/python-argparse-command-line-arguments/)。


我們的腳本需要四個命令行參數:

·--圖片:提供為年齡檢測輸入圖像的路徑

·--人臉:為預先訓練的面部檢測器模型提供路徑

·--年齡:預先訓練的年齡探測器模型

·--置信度:最小概率閾值,以便篩除低置信檢測


如上所述,我們的年齡檢測器是一種分類器,可以根據預定義的年齡分段,通過人的面部ROI預測這個人的年齡——我們不會將其視為迴歸問題。現在讓我們定義這些年齡段的bucket:

用OpenCV和深度學習進行年齡識別


我們的年齡是在預先訓練好的年齡檢測器的bucket(即類別標籤)中定義的。我們將使用此列表和相關的索引來獲取年齡段,從而在輸出的圖像上進行註釋。


完成了導入,命令行參數和年齡段的設置,我們現在就可以加載兩個預先訓練的模型:

用OpenCV和深度學習進行年齡識別


在這裡,我們加載兩個模型:

·我們的人臉檢測器可以找到並定位圖片中的人臉(第25-28行)

·年齡分類器確定特定面孔所屬的年齡範圍(第32-34行)


這些模型均使用Caffe框架進行了訓練。我在PyImageSearch Gurus課程(


https://www.pyimagesearch.com/pyimagesearch-gurus/)中介紹瞭如何訓練Caffe分類器。


現在我們已經完成了所有初始化,讓我們從磁盤加載圖像並檢測面部ROI:

用OpenCV和深度學習進行年齡識別

37-40行加載並預處理了我們輸入的圖像。我們使用OpenCV的blobFromImage方法——請在我的教程(
https://www.pyimagesearch.com/2017/11/06/deep-learning-opencvs-blobfromimage-works/)中閱讀有關blobFromImage的更多信息。


為了檢測圖片中的人臉,我們通過CNN傳送blob,得到了detections的列表。現在讓我們循環面部ROI的檢測:

用OpenCV和深度學習進行年齡識別

當我們循環detections時,我們清除了低置信度的面部(第51-55行)。


對於滿足了最低置信度標準的面部,我們提取它們的ROI座標(第58-63行)。現在,我們在僅包含單個面部的圖像中有了小小收穫。我們在第64-66行根據此ROI創建一個blob(即faceBlob)。


現在,我們將進行年齡識別:

用OpenCV和深度學習進行年齡識別

我們使用face blob進行年齡預測(第70-74行),從而得出年齡段和年齡的置信度。我們使用這些數據點以及面部ROI的座標來註釋最初輸入的圖片(第77-86行)並顯示結果(第89和90行)。


在下一部分中,我們將分析結果。


OpenCV的年齡識別結果


讓我們運行OpenCV年齡檢測器。


首先,從本教程的“下載”部分下載源代碼,預先訓練的年齡檢測器模型及示例圖像。


從那裡打開一個終端,然後執行以下命令:

用OpenCV和深度學習進行年齡識別

用OpenCV和深度學習進行年齡識別

圖5:在我30歲時的照片中,該OpenCV年齡檢測器正確識別了我的年齡。


在這裡,您可以看到我們的OpenCV年齡檢測器以57.51%的置信度預測了我的年齡為25-32歲——實際上,該年齡檢測器是正確的(我拍攝這張照片時是30歲)。


讓我們再舉一個例子,這是著名演員Neil Patrick Harris小時候的照片:

用OpenCV和深度學習進行年齡識別

用OpenCV和深度學習進行年齡識別

圖6:使用OpenCV進行年齡預測時,可以很確定地認為拍攝這張照片時的Neil Patrick Harris是8-12歲。


我們的年齡預測值又是正確的——拍攝這張照片時,Nat Patrick Harris看起來的確在8-12歲年齡段中的某個年齡。


讓我們嘗試另一張圖片;這張圖是Samuel L. Jackson,他是我最喜歡的演員之一:

用OpenCV和深度學習進行年齡識別

用OpenCV和深度學習進行年齡識別

圖7:使用OpenCV通過深度學習進行年齡預測並不總是準確的,正如Samuel L. Jackson的照片所證明的那樣。年齡預測只是一個軟件,對人類來說是主觀的。


這裡我們的OpenCV年齡檢測器出錯了——Samuel L. Jackson大約71歲,這使我們的年齡預測大約有了18歲的偏差。


也就是說,僅僅看照片——Jackson先生看上去像71歲嗎?


我的猜測應該是50到60歲左右。至少對我來說,他不像70歲多一點的男人。


但這恰恰印證了我在前文提出的觀點:


用視覺進行年齡預測的過程很困難,當計算機或人試圖猜測某人的年齡時,我認為這是主觀的。


為了評估年齡檢測器,您不能依賴人的實際年齡去評價。相反,您需要衡量預測年齡和感知年齡之間的準確度。


為實時視頻運行我們的OpenCV年齡檢測器


現在我們可以在靜態圖像中實現年齡檢測,但實時視頻可以嗎?


我們可以這樣做嗎?


您應該猜我們可以。我們的視頻腳本與圖像腳本非常相似。不同之處在於,我們需要設置視頻流並在每個幀上循環進行年齡檢測。本文將重點介紹視頻功能,因此請根據需要參考上面的流程。


要了解如何在視頻中進行年齡識別,那就來看看detect_age_video.py。

用OpenCV和深度學習進行年齡識別

我們需要導入三個新的模塊:(1)VideoStream (2)imutils (3)time。這些導入允許我們對視頻進行設置和使用webcam功能。


我決定定義一個快捷函數來獲取幀,定位面部並預測年齡。函數通過進行檢測和邏輯預測,使我們的幀處理循環不會那麼龐大(您也可以將此函數放到單獨的文件中)。現在讓我們進入這個程序:

用OpenCV和深度學習進行年齡識別

我們的 detect_and_predict_age 輔助函數接受以下參數:

·frame:視頻通過webcam獲取的單個幀

·faceNet:初始化的深度學習人臉檢測器

·ageNet:初始化的深度學習年齡分類器

·minConf:篩去較差人臉識別的置信度閾值


這裡的參數和我們的圖片年齡檢測器腳本的命令行參數是相似的。


我們的AGE_BUCKETS再次被定義(第12和13行)。


然後我們定義一個空列表來保存面部定位和年齡檢測的結果。


第20-26行進行面部檢測。


接下來,我們將處理每個detections:

用OpenCV和深度學習進行年齡識別

請看29-43行——它們循環檢測,以確保較高的置信度,然後提取出面部ROI。


第46-47行是新的——由於以下兩個原因,我們要確保視頻中的面部ROI足夠大:

·首先,我們要篩掉幀中檢測到的假陽性面部。

·其次,年齡分類結果對於遠離相機的臉(即臉部很小)來說並不準確。


為了完成我們的輔助功能,我們將進行年齡識別並返回結果:

用OpenCV和深度學習進行年齡識別

在這裡,我們預測人臉的年齡並提取出年齡段和年齡置信度(第56-60行)。


第65-68行在一個字典中存儲面部定位和年齡預測。循環檢測的最後一步是將該字典放到結果列表中(第69行)。


如果所有檢測都已經完成,並且結果都得到了,那我們將結果返回給調用者。


定義好輔助函數後,現在我們可以繼續處理視頻了。但我們需要先定義命令行參數:

用OpenCV和深度學習進行年齡識別

我們的腳本需要三個命令行參數:

·--face:預先訓練的面部檢測器模型的目錄的路徑

·--age:預先訓練的年齡檢測器模型的目錄

·--confidence:最小概率閾值,以便篩除低置信檢測


在這裡,我們將加載模型並初始化視頻:

用OpenCV和深度學習進行年齡識別

第86-89行加載並初始化了我們的面部檢測器,而第93-95行加載了年齡檢測器。


然後,我們使用VideoStream類來初始化webcam(第99和100行)。


webcam準備好後,我們將開始處理幀:

用OpenCV和深度學習進行年齡識別

在上面的循環中,我們:

·獲取幀,並將其調整為已知寬度(第106和107行)

·通過我們的detect_and_predict_age便捷函數傳遞幀,以便(1)檢測面部(2)確定年齡(第111和112行)

·在幀上註釋結果(第115-124行)

·顯示和捕獲鍵盤輸入(第127和128行)

·如果鍵入q,那麼退出並清空(第131-136行)


在下一節中,我們將啟動年齡檢測器,看看它是否有效!


使用OpenCV進行實時年齡檢測的結果


現在,讓我們將OpenCV年齡檢測器應用於實時視頻。


確保您已從本教程的“下載”部分下載源代碼和預先訓練的年齡檢測器。


從那裡打開一個終端,然後輸入以下命令:

用OpenCV和深度學習進行年齡識別

用OpenCV和深度學習進行年齡識別

在這裡,您可以看到OpenCV年齡檢測器將我的年齡範圍準確地預測為25-32歲(在寫本文時,我還是31歲)。


如何改善年齡預測結果?


由Levi和Hassner訓練的年齡預測模型的問題之一是,它嚴重偏向25-32歲年齡組,如他們原始版本(
https://talhassner.github.io/home/projects/cnn_agegender/CVPR2015_CNN_AgeGenderEstimation.pdf)中的這個混淆矩陣表所示:

用OpenCV和深度學習進行年齡識別

圖8:Levi和Hassner的深度學習年齡檢測模型嚴重偏向25-32歲年齡段。為了在您的模型中解決此問題,請考慮收集更多的訓練數據,使用類權重、數據擴充和正則化技術。(圖片來源
https://talhassner.github.io/home/projects/cnn_agegender/CVPR2015_CNN_AgeGenderEstimation.pdf)


不幸的是,這意味著我們的模型預測的25-32歲結果可能實際上屬於其他的年齡段——我在分析本教程的結果以及我自己的年齡預測中也遇到了幾次這樣的情況。


您可以通過以下方法消除這種偏差:

1 收集其他年齡段的額外訓練數據以幫助平衡數據集

2 使用類權重來處理類失衡的問題

3 注意數據擴充

4 訓練模型時使用正則化


其次,年齡預測結果可以通過使用人臉對齊(
https://www.pyimagesearch.com/2017/05/22/face-alignment-with-opencv-and-python/)來改善。


人臉對齊功能會識別人臉的幾何結構,然後嘗試使用平移,縮放和旋轉獲得人臉的規範化。


在許多情況下(但並非總是如此),人臉對齊可以改善面部應用的效果,包括面部識別,年齡預測等。


為簡單起見,我們在本教程中沒有使用人臉對齊功能,但是您可以按照這個教程(
https://www.pyimagesearch.com/2017/05/22/face-alignment-with-opencv-and-python/)學習有關人臉對齊的更多信息,然後將其應用於自己的年齡預測程序中。


性別預測呢?


我特意選擇不在本教程中介紹性別預測。


使用計算機視覺和深度學習來識別一個人的性別似乎是一個有趣的分類問題,但實際上這是一個道德問題。


某人在視覺上看上去怎樣,穿著什麼或如何表現,這些都並不意味著他們可能是某種(或其他)性別。


試圖將性別劃分為兩類的軟件只會把我們束縛在對於性別的過時觀念裡。因此,我鼓勵您儘可能不要在自己的程序中使用性別識別。


如果必須進行性別識別,請確保對自己負責,並確保您不去創建使他人遵循性別偏見的應用程序(例如根據感知到的性別去定義用戶體驗)。


性別識別幾乎沒有價值,而且它引起的問題比它解決的問題還要多。請儘可能避免它。


總結


在本教程中,您學習瞭如何使用OpenCV通過深度學習進行年齡識別。


為此,我們利用了Levi和Hassner在2015年出版的《使用卷積神經網絡進行年齡和性別分類》中的預訓練模型。該模型使我們能夠以相當高的準確度去預測八個不同的年齡段;但是,我們必須認識到年齡預測是一個很有挑戰性的問題。


有很多因素可以決定一個人的視覺年齡,包括他們的生活方式,工作,吸菸習慣,最重要的是基因。其次,請記住,人們試圖掩飾自己的年齡——如果人類準確地預測某人的年齡有困難的話,那麼機器學習模型同樣會有困難。


因此,您必須根據感知年齡(而非實際年齡)去評估所有的年齡預測結果。在您自己的計算機視覺項目中進行年齡識別時,請記住這一點。


希望您喜歡本教程!


要從本文中下載源代碼(包括預先訓練的年齡檢測器模型),只需在下面的表格(
https://app.monstercampaigns.com/c/tortsem7qkvyuxc4cyfi)中輸入您的電子郵件地址即可!


英文原文:
https://www.pyimagesearch.com/2020/04/13/opencv-age-detection-with-deep-learning/
譯者:桃夭


分享到:


相關文章: