摘要:人臉性別識別是人臉識別領域的一個熱門方向,本文詳細介紹基于深度學習的人臉性別識別系統,在介紹演算法原理的同時,給出Python的實作代碼以及PyQt的UI界面,在界面中可以選擇人臉圖片、視頻進行檢測識別,也可通過電腦連接的攝像頭設備進行實時識別人臉性別;可對影像中存在的多張人臉進行性別識別,可選擇任意一張人臉框選顯示結果,檢測速度快、識別精度高,博文提供了完整的Python代碼和使用教程,適合新入門的朋友參考,完整代碼資源檔案請轉至文末的下載鏈接,本博文目錄如下:
目錄- 前言
- 1. 效果演示
- 2. 人臉檢測與性別識別
- 下載鏈接
- 結束語
?點擊跳轉至文末所有涉及的完整代碼檔案下載頁?
完整資源下載鏈接: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\)的影像作為網路輸入,該網路結構如下圖所示:
- 尺寸為\(96 \times 3 \times 7 \times 7\)的卷積核,接ReLU層、MaxPooling(\(3 \times 3, stride=2\))、歸一化層,輸出尺寸:\(96 \times 28 \times 28\);
- 尺寸為\(96 \times 5 \times 5 \times 256\)的卷積核,接ReLU層、MaxPooling(\(3 \times 3, stride=2\))、歸一化層,輸出尺寸:\(256 \times 14 \times 14\);
- 尺寸為\(256 \times 14 \times 14 \times 384\)的卷積核,接ReLU層、MaxPooling(\(3 \times 3\))$;
- 全連接層(512個神經元),接ReLU層及Dropout層;
- 全連接層(512個神經元),接ReLU層及Dropout層;
- 根據性別映射到最后的類別輸出,
利用以上網路進行訓練,所有層中的權重均采用標準偏差為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
完整資源下載鏈接1:https://mianbaoduo.com/o/bread/YpmXk5xv
完整資源下載鏈接2:博主在CSDN下載頻道的完整資源下載頁
結束語
由于博主能力有限,博文中提及的方法即使經過試驗,也難免會有疏漏之處,希望您能熱心指出其中的錯誤,以便下次修改時能以一個更完美更嚴謹的樣子,呈現在大家面前,同時如果有更好的實作方法也請您不吝賜教,
https://wuxian.blog.csdn.net/article/details/91347164 ??
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. ??
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. ??
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/458531.html
標籤:其他
上一篇:集成學習-偏差與方差
