基於深度學習的人臉性別識別系統(含UI介面,Python程式碼)

思緒無限發表於2022-04-18
功能演示動圖

摘要:人臉性別識別是人臉識別領域的一個熱門方向,本文詳細介紹基於深度學習的人臉性別識別系統,在介紹演算法原理的同時,給出Python的實現程式碼以及PyQt的UI介面。在介面中可以選擇人臉圖片、視訊進行檢測識別,也可通過電腦連線的攝像頭裝置進行實時識別人臉性別;可對影像中存在的多張人臉進行性別識別,可選擇任意一張人臉框選顯示結果,檢測速度快、識別精度高。博文提供了完整的Python程式碼和使用教程,適合新入門的朋友參考,完整程式碼資原始檔請轉至文末的下載連結。本博文目錄如下:

➷點選跳轉至文末所有涉及的完整程式碼檔案下載頁☇

完整資源下載連結https://mianbaoduo.com/o/bread/YpmXk5xv

程式碼介紹及演示視訊連結:https://www.bilibili.com/video/BV15Y4y1v7AB/(正在更新中,歡迎關注博主B站視訊)


前言

        隨著科技的發展,人臉識別以及性別檢測在日常生活中的應用越來越廣泛,由於人臉影像的生物特徵識別是非接觸的,比較簡單快速,還具有一定的娛樂性,在社交網路、視訊監控、人機互動等領域具有廣闊的應用前景。本文使用OpenCV演算法,實現人臉檢測以及性別識別,使用者可以選擇傳入圖片、視訊、或者攝像頭實時攝影作為檢測的檔案。

        人臉性別識別,其實是人臉屬性識別的一種,即根據影像中的人臉判斷其性別屬於男性還是女性,該任務本身具有較強的現實意義。前面博主分享有人臉表情識別系統介紹的博文,可以認為是檢測人臉的表情屬性[1],對性別的識別算是繼續人臉識別的小專題。這裡博主分享一個性別識別的小專案,供大家參考學習了。

        網上的人臉性別識別程式程式碼很多,大部分都是採用OpenCV演算法和face_recognition等識別單張圖片中的人臉,雖然後者的演算法相較於前者更簡單,但是對於大多數Windows使用者想要下載這個庫是很困難的,所以本博文使用對Windows使用者更友好的OpenCV演算法來完成。網上的人臉性別識別程式指令碼很多,但幾乎沒有人將其開發成一個可以展示的完整軟體,並不方便選擇檔案和實時檢測。對此這裡給出博主設計的介面,同款的簡約風,功能也可以滿足圖片、視訊和攝像頭的識別檢測,希望大家可以喜歡,初始介面如下圖:

功能演示動圖

        檢測人臉時的介面截圖(點選圖片可放大)如下圖,可識別畫面中存在的多個人臉,也可開啟攝像頭或視訊檢測:

功能演示動圖

         詳細的功能演示效果參見博主的B站視訊或下一節的動圖演示,覺得不錯的朋友敬請點贊、關注加收藏!系統UI介面的設計工作量較大,介面美化更需仔細雕琢,大家有任何建議或意見和可在下方評論交流。


1. 效果演示

        軟體好不好用,顏值很重要,首先我們還是通過動圖看一下識別性別的效果,系統主要實現的功能是對圖片、視訊和攝像頭畫面中的人臉性別屬性進行識別,識別的結果視覺化顯示在介面和影像中,另外提供多個人臉的顯示選擇功能,演示效果如下。

(一)選擇人臉圖片識別

        系統允許選擇圖片檔案進行識別,點選圖片選擇按鈕圖示選擇圖片後,顯示所有人臉識別的結果,可通過下拉選框檢視單個人臉的結果。本功能的介面展示如下圖所示:

功能演示動圖

(二)人臉視訊識別效果展示

        很多時候我們需要識別一段視訊中的人臉屬性,這裡設計了視訊選擇功能。點選視訊按鈕可選擇待檢測的視訊,系統會自動解析視訊逐幀識別人臉,並將結果記錄在右下角表格中,效果如下圖所示:

功能演示動圖

(三)攝像頭檢測效果展示

        在真實場景中,我們往往利用裝置攝像頭獲取實時畫面,同時需要對畫面中的人臉性別進行識別,因此本文考慮到此項功能。如下圖所示,點選攝像頭按鈕後系統進入準備狀態,系統顯示實時畫面並開始檢測畫面中的人臉,識別結果展示如下圖:

