1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        (附代碼)實(shí)戰(zhàn) | 用OpenCV和深度學(xué)習(xí)進(jìn)行年齡識(shí)別

        共 15440字,需瀏覽 31分鐘

         ·

        2021-08-02 23:15

        點(diǎn)擊左上方藍(lán)字關(guān)注我們



        全網(wǎng)搜集目標(biāo)檢測相關(guān),人工篩選最優(yōu)價(jià)值內(nèi)容

        編者薦語
        文章可使大家Get如何使用OpenCV,深度學(xué)習(xí)和Python執(zhí)行年齡的自動(dòng)識(shí)別/預(yù)測。擼完本教程您將能以相當(dāng)高的精確度,預(yù)測靜態(tài)圖像文件、實(shí)時(shí)視頻中人的年齡。

        轉(zhuǎn)載自 | python程序員


        用OpenCV和深度學(xué)習(xí)進(jìn)行年齡識(shí)別

        在本文的第一部分關(guān)于年齡識(shí)別,包括從圖片或視頻中自動(dòng)預(yù)測人的年齡所需要的步驟(以及為何將年齡識(shí)別當(dāng)做分類問題而不是回歸問題來處理)。

        下面我們將介紹這個(gè)基于深度學(xué)習(xí)的年齡識(shí)別模型,然后學(xué)習(xí)如何將該模型應(yīng)用在兩個(gè)方面:

        1. 靜態(tài)圖像中的年齡識(shí)別
        2. 實(shí)時(shí)視頻中的年齡識(shí)別

        什么是年齡識(shí)別?

        圖1:本教程使用 OpenCV 和預(yù)訓(xùn)練的深度學(xué)習(xí)模型來預(yù)測給定人臉的年齡

        年齡識(shí)別是僅用人臉的照片去自動(dòng)識(shí)別其年齡的過程,通常,年齡識(shí)別可分為兩個(gè)階段進(jìn)行實(shí)現(xiàn):

        • 階段1. :檢測輸入圖像/視頻中的人臉;
        • 階段2:提取人的面部區(qū)域(ROI),并通過年齡檢測算法預(yù)測人的年齡。

        對(duì)于第一階段,可以使用任何能夠?yàn)閳D片中的人臉生成邊框的人臉檢測器。這些檢測器包括但不限于Haar cascades,HOG+線性SVM,單鏡頭檢測器(SSD)等。

        具體使用哪種人臉檢測器取決于您的項(xiàng)目:

        • Haar cascades速度很快,并且能夠在嵌入式設(shè)備上實(shí)時(shí)運(yùn)行。缺點(diǎn)是準(zhǔn)確度較低,并且極易出現(xiàn)假陽性檢測。
        • HOG+線性SVM模型比Haar cascades更精確,但速度較慢。它們對(duì)遮擋(即部分面部可見)或視角變化(即面部的不同視圖)的容錯(cuò)性也較低。
        • 基于深度學(xué)習(xí)的人臉檢測器功能最為強(qiáng)大,它提供了最高的準(zhǔn)確度,但比Haar cascades和HOG+線性SVM需要更多的計(jì)算資源。

        當(dāng)選擇人臉檢測器時(shí),需要花點(diǎn)時(shí)間考慮您的項(xiàng)目需求——速度或準(zhǔn)確性,哪個(gè)對(duì)您更加重要?除此之外,還建議您對(duì)每個(gè)人臉檢測器進(jìn)行試驗(yàn),以便從實(shí)驗(yàn)結(jié)果中擇優(yōu)而從。

        一旦您的人臉檢測器在圖像/視頻中生成了人臉的邊界框坐標(biāo),就可以進(jìn)入第二階段——確定人的年齡。

        確定了臉部的邊界框坐標(biāo)(x,y)后,首先提取面部ROI,而忽略圖像/幀的其余部分。以便將年齡檢測器的注意力放在人臉上,而非圖像中其他不相關(guān)的“噪點(diǎn)”。然后將面部ROI傳遞給模型,從而得到實(shí)際的年齡預(yù)測。

        年齡檢測器的算法有很多,但是最受歡迎的是基于深度學(xué)習(xí)的年齡檢測器——在本教程中,將使用這種基于深度學(xué)習(xí)的年齡檢測器。

        基于深度學(xué)習(xí)的年齡檢測器模型

        圖2:用深度學(xué)習(xí)進(jìn)行年齡識(shí)別是一個(gè)活躍的研究領(lǐng)域

        本文中使用的深度學(xué)習(xí)年齡檢測器模型是Levi和Hassner發(fā)表的《使用卷積神經(jīng)網(wǎng)絡(luò)進(jìn)行年齡和性別分類》中構(gòu)建和訓(xùn)練的。該文作者提出了一個(gè)類似AlexNet的簡單體系,該體系總共學(xué)習(xí)了8個(gè)年齡段:

        1. 0-2
        2. 4-6
        3. 8-12
        4. 15-20
        5. 25-32
        6. 38-43
        7. 48-53
        8. 60-100

        您可能會(huì)注意到這些年齡段是不連續(xù)的,這是有意而為。因?yàn)橛糜谟?xùn)練模型的Adience數(shù)據(jù)集定義了年齡段(下一節(jié)中將介紹為什么這樣做)。

        在這篇文章中,我們將使用預(yù)先訓(xùn)練的年齡檢測器模型。如果您有興趣學(xué)習(xí)如何從頭開始訓(xùn)練它,請(qǐng)務(wù)必閱讀《用Python進(jìn)行計(jì)算機(jī)視覺深度學(xué)習(xí)》,在那里我將向您展示如何訓(xùn)練。

        我們?yōu)槭裁床粚⒛挲g預(yù)測看做回歸問題?

        圖3:用深度學(xué)習(xí)進(jìn)行年齡預(yù)測可以被歸類為回歸或分類問題

        您會(huì)在上面注意到,我們將年齡離散化為"不同的區(qū)間”,從而將年齡預(yù)測作為分類問題——為什么不將它看做回歸問題?

        從技術(shù)上講,沒有理由不能將年齡預(yù)測看做回歸任務(wù)。甚至有一些模型可以通過回歸來實(shí)現(xiàn)。問題在于年齡預(yù)測本質(zhì)上是主觀的,并且僅基于容貌。

        一個(gè)五十多歲的人,從未吸過煙、出門總是擦防曬霜、每天都要護(hù)理皮膚,相比一個(gè)三十多歲的人一天要抽很多煙、不擦防曬霜、從事體力勞動(dòng),且沒有適當(dāng)?shù)钠つw護(hù)理的人,五十歲的人很可能看起來比三十歲的人年輕。

        而且,基因是衰老最重要的驅(qū)動(dòng)因素。有些人就是比其他人衰老得慢。

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

        圖4:許多名人和行業(yè)領(lǐng)袖努力使自己看起來更年輕。這對(duì)使用OpenCV深度學(xué)習(xí)進(jìn)行年齡檢測提出了挑戰(zhàn)

        您能猜出 Matthew Perry(50歲)實(shí)際上比 Jennifer Aniston(51歲)小一歲嗎?若非您事先了解了關(guān)于這些演員的情況,否則我不會(huì)相信。

        但另一方面,您能猜到這些演員在48-53歲嗎?這個(gè)準(zhǔn)確率恐怕高一些。

        雖然人類天生不擅長預(yù)測年齡的準(zhǔn)確值,但我們實(shí)際上在預(yù)測年齡段方面還是不錯(cuò)的。當(dāng)然上面只是一個(gè)示例,Jennifer Aniston的基因近乎完美,再加上有非常優(yōu)秀的整形外科醫(yī)生,她似乎青春不老。

        但這印證了我的觀點(diǎn)——如果人類準(zhǔn)確地預(yù)測一個(gè)人的年齡很困難的話,那么機(jī)器肯定也會(huì)同樣困難。

        一旦將年齡預(yù)測看做回歸問題,那么對(duì)于一個(gè)模型,要準(zhǔn)確預(yù)測人的圖像中的年齡值是極困難的。但如果您將其視為分類問題,為模型定義了年齡段,那么我們的年齡預(yù)測模型將更容易訓(xùn)練,通常會(huì)比基于回歸的預(yù)測提供更高的準(zhǔn)確性。

        簡而言之:將年齡預(yù)測看做分類問題可以極大地"緩解”準(zhǔn)確程度——通常我們不需要一個(gè)人的確切年齡,粗略的估計(jì)就足夠了。

        項(xiàng)目結(jié)構(gòu)

        您可從本文相關(guān)鏈接中獲取代碼,模型和圖片,提取文件后,您的項(xiàng)目將如下所示:

        $ tree --dirsfirst
        .
        ├── age_detector
        │ ├── age_deploy.prototxt
        │ └── age_net.caffemodel
        ├── face_detector
        │ ├── deploy.prototxt
        │ └── res10_300x300_ssd_iter_140000.caffemodel
        ├── images
        │ ├── adrian.png
        │ ├── neil_patrick_harris.png
        │ └── samuel_l_jackson.png
        ├── detect_age.py
        └── detect_age_video.py
        3 directories, 9 files

        前兩個(gè)目錄由年齡預(yù)測器和面部檢測器組成。這兩個(gè)深度學(xué)習(xí)模型都基于Caffe。

        這里提供了三張用于年齡預(yù)測的測試圖片,您也可以添加自己的圖片。

        在本教程的其余部分,我們將討論這兩個(gè)Python腳本:

        • detect\_age.py:圖片年齡預(yù)測
        • detect\_age\_video.py:視頻年齡預(yù)測

        這些腳本都會(huì)檢測圖片/幀中的人臉,然后使用OpenCV對(duì)它們進(jìn)行年齡預(yù)測。

        運(yùn)行該 OpenCV 圖像年齡檢測器

        首先,開始在靜態(tài)圖像中使用OpenCV進(jìn)行年齡檢測。在目錄中打開detect\_age.py文件,運(yùn)行工作:

        # import the necessary packages
        import numpy as np
        import argparse
        import cv2
        import os
        # construct the argument parse and parse the arguments
        ap = argparse.ArgumentParser()
        ap.add_argument("-i", "--image", required=True,
        help="path to input image")
        ap.add_argument("-f", "--face", required=True,
        help="path to face detector model directory")
        ap.add_argument("-a", "--age", required=True,
        help="path to age detector model directory")
        ap.add_argument("-c", "--confidence", type=float, default=0.5,
        help="minimum probability to filter weak detections")
        args = vars(ap.parse_args())

        為了啟動(dòng)我們的年齡檢測器腳本,我們先導(dǎo)入NumPy和OpenCV。我建議查看我的pip install opencv教程來配置您的系統(tǒng)。

        此外,需要導(dǎo)入Python內(nèi)置的os模塊,它可以添加模型所需的路徑。

        最后,導(dǎo)入argparse來解析命令行參數(shù)。

        此處的腳本需要四個(gè)命令行參數(shù):

        • image:提供為年齡檢測輸入圖像的路徑
        • face:為預(yù)先訓(xùn)練的面部檢測器模型提供路徑
        • age:預(yù)先訓(xùn)練的年齡探測器模型
        • confidence:最小概率閾值,以便篩除低置信檢測

        如上所述,本文的年齡檢測器是一種分類器,可以根據(jù)預(yù)定義的年齡分段,通過人的面部 ROI 預(yù)測這個(gè)人的年齡——我們不會(huì)將其視為回歸問題。現(xiàn)在讓我們定義這些年齡段的bucket:

        # define the list of age buckets our age detector will predict
        AGE_BUCKETS = ["(0-2)", "(4-6)", "(8-12)", "(15-20)", "(25-32)",
        "(38-43)", "(48-53)", "(60-100)"]


        我們的年齡是在預(yù)先訓(xùn)練好的年齡檢測器的bucket(即類別標(biāo)簽)中定義的。我們將使用此列表和相關(guān)的索引來獲取年齡段,從而在輸出的圖像上進(jìn)行注釋。

        完成了導(dǎo)入,命令行參數(shù)和年齡段的設(shè)置,我們現(xiàn)在就可以加載兩個(gè)預(yù)先訓(xùn)練的模型:

        # load our serialized face detector model from disk
        print("[INFO] loading face detector model...")
        prototxtPath = os.path.sep.join([args["face"], "deploy.prototxt"])
        weightsPath = os.path.sep.join([args["face"],
        "res10_300x300_ssd_iter_140000.caffemodel"])
        faceNet = cv2.dnn.readNet(prototxtPath, weightsPath)
        # load our serialized age detector model from disk
        print("[INFO] loading age detector model...")
        prototxtPath = os.path.sep.join([args["age"], "age_deploy.prototxt"])
        weightsPath = os.path.sep.join([args["age"], "age_net.caffemodel"])
        ageNet = cv2.dnn.readNet(prototxtPath, weightsPath)

        在這里,我們加載兩個(gè)模型:

        • 我們的人臉檢測器可以找到并定位圖片中的人臉(第25-28行)
        • 年齡分類器確定特定面孔所屬的年齡范圍(第32-34行)

        這些模型均使用Caffe框架進(jìn)行了訓(xùn)練。在PyImageSearch Gurus課程中介紹了如何訓(xùn)練Caffe分類器。

        現(xiàn)在我們已經(jīng)完成了所有初始化,從磁盤加載圖像并檢測面部ROI:

        # load the input image and construct an input blob for the image
        image = cv2.imread(args["image"])
        (h, w) = image.shape[:2]
        blob = cv2.dnn.blobFromImage(image, 1.0, (300, 300),
        (104.0, 177.0, 123.0))
        # pass the blob through the network and obtain the face detections
        print("[INFO] computing face detections...")
        faceNet.setInput(blob)
        detections = faceNet.forward()
        37-40行加載并預(yù)處理了輸入的圖像

        我們使用OpenCV的blobFromImage方法——請(qǐng)?jiān)谖业慕坛讨虚喿x有關(guān)blobFromImage的更多信息。

        為了檢測圖片中的人臉,我們通過CNN傳送blob,得到了detections的列表?,F(xiàn)在讓我們循環(huán)面部ROI的檢測:

        # loop over the detections
        for i in range(0, detections.shape[2]):
        # extract the confidence (i.e., probability) associated with the
        # prediction
        confidence = detections[0, 0, i, 2]
        # filter out weak detections by ensuring the confidence is
        # greater than the minimum confidence
        if confidence > args["confidence"]:
        # compute the (x, y)-coordinates of the bounding box for the
        # object
        box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
        (startX, startY, endX, endY) = box.astype("int")
        # extract the ROI of the face and then construct a blob from
        # *only* the face ROI
        face = image[startY:endY, startX:endX]
        faceBlob = cv2.dnn.blobFromImage(face, 1.0, (227, 227),
        (78.4263377603, 87.7689143744, 114.895847746),
        swapRB=False)

        當(dāng)我們循環(huán)detections時(shí),我們清除了低置信度的面部(第51-55行)。

        對(duì)于滿足了最低置信度標(biāo)準(zhǔn)的面部,我們提取它們的ROI坐標(biāo)(第58-63行)。現(xiàn)在,我們?cè)趦H包含單個(gè)面部的圖像中有了小小收獲。我們?cè)诘?4-66行根據(jù)此ROI創(chuàng)建一個(gè)blob(即faceBlob)。

        現(xiàn)在,我們將進(jìn)行年齡識(shí)別:

        		# make predictions on the age and find the age bucket with
        # the largest corresponding probability
        ageNet.setInput(faceBlob)
        preds = ageNet.forward()
        i = preds[0].argmax()
        age = AGE_BUCKETS[i]
        ageConfidence = preds[0][i]
        # display the predicted age to our terminal
        text = "{}: {:.2f}%".format(age, ageConfidence * 100)
        print("[INFO] {}".format(text))
        # draw the bounding box of the face along with the associated
        # predicted age
        y = startY - 10 if startY - 10 > 10 else startY + 10
        cv2.rectangle(image, (startX, startY), (endX, endY),
        (0, 0, 255), 2)
        cv2.putText(image, text, (startX, y),
        cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 2)
        # display the output image
        cv2.imshow("Image", image)
        cv2.waitKey(0)

        我們使用face blob進(jìn)行年齡預(yù)測(第70-74行),從而得出年齡段和年齡的置信度。我們使用這些數(shù)據(jù)點(diǎn)以及面部ROI的坐標(biāo)來注釋最初輸入的圖片(第77-86行)并顯示結(jié)果(第89和90行)。

        在下一部分中,我們將分析結(jié)果。

        OpenCV的年齡識(shí)別結(jié)果

        讓我們運(yùn)行OpenCV年齡檢測器。

        首先,從本教程的"下載"部分下載源代碼,預(yù)先訓(xùn)練的年齡檢測器模型及示例圖像。
        從那里打開一個(gè)終端,然后執(zhí)行以下命令:

        $ python detect_age.py --image images/adrian.png --face face_detector --age age_detector
        [INFO] loading face detector model...
        [INFO] loading age detector model...
        [INFO] computing face detections...
        [INFO] (25-32): 57.51%
        圖5:我30歲時(shí)的照片,OpenCV年齡檢測器正確識(shí)別了我的年齡

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

        讓我們?cè)倥e一個(gè)例子,這是著名演員Neil Patrick Harris小時(shí)候的照片:

        $ python detect_age.py --image images/neil_patrick_harris.png --face face_detector --age age_detector
        [INFO] loading face detector model...
        [INFO] loading age detector model...
        [INFO] computing face detections...
        [INFO] (8-12): 85.72%

        我們的年齡預(yù)測是正確的,拍攝這張照片時(shí),Nat Patrick Harris看起來的確在8-12歲年齡段中的某個(gè)年齡。

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

        $ python detect_age.py --image images/samuel_l_jackson.png --face face_detector --age age_detector
        [INFO] loading face detector model...
        [INFO] loading age detector model...
        [INFO] computing face detections...
        [INFO] (48-53): 69.38%
        圖7:使用OpenCV通過深度學(xué)習(xí)進(jìn)行年齡預(yù)測并不總是準(zhǔn)確的,正如Samuel L. Jackson的照片所證實(shí)的,年齡預(yù)測會(huì)受很多因素影響

        OpenCV年齡檢測器針對(duì)Samuel L. Jackson的結(jié)果出錯(cuò)了——Jackson大約71歲,年齡預(yù)測大約有18歲的偏差。

        僅僅看照片Jackson先生看上去像71歲嗎?我猜測應(yīng)該是50到60歲左右,他不像70歲多一點(diǎn)的男人。但這恰恰印證了我在前文提出的觀點(diǎn):

        用視覺進(jìn)行年齡預(yù)測的過程很困難,當(dāng)計(jì)算機(jī)或人試圖猜測某人的年齡時(shí),我認(rèn)為這是主觀的。

        為了評(píng)估年齡檢測器,不能依賴人的實(shí)際年齡去評(píng)價(jià)。相反,需要衡量預(yù)測年齡和感知年齡之間的準(zhǔn)確度。

        為實(shí)時(shí)視頻運(yùn)行我們的OpenCV年齡檢測器

        現(xiàn)在我們可以在靜態(tài)圖像中實(shí)現(xiàn)年齡檢測,但實(shí)時(shí)視頻可以嗎?

        您應(yīng)該猜我們可以。我們的視頻腳本與圖像腳本非常相似。不同之處在于,我們需要設(shè)置視頻流并在每個(gè)幀上循環(huán)進(jìn)行年齡檢測。本文將重點(diǎn)介紹視頻功能,可根據(jù)需要參考上面的流程。

        要了解如何在視頻中進(jìn)行年齡識(shí)別,那就來看看detect\_age\_video.py。

        # import the necessary packages
        from imutils.video import VideoStream
        import numpy as np
        import argparse
        import imutils
        import time
        import cv2
        import os

        我們需要導(dǎo)入三個(gè)新的模塊:

        1. VideoStream
        2. imutils
        3. time

        這些導(dǎo)入允許我們對(duì)視頻進(jìn)行設(shè)置和使用webcam功能。

        我決定定義一個(gè)快捷函數(shù)來獲取幀,定位面部并預(yù)測年齡。函數(shù)通過進(jìn)行檢測和邏輯預(yù)測,使我們的幀處理循環(huán)不會(huì)那么龐大(您也可以將此函數(shù)放到單獨(dú)的文件中)?,F(xiàn)在讓我們進(jìn)入這個(gè)程序:

        def detect_and_predict_age(frame, faceNet, ageNet, minConf=0.5):
        # define the list of age buckets our age detector will predict
        AGE_BUCKETS = ["(0-2)", "(4-6)", "(8-12)", "(15-20)", "(25-32)",
        "(38-43)", "(48-53)", "(60-100)"]
        # initialize our results list
        results = []
        # grab the dimensions of the frame and then construct a blob
        # from it
        (h, w) = frame.shape[:2]
        blob = cv2.dnn.blobFromImage(frame, 1.0, (300, 300),
        (104.0, 177.0, 123.0))
        # pass the blob through the network and obtain the face detections
        faceNet.setInput(blob)
        detections = faceNet.forward()

        我們的 detect\_and\_predict\_age 輔助函數(shù)接受以下參數(shù):

        • frame:視頻通過webcam獲取的單個(gè)幀
        • faceNet:初始化的深度學(xué)習(xí)人臉檢測器
        • ageNet:初始化的深度學(xué)習(xí)年齡分類器
        • minConf:篩去較差人臉識(shí)別的置信度閾值

        這里的參數(shù)和我們的圖片年齡檢測器腳本的命令行參數(shù)是相似的。
        我們的AGE\_BUCKETS再次被定義(第12和13行)。然后我們定義一個(gè)空列表來保存面部定位和年齡檢測的results。(第20-26行進(jìn)行面部檢測。)

        接下來,我們將處理每個(gè)detections

        	# loop over the detections
        for i in range(0, detections.shape[2]):
        # extract the confidence (i.e., probability) associated with
        # the prediction
        confidence = detections[0, 0, i, 2]
        # filter out weak detections by ensuring the confidence is
        # greater than the minimum confidence
        if confidence > minConf:
        # compute the (x, y)-coordinates of the bounding box for
        # the object
        box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
        (startX, startY, endX, endY) = box.astype("int")
        # extract the ROI of the face
        face = frame[startY:endY, startX:endX]
        # ensure the face ROI is sufficiently large
        if face.shape[0] < 20 or face.shape[1] < 20:
        continue

        請(qǐng)看29-43行——它們循環(huán)檢測,以確保較高的置信度,然后提取出面部ROI。

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

        • 首先,我們要篩掉幀中檢測到的假陽性面部。
        • 其次,年齡分類結(jié)果對(duì)于遠(yuǎn)離相機(jī)的臉(即臉部很?。﹣碚f并不準(zhǔn)確。

        為了完成我們的輔助功能,我們將進(jìn)行年齡識(shí)別并返回結(jié)果:

        			# construct a blob from *just* the face ROI
        faceBlob = cv2.dnn.blobFromImage(face, 1.0, (227, 227),
        (78.4263377603, 87.7689143744, 114.895847746),
        swapRB=False)
        # make predictions on the age and find the age bucket with
        # the largest corresponding probability
        ageNet.setInput(faceBlob)
        preds = ageNet.forward()
        i = preds[0].argmax()
        age = AGE_BUCKETS[i]
        ageConfidence = preds[0][i]
        # construct a dictionary consisting of both the face
        # bounding box location along with the age prediction,
        # then update our results list
        d = {
        "loc": (startX, startY, endX, endY),
        "age": (age, ageConfidence)
        }
        results.append(d)
        # return our results to the calling function
        return results

        在這里預(yù)測人臉的年齡并提取出年齡段和年齡置信度(第56-60行)。第65-68行在一個(gè)字典中存儲(chǔ)面部定位和年齡預(yù)測。循環(huán)檢測的最后一步是將該字典放到結(jié)果列表中(第69行)。

        如果所有檢測都已經(jīng)完成,并且結(jié)果都得到了,那我們將結(jié)果返回給調(diào)用者。

        定義好輔助函數(shù)后,現(xiàn)在我們可以繼續(xù)處理視頻了。但我們需要先定義命令行參數(shù):

        # construct the argument parse and parse the arguments
        ap = argparse.ArgumentParser()
        ap.add_argument("-f", "--face", required=True,
        help="path to face detector model directory")
        ap.add_argument("-a", "--age", required=True,
        help="path to age detector model directory")
        ap.add_argument("-c", "--confidence", type=float, default=0.5,
        help="minimum probability to filter weak detections")
        args = vars(ap.parse_args())

        我們的腳本需要三個(gè)命令行參數(shù):

        • face:預(yù)先訓(xùn)練的面部檢測器模型的目錄的路徑
        • age:預(yù)先訓(xùn)練的年齡檢測器模型的目錄
        • confidence:最小概率閾值,以便篩除低置信檢測

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

        # load our serialized face detector model from disk
        print("[INFO] loading face detector model...")
        prototxtPath = os.path.sep.join([args["face"], "deploy.prototxt"])
        weightsPath = os.path.sep.join([args["face"],
        "res10_300x300_ssd_iter_140000.caffemodel"])
        faceNet = cv2.dnn.readNet(prototxtPath, weightsPath)
        # load our serialized age detector model from disk
        print("[INFO] loading age detector model...")
        prototxtPath = os.path.sep.join([args["age"], "age_deploy.prototxt"])
        weightsPath = os.path.sep.join([args["age"], "age_net.caffemodel"])
        ageNet = cv2.dnn.readNet(prototxtPath, weightsPath)
        # initialize the video stream and allow the camera sensor to warm up
        print("[INFO] starting video stream...")
        vs = VideoStream(src=0).start()
        time.sleep(2.0)

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

        然后,我們使用VideoStream類來初始化webcam(第99和100行)。webcam準(zhǔn)備好后,我們將開始處理幀:

        # loop over the frames from the video stream
        while True:
        # grab the frame from the threaded video stream and resize it
        # to have a maximum width of 400 pixels
        frame = vs.read()
        frame = imutils.resize(frame, width=400)
        # detect faces in the frame, and for each face in the frame,
        # predict the age
        results = detect_and_predict_age(frame, faceNet, ageNet,
        minConf=args["confidence"])
        # loop over the results
        for r in results:
        # draw the bounding box of the face along with the associated
        # predicted age
        text = "{}: {:.2f}%".format(r["age"][0], r["age"][1] * 100)
        (startX, startY, endX, endY) = r["loc"]
        y = startY - 10 if startY - 10 > 10 else startY + 10
        cv2.rectangle(frame, (startX, startY), (endX, endY),
        (0, 0, 255), 2)
        cv2.putText(frame, text, (startX, y),
        cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 2)
        # show the output frame
        cv2.imshow("Frame", frame)
        key = cv2.waitKey(1) & 0xFF
        # if the `q` key was pressed, break from the loop
        if key == ord("q"):
        break
        # do a bit of cleanup
        cv2.destroyAllWindows()
        vs.stop()

        在上面的循環(huán)中,我們:

        • 獲取幀,并將其調(diào)整為已知寬度(第106和107行)
        • 通過我們的detect_and_predict_age便捷函數(shù)傳遞幀,以便(1)檢測面部(2)確定年齡(第111和112行)
        • 在幀上注釋結(jié)果(第115-124行)
        • 顯示和捕獲鍵盤輸入(第127和128行)
        • 如果鍵入q,那么退出并清空(第131-136行)

        在下一節(jié)中,我們將啟動(dòng)年齡檢測器,看看它是否有效!

        使用OpenCV進(jìn)行實(shí)時(shí)年齡檢測的結(jié)果

        現(xiàn)在,讓我們將OpenCV年齡檢測器應(yīng)用于實(shí)時(shí)視頻。
        確保您已從本教程的"下載"部分下載源代碼和預(yù)先訓(xùn)練的年齡檢測器。
        從那里打開一個(gè)終端,然后輸入以下命令:

        $ python detect_age_video.py --face face_detector --age age_detector
        [INFO] loading face detector model...
        [INFO] loading age detector model...
        [INFO] starting video stream...

        在這里,您可以看到OpenCV年齡檢測器將我的年齡范圍準(zhǔn)確地預(yù)測為25-32歲(在寫本文時(shí),我還是31歲)。

        如何改善年齡預(yù)測結(jié)果?

        由Levi和Hassner訓(xùn)練的年齡預(yù)測模型的問題之一是,它嚴(yán)重偏向25-32歲年齡組,如他們?cè)及姹局械倪@個(gè)混淆矩陣表所示:

        圖8:Levi和Hassner的深度學(xué)習(xí)年齡檢測模型嚴(yán)重偏向25-32歲年齡段

        為了在您的模型中解決此問題,請(qǐng)考慮收集更多的訓(xùn)練數(shù)據(jù),使用類權(quán)重、數(shù)據(jù)擴(kuò)充和正則化技術(shù)。

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

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

        1. 收集其他年齡段的額外訓(xùn)練數(shù)據(jù)以幫助平衡數(shù)據(jù)集;
        2. 使用類權(quán)重來處理類失衡的問題;
        3. 注意數(shù)據(jù)擴(kuò)充;
        4. 訓(xùn)練模型時(shí)使用正則化。

        其次,年齡預(yù)測結(jié)果可以通過使用人臉對(duì)齊來改善。

        人臉對(duì)齊功能會(huì)識(shí)別人臉的幾何結(jié)構(gòu),然后嘗試使用平移,縮放和旋轉(zhuǎn)獲得人臉的規(guī)范化。

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

        為簡單起見,我們?cè)诒窘坛讨袥]有使用人臉對(duì)齊功能,但您可以按照這個(gè)教程學(xué)習(xí)有關(guān)人臉對(duì)齊的更多信息,然后將其應(yīng)用于自己的年齡預(yù)測程序中。

        性別預(yù)測呢?

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

        使用計(jì)算機(jī)視覺和深度學(xué)習(xí)來識(shí)別一個(gè)人的性別似乎是一個(gè)有趣的分類問題,但實(shí)際上這是一個(gè)道德問題。

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

        試圖將性別劃分為兩類的軟件只會(huì)把我們束縛在對(duì)于性別的過時(shí)觀念里。因此,我鼓勵(lì)您盡可能不要在自己的程序中使用性別識(shí)別。

        如果必須進(jìn)行性別識(shí)別,請(qǐng)確保對(duì)自己負(fù)責(zé),并確保您不去創(chuàng)建使他人遵循性別偏見的應(yīng)用程序(例如根據(jù)感知到的性別去定義用戶體驗(yàn))。

        性別識(shí)別幾乎沒有價(jià)值,而且它引起的問題比它解決的問題還要多。請(qǐng)盡可能避免它。

        總結(jié)

        在本教程中,您學(xué)習(xí)了如何使用OpenCV通過深度學(xué)習(xí)進(jìn)行年齡識(shí)別。

        為此,我們利用了Levi和Hassner在2015年出版的《使用卷積神經(jīng)網(wǎng)絡(luò)進(jìn)行年齡和性別分類》中的預(yù)訓(xùn)練模型。該模型使我們能夠以相當(dāng)高的準(zhǔn)確度去預(yù)測八個(gè)不同的年齡段;但是,我們必須認(rèn)識(shí)到年齡預(yù)測是一個(gè)很有挑戰(zhàn)性的問題。

        有很多因素可以決定一個(gè)人的視覺年齡,包括他們的生活方式,工作,吸煙習(xí)慣,最重要的是基因。其次,請(qǐng)記住,人們?cè)噲D掩飾自己的年齡——如果人類準(zhǔn)確地預(yù)測某人的年齡有困難的話,那么機(jī)器學(xué)習(xí)模型同樣會(huì)有困難。

        因此,您需要根據(jù)感知年齡(而非實(shí)際年齡)去評(píng)估所有的年齡預(yù)測結(jié)果。在您自己的計(jì)算機(jī)視覺項(xiàng)目中進(jìn)行年齡識(shí)別時(shí),請(qǐng)記住這一點(diǎn)。

        希望您喜歡本教程!

        原文鏈接:https://www.pyimagesearch.com/2020/04/13/opencv-age-detection-with-deep-learning


        END



        雙一流大學(xué)研究生團(tuán)隊(duì)創(chuàng)建,專注于目標(biāo)檢測與深度學(xué)習(xí),希望可以將分享變成一種習(xí)慣!

        整理不易,點(diǎn)贊三連↓

        瀏覽 402
        點(diǎn)贊
        1評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        全部評(píng)論
        QS184565d5a423789862024-02-21 15:20
        代碼可以給我一份嗎
        點(diǎn)贊回復(fù)
        推薦
        點(diǎn)贊
        1評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            女人被男人猛烈进入是怎么了 | 嗯啊啊啊视频 | 秋霞论乱 | 欧美一级棒 | 看操逼逼 | 黄色一级大片在线免费看国产一 | 做爰全过程男欢女爱 | 黄色片快播| 五月丁香影院 | 免费下载一级片 |