功能演示動圖

2. 人臉檢測與性別識別

        人臉性別識別可看成是通過人臉影像資訊自動發掘和分析人臉屬性的二分類問題。在廣告定向投放、個性化智慧推薦、人臉屬性分析等方面得到廣泛應用。如今人工智慧橫掃經典演算法,因此以卷積神經網路為代表的深度學習方法自然就被廣泛用於人臉性別識別研究。本文藉助OpenCV演算法,實現人臉檢測以及性別識別,這裡首先對實現原理進行介紹。

        本文所使用的模型是由 Gil Levi 和Tal Hassner 釋出在CVPR的《Age and Gender Classification using Convolutional Neural Networks》論文,論文旨在縮小自動人臉識別能力與年齡性別估計方法之間的差距[2]。論文使用Adience資料集,該資料集包含比LFW資料集的影像更具挑戰性,使用一個健壯性更強的系統提升效能,以更好地利用來自大量示例訓練集的資訊。

功能演示動圖

        這裡使用的是一種以上論文提出的卷積神經網路架構,類似於 CaffeNet 和 AlexNet。該網路使用 3 個卷積層、2 個全連線層和一個最終輸出層。首先原始影像被縮放至\(256 \times 256\)的尺寸,對影像進行中心裁剪,得到尺寸為\(227 \times 227\)的影像作為網路輸入,該網路結構如下圖所示:

功能演示動圖
  1. 尺寸為\(96 \times 3 \times 7 \times 7\)的卷積核,接ReLU層、MaxPooling(\(3 \times 3, stride=2\))、歸一化層,輸出尺寸:\(96 \times 28 \times 28\)
  2. 尺寸為\(96 \times 5 \times 5 \times 256\)的卷積核,接ReLU層、MaxPooling(\(3 \times 3, stride=2\))、歸一化層,輸出尺寸:\(256 \times 14 \times 14\)
  3. 尺寸為\(256 \times 14 \times 14 \times 384\)的卷積核,接ReLU層、MaxPooling(\(3 \times 3\))$;
  4. 全連線層(512個神經元),接ReLU層及Dropout層;
  5. 全連線層(512個神經元),接ReLU層及Dropout層;
  6. 根據性別對映到最後的類別輸出。

        利用以上網路進行訓練,所有層中的權重均採用標準偏差為0.01,均值為0的高斯隨機值初始化。訓練時不使用預訓練模型,不使用基準可用的影像和標籤之外的任何資料,網路從頭開始進行訓練。訓練的目標值用與真實類別相對應的稀疏二進位制向量表示,對於每個訓練影像,目標標籤向量具有類數的長度,在真實值所在索引位置為1,在其他位置為0。訓練基於Adience資料集,使用隨機梯度下降演算法進行訓練,其中批量大小(Batch Size)設定為50,初始學習率為\(e-3\),在\(10K\)次迭代後降為\(e-4\)

        這裡我們利用OpenCV匯入該演算法,呼叫電腦自帶的攝像頭獲取畫面,並對畫面中的人臉進行性別識別。首先需要匯入用到的Python庫:

import cv2 as cv
import time
import argparse

        然後匯入我們下載到的訓練模型,主要有人臉檢測和性別識別的模型,程式碼如下:

faceProto = "opencv_face_detector.pbtxt"
faceModel = "opencv_face_detector_uint8.pb" # 檢測人臉的模型,

genderProto = "gender_deploy.prototxt"
genderModel = "gender_net.caffemodel" # 判斷性別的模型
MODEL_MEAN_VALUES = (78.4263377603, 87.7689143744, 114.895847746)
genderList = ['Male', 'Female'] # 性別列表

# 載入 network
genderNet = cv.dnn.readNet(genderModel, genderProto)
faceNet = cv.dnn.readNet(faceModel, faceProto)

        接下來我們定義獲得影像/視訊的人臉資訊的函式,使用模型對影像中的人臉進行檢測,框出人臉位置:

def getFace(frame):
    conf_threshold = 0.7
    # 獲取影像的資訊,以便之後對影像的操作
    height = frame.copy().shape[0]
    width = frame.copy().shape[1]
    # 對圖片進行預處理, frame就是我們讀取到視訊的每一幀,最後輸出的大小是300*300
    # 同時也幫助我們減均值抵抗亮度的變化對模型造成的不良影響
    # 為了消除同一場景下不同光照的圖片,對我們最終的分類或者神經網路的影響,
    # 我們常常對圖片的R、G、B通道的畫素求一個平均值,然後將每個畫素值減去我們的平均值,
    # 這樣就可以得到畫素之間的相對值,就可以排除光照的影響。
    frameblob = cv.dnn.blobFromImage(frame.copy(), 1.0, (300, 300), [104, 117, 123], True, False)
    # 識別人臉
    faceNet.setInput(frameblob)# 將預處理後的影像輸入網路
    detections = faceNet.forward() # 將影像向前傳播,檢測可以檢測到的東西
    box = []  # 用來保留檢測到的結果
    # 遍歷所有的結果, 並將可行的放到我們最終的結果中
    for i in range(detections.shape[2]):
        confidence = detections[0, 0, i, 2]  # 得到檢測結果的分數
        if confidence > conf_threshold: # 大於閾值就是我們需要的結果
            # 取出相對座標並獲得原座標
            x1 = int(detections[0, 0, i, 3] * width)
            y1 = int(detections[0, 0, i, 4] * height)
            x2 = int(detections[0, 0, i, 5] * width)
            y2 = int(detections[0, 0, i, 6] * height)
            box.append([x1, y1, x2, y2])
            # 繪圖
            cv.rectangle(frame.copy(), (x1, y1), (x2, y2), (0, 255, 0), int(round(height / 150)), 8)
    return frame.copy(), box

        以上函式傳入的引數是影像的資訊,經過該函式的處理,我們檢測影像中包含的資訊,然後通過上述論文模型的預測,取出影像中可能是人臉資料的值,這些就是最後用來預測的資料,該步驟主要用的就是facenet這個神經網路模型,使用該模型之後能夠大大增加資料的準確性,讓後面的預測模型更加精準。

        FaceNet是谷歌於CVPR2015.02發表,提出了一個對識別(這是誰?)、驗證(這是用一個人嗎?)、聚類(在這些面孔中找到同一個人)等問題的統一解決框架,即它們都可以放到特徵空間裡統一處理,只需要專注於解決的僅僅是如何將人臉更好的對映到特徵空間[3]。其本質是通過卷積神經網路學習人臉影像到128維歐幾里得空間的對映,該對映將人臉影像對映為128維的特徵向量,聯想到二維空間的相關係數的定義,使用特徵向量之間的距離的倒數來表徵人臉影像之間的"相關係數"(為了方便理解,後文稱之為相似度),對於相同個體的不同圖片,其特徵向量之間的距離較小(即相似度較大),對於不同個體的影像,其特徵向量之間的距離較大(即相似度較小)。最後基於特徵向量之間的相似度來解決人臉影像的識別、驗證和聚類等問題。論文地址如下:https://arxiv.org/abs/1503.03832

功能演示動圖

        如上圖所示,FaceNet由一個批量輸入層和一個深度卷積神經網路(CNN )組成,然後是 L2 歸一化和之後的人臉嵌入,最後使用三元組損失函式進行訓練。影像經過該模型後就可以得到影像中人臉的基本資訊特徵,接下來呼叫匯入的辨別gender的模型就可以完成人臉的識別,呼叫和標記識別結果的程式碼如下:

def face_pred(cap):
    padding = 20
    while cv.waitKey(1) < 0:
        # 讀取 frame
        t = time.time()
        # 讀取視訊中的幀
        hasFrame, frame = cap.read()
        if not hasFrame:
            # 等待鍵盤發出命令
            cv.waitKey(100)
            break
        frameFace, bboxes = getFace(frame)
        # if not bboxes:
        #     continue
        for bbox in bboxes:
            face = frame[max(0, bbox[1] - padding):min(bbox[3] + padding, frame.shape[0] - 1),
                   max(0, bbox[0] - padding):min(bbox[2] + padding, frame.shape[1] - 1)]
            # 繼續對影像進行處理,得到展示的圖片的形式
            blob = cv.dnn.blobFromImage(face+, 1.0, (227, 227), MODEL_MEAN_VALUES, swapRB=False)
            genderNet.setInput(blob)
            genderPreds = genderNet.forward()
            gender = genderList[genderPreds[0].argmax()]
            label = "{}".format(gender)
            cv.putText(frameFace, label, (bbox[0], bbox[1] - 10), cv.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 255), 2,
                       cv.LINE_AA)
            cv.imshow("Gender_recognition", frameFace)

        該函式傳入的引數是視訊的資料,讀取視訊的函式是cv.VideoCapture( ),如果該函式的引數是0,那麼就會呼叫系統攝像頭,獲取本人的人臉資料,如果傳入的引數是一個檔案地址,那麼就會預測傳入視訊的性別。最終執行以上函式進行識別的程式碼如下:

cap = cv.VideoCapture(0)
face_pred(cap)

        執行以上演示指令碼,達到的結果如下圖所示,性別識別結果被顯示在人臉上方。有了以上的思路,我們可以在此基礎上利用PyQt5設計UI介面,將圖片、視訊選擇和攝像頭功能更好展示在介面中。

功能演示動圖

        開啟QtDesigner軟體,拖動以下控制元件至主視窗中,調整介面樣式和控制元件放置,性別識別系統的介面設計如下圖所示:

功能演示動圖

        控制元件介面部分設計好,接下來利用PyUIC工具將.ui檔案轉化為.py程式碼檔案,通過呼叫介面部分的程式碼同時加入對應的邏輯處理程式碼。博主對其中的UI功能進行了詳細測試,最終開發出一版流暢得到清新介面,就是博文演示部分的展示,完整的UI介面、測試圖片視訊、程式碼檔案,以及Python離線依賴包(方便安裝執行,也可自行配置環境),均已打包上傳,感興趣的朋友可以通過下載連結獲取。


下載連結

    若您想獲得博文中涉及的實現完整全部程式檔案(包括測試圖片、視訊,py, UI檔案等,如下圖),這裡已打包上傳至博主的麵包多平臺和CSDN下載資源。本資源已上傳至麵包多網站和CSDN下載資源頻道,可以點選以下連結獲取,已將所有涉及的檔案同時打包到裡面,點選即可執行,完整檔案截圖如下:

功能演示動圖

    在資料夾下的資源顯示如下,其中包含了Python的離線依賴包,讀者可在正確安裝Anaconda和Pycharm軟體後,點選bat檔案進行安裝,詳細演示也可見本人B站視訊。

功能演示動圖

注意:本資源已經過除錯通過,下載後可通過Pycharm執行;執行介面的主程式為runMain.py,測試攝像頭或視訊指令碼可執行main.py,為確保程式順利執行,請配置Python依賴包的版本如下:➷➷➷

Python版本:3.8,請勿使用其他版本,詳見requirements.txt檔案;

certifi == 2021.10.8
click == 7.1.2
numpy == 1.22.3
opencv-python == 4.5.5.64
Pillow == 9.0.1
PyQt5 == 5.15.4
pyqt5-plugins == 5.15.4.2.2
PyQt5-Qt5 == 5.15.2
PyQt5-sip == 12.9.1
pyqt5-tools == 5.15.4.3.2
python-dotenv == 0.19.2
qt5-applications == 5.15.2.2.2
qt5-tools == 5.15.2.1.2
wincertstore == 0.2

完整資源下載連結1https://mianbaoduo.com/o/bread/YpmXk5xv

完整資源下載連結2博主在CSDN下載頻道的完整資源下載頁


結束語

        由於博主能力有限,博文中提及的方法即使經過試驗,也難免會有疏漏之處。希望您能熱心指出其中的錯誤,以便下次修改時能以一個更完美更嚴謹的樣子,呈現在大家面前。同時如果有更好的實現方法也請您不吝賜教。


  1. https://wuxian.blog.csdn.net/article/details/91347164 ↩︎

  2. Levi G, Hassner T. Age and gender classification using convolutional neural networks[C]//Proceedings of the IEEE conference on computer vision and pattern recognition workshops. 2015: 34-42. ↩︎

  3. Schroff F, Kalenichenko D, Philbin J. Facenet: A unified embedding for face recognition and clustering[C]//Proceedings of the IEEE conference on computer vision and pattern recognition. 2015: 815-823. ↩︎

相關文章