摘要:人臉檢測(cè)與識(shí)別是機(jī)器視覺(jué)領(lǐng)域最熱門的研究方向之一,本文詳細(xì)介紹博主自主設(shè)計(jì)的一款基于深度學(xué)習(xí)的人臉識(shí)別與管理系統(tǒng)。博文給出人臉識(shí)別實(shí)現(xiàn)原理的同時(shí),給出Python的人臉識(shí)別實(shí)現(xiàn)代碼以及PyQt設(shè)計(jì)的UI界面。系統(tǒng)實(shí)現(xiàn)了集識(shí)別人臉、錄入人臉、管理人臉在內(nèi)的多項(xiàng)功能:包括通過(guò)選擇人臉圖片、視頻、攝像頭進(jìn)行已錄入人臉的實(shí)時(shí)識(shí)別;可通過(guò)圖片和攝像頭檢測(cè)人臉并錄入新的人臉;通過(guò)系統(tǒng)管理和更新人臉數(shù)據(jù)等功能,檢測(cè)速度快、識(shí)別精度較高。博文提供了完整的Python代碼和使用教程,適合新入門的朋友參考,完整代碼資源文件請(qǐng)轉(zhuǎn)至文末的下載鏈接。本博文目錄如下:
?點(diǎn)擊跳轉(zhuǎn)至文末所有涉及的完整代碼文件下載頁(yè)?
代碼介紹及演示視頻鏈接:https://www.bilibili.com/video/BV1XB4y1U73S(正在更新中,歡迎關(guān)注博主B站視頻)
前言
????????近年來(lái),人臉識(shí)別的技術(shù)愈發(fā)成熟,在大型數(shù)據(jù)集上的訓(xùn)練測(cè)試結(jié)果已超過(guò)人類,其應(yīng)用也日益廣泛,譬如刷臉支付、安防偵破、出入口控制、互聯(lián)網(wǎng)服務(wù)等。人臉識(shí)別(Face Recognition)是一種通過(guò)獲取人面部的特征信息進(jìn)行身份確認(rèn)的技術(shù),類似已用于身份識(shí)別的人體的其他生物特征(如虹膜、指紋等),人臉具備唯一性、一致性和高度的不可復(fù)制性,為身份識(shí)別提供了穩(wěn)定的條件。人臉識(shí)別系統(tǒng)是博主一直想做的一個(gè)項(xiàng)目,通過(guò)人臉面部信息識(shí)別可以進(jìn)行很多有趣的設(shè)計(jì),如面部解鎖、考勤打卡等。
????????前面博主撰寫了人臉性別識(shí)別系統(tǒng)、表情識(shí)別系統(tǒng)等,其實(shí)是人臉屬性識(shí)別的一種,即根據(jù)人臉面部圖像中的相關(guān)特征判斷其性別或表情屬性,該任務(wù)本身也同樣具有較強(qiáng)的現(xiàn)實(shí)意義。這篇博文則回到人臉識(shí)別的任務(wù)本身,采用深度學(xué)習(xí)的方法對(duì)人臉特征進(jìn)行提取,計(jì)算其與已存在的人臉特征的相似度,判讀其是否屬于庫(kù)中的某一人臉,達(dá)到身份識(shí)別的目的。不過(guò)我希望在實(shí)現(xiàn)的基礎(chǔ)上,能多增加一些可操作性,因此盡可能設(shè)計(jì)一個(gè)功能完善的人臉識(shí)別系統(tǒng)。
????????查閱網(wǎng)上資料發(fā)現(xiàn),研究和分享人臉識(shí)別技術(shù)和代碼的大有人在,主要是做一些簡(jiǎn)單易行的小Demo等,大家可自行查閱參考。這里博主分享一個(gè)自主設(shè)計(jì)的人臉識(shí)別項(xiàng)目,包括識(shí)別人臉、錄入人臉、管理人臉在內(nèi)的多項(xiàng)功能,以下是界面的截圖,供大家參考學(xué)習(xí)了:
????????檢測(cè)識(shí)別人臉時(shí)的界面截圖(點(diǎn)擊圖片可放大)如下圖,可識(shí)別畫面中存在的多個(gè)人臉,也可開(kāi)啟攝像頭或視頻檢測(cè),以及人臉?shù)浫牍芾淼裙δ埽?/font>
???????? 詳細(xì)的功能演示效果參見(jiàn)博主的B站視頻或下一節(jié)的動(dòng)圖演示,覺(jué)得不錯(cuò)的朋友敬請(qǐng)點(diǎn)贊、關(guān)注加收藏!系統(tǒng)UI界面的設(shè)計(jì)工作量較大,界面美化更需仔細(xì)雕琢,大家有任何建議或意見(jiàn)和可在下方評(píng)論交流。
1. 效果演示
(一)選擇人臉圖片識(shí)別
????????在系統(tǒng)的功能選項(xiàng)按鈕中選擇“識(shí)別人臉”,點(diǎn)擊下方的圖片選擇按鈕圖標(biāo)選擇圖片后,在主顯區(qū)域標(biāo)記所有人臉識(shí)別的結(jié)果,并被逐條記錄在表格中。本功能的界面展示如下圖所示:
(二)人臉視頻識(shí)別效果展示
????????很多時(shí)候我們需要識(shí)別一段視頻中的人臉信息,這里設(shè)計(jì)了視頻選擇功能。同樣的在“識(shí)別人臉”功能選項(xiàng)下,點(diǎn)擊視頻按鈕可選擇待檢測(cè)的視頻,系統(tǒng)會(huì)自動(dòng)解析視頻逐幀識(shí)別人臉,并將結(jié)果記錄在右下角表格中,效果如下圖所示:
????????
(三)攝像頭檢測(cè)效果展示
????????在真實(shí)場(chǎng)景中,我們往往利用設(shè)備攝像頭獲取實(shí)時(shí)畫面,同時(shí)需要對(duì)畫面中的人臉進(jìn)行識(shí)別,同樣可以在“識(shí)別人臉”功能選項(xiàng)下選擇此項(xiàng)功能。如下圖所示,點(diǎn)擊攝像頭按鈕后系統(tǒng)進(jìn)入準(zhǔn)備狀態(tài),系統(tǒng)顯示實(shí)時(shí)畫面并開(kāi)始檢測(cè)畫面中的人臉,識(shí)別結(jié)果展示如下圖:
(四)錄入人臉效果展示
????????當(dāng)出現(xiàn)一個(gè)新的人臉需要錄入時(shí),點(diǎn)擊“錄入人臉”功能選項(xiàng)按鈕,此時(shí)底部功能界面切換至錄入功能,首先輸入人臉名字點(diǎn)擊“新建”后可通過(guò)選擇人臉圖片或開(kāi)啟攝像頭進(jìn)行畫面捕捉,系統(tǒng)檢測(cè)到人臉后可選擇“取圖”,系統(tǒng)得到捕獲的人臉區(qū)域圖片,最后點(diǎn)擊“錄入”按鈕,則提取所有人臉圖片特征并寫入系統(tǒng)庫(kù)中,演示效果如下:
(五)管理人臉效果展示
????????對(duì)于已經(jīng)存在的人臉數(shù)據(jù)可選擇“管理人臉”功能選項(xiàng)按鈕,切換至管理界面,選擇表格中要?jiǎng)h除或更新的人臉數(shù)據(jù)欄,點(diǎn)擊確定后系統(tǒng)自動(dòng)更新人臉數(shù)據(jù)庫(kù),該功能展示如下圖:
???????? 在識(shí)別某張?zhí)囟ㄈ四樓?,?yīng)該先在系統(tǒng)庫(kù)中錄入人臉信息,即送入一張人臉圖像供系統(tǒng)提取特征,此過(guò)程可選擇圖片也可開(kāi)啟攝像頭實(shí)時(shí)獲取。至此系統(tǒng)的演示完畢,其實(shí)除了動(dòng)圖中演示的功能,當(dāng)然還有許多細(xì)節(jié)功能無(wú)法一一演示,讀者可以自行測(cè)試。
2. 人臉識(shí)別原理
????????如今機(jī)器學(xué)習(xí)、神經(jīng)網(wǎng)絡(luò)方法廣泛應(yīng)用于人臉識(shí)別領(lǐng)域,而后深度學(xué)習(xí)廣泛應(yīng)用于各種目標(biāo)檢測(cè)領(lǐng)域,2015年,Google團(tuán)隊(duì)的FaceNet在LFW數(shù)據(jù)集上得平均準(zhǔn)確率達(dá)到了99.63%,基于深度學(xué)習(xí)的人臉識(shí)別的準(zhǔn)確率已經(jīng)高于人類本身,深度學(xué)習(xí)在人臉識(shí)別領(lǐng)域基本占據(jù)了統(tǒng)治地位。
????????Dlib是一個(gè)包含機(jī)器學(xué)習(xí)算法的C++開(kāi)源工具包,目前已經(jīng)被廣泛的用在行業(yè)和學(xué)術(shù)領(lǐng)域,包括機(jī)器人,嵌入式設(shè)備,移動(dòng)電話和大型高性能計(jì)算環(huán)境。作為人臉識(shí)別工具之一,Dlib在圖像處理及人臉面部特征處理、分類、識(shí)別等方面具有計(jì)算簡(jiǎn)單、較容易實(shí)現(xiàn)的優(yōu)點(diǎn)。
????????Dlib在人臉識(shí)別上的應(yīng)用:(1)接受圖像并將其加載到一個(gè)像素?cái)?shù)組中進(jìn)行處理;(2)使用局部二進(jìn)制模式的人臉描述生成新的圖像;(3)根據(jù)Dlib庫(kù)中的scan_image_boxes等函數(shù)寫入讀取到的圖片,進(jìn)而計(jì)算人臉之間的特征向量;(4)與人臉數(shù)據(jù)庫(kù)中的特征向量進(jìn)行對(duì)比并利用全局函數(shù)threshold_image計(jì)算閾值,完成人臉識(shí)別1。
????????Dlib可通過(guò)Python調(diào)用,實(shí)現(xiàn)對(duì)圖像預(yù)處理、提取特征向量、與人臉數(shù)據(jù)庫(kù)中數(shù)據(jù)進(jìn)行校驗(yàn)進(jìn)而判別人物身份的流程。這里我們的人臉識(shí)別的過(guò)程有人臉檢測(cè)(Face Detection)、人臉對(duì)齊(Face Alignment)、人臉表示(Face Representation)和人臉匹配(Face Matching),示意圖如下圖所示:
????????(1)人臉檢測(cè)(Face Detection):首先利用Dlib的get_frontal_face_detector方法檢測(cè)人臉區(qū)域并輸出人臉矩形的四個(gè)坐標(biāo)點(diǎn)。調(diào)用get_frontal_face_detector會(huì)返回 dlib 庫(kù)中包含的預(yù)訓(xùn)練方向梯度直方圖 (HOG)結(jié)合線性支持向量機(jī)(SVM)的人臉檢測(cè)器,該檢測(cè)器快速高效。由于方向梯度直方圖 (HOG) 描述符的工作原理,它對(duì)圖像幾何的和光學(xué)的形變都能保持很好的不變性。
????????(2)人臉對(duì)齊(Face Alignment):這是人臉識(shí)別系統(tǒng)中的一種標(biāo)準(zhǔn)操作,即從人臉區(qū)域中檢測(cè)到人臉特征點(diǎn),并以特征點(diǎn)為依據(jù)對(duì)人臉進(jìn)行歸一化操作,使人臉區(qū)域的尺度和角度一致,方便特征提取與人臉匹配。一般通過(guò)旋轉(zhuǎn)、平移與縮放將目標(biāo)人臉區(qū)域放置在圖像特定位置。這樣做可以減小需要處理的人臉圖像在空間分布上的差異。這里我們使用的是基于回歸樹(shù)的人臉對(duì)齊算法2,該算法是Vahid Kazemi 和 Josephine Sullivan在CVPR2014上發(fā)表的One Millisecond Face Alignment with an Ensemble of Regression Trees算法(以下簡(jiǎn)稱GBDT),這種方法通過(guò)建立一個(gè)級(jí)聯(lián)的殘差回歸樹(shù)(GBDT)來(lái)使人臉形狀從當(dāng)前形狀一步一步回歸到真實(shí)形狀。每一個(gè)GBDT的每一個(gè)葉子節(jié)點(diǎn)上都存儲(chǔ)著一個(gè)殘差回歸量,當(dāng)輸入落到一個(gè)節(jié)點(diǎn)上時(shí),就將殘差加到改輸入上,起到回歸的目的,最終將所有殘差疊加在一起,就完成了人臉對(duì)齊的目的。此處我們使用shape_predictor方法載入shape_predictor_68_face_landmarks.dat模型實(shí)現(xiàn)。
????????(3)人臉表示(Face Representation):這一步我們從歸一化的人臉區(qū)域中進(jìn)行面部特征提取,采用深度神經(jīng)網(wǎng)絡(luò)方法得到具有128個(gè)特征的特征向量。這里利用Dlib中的殘差學(xué)習(xí)深度神經(jīng)網(wǎng)絡(luò)(ResNet)3為待識(shí)別人臉創(chuàng)建128維特征向量。人臉的特征表示,最理想的情況是不同人臉的照片提取出的特征向量差異較大,而同一人臉在不同照片中可以提取出相似度高的特征向量。此處我們使用的是dlib庫(kù)中的face_recognition_model_v1方法,使用預(yù)訓(xùn)練的dlib_face_recognition_resnet_model_v1.dat模型。
????????(4)人臉匹配(Face Matching):將待識(shí)別圖片中提取的特征向量與比對(duì)圖中的進(jìn)行對(duì)比,通過(guò)評(píng)估方法計(jì)算兩幅照片的相似度。可以根據(jù)相似得分,將得分高的判斷為同一人,得分低的判斷為不同人。這里我們使用歐式距離計(jì)算,兩個(gè)人臉特征向量的歐式距離越小,則兩張人臉越相似,若人臉圖像與待識(shí)別人像之間的歐式距離小于設(shè)定的閾值(這里我設(shè)置為0.4)時(shí),則判定為同一人。
D i s = ( x 1 ? y 1 ) 2 + ( x 2 ? y 2 ) 2 + … + ( x n ? y n ) 2 Dis = \sqrt{\left(x_{1}-y_{1}\right)^{2}+\left(x_{2}-y_{2}\right)^{2}+\ldots+\left(x_{n}-y_{n}\right)^{2}} Dis=(x1??y1?)2+(x2??y2?)2+…+(xn??yn?)2?
3. 代碼實(shí)現(xiàn)
????????原理介紹完畢,我們開(kāi)始按照以上的步驟實(shí)現(xiàn)人臉識(shí)別過(guò)程。首先是導(dǎo)入幾個(gè)需要用到的Python依賴包,我們使用的Python版本是3.8,其代碼如下:
import dlib
import csv
import os
import cv2
import numpy as np
????????這里面值得要說(shuō)的dlib這個(gè)依賴,是后面人臉識(shí)別算法需要用到的工具庫(kù),它的安裝其實(shí)很簡(jiǎn)單,并不需要像網(wǎng)上說(shuō)的安裝Visual Studio 2015等軟件(網(wǎng)上安裝問(wèn)題主要是dlib沒(méi)有編譯的安裝包)。這里我將所有需要用到的依賴包都打包在了mylib文件夾中,并將依賴的版本號(hào)寫入了requirements.txt文件中,如下圖所示:
????????在安裝有Python3.8的情況下,首先切換cmd的目錄到mylib所在文件夾(requirements.txt也放在文件夾下),然后輸入以下代碼就可以完成依賴安裝了。這樣省去了版本不一致帶來(lái)的出錯(cuò)或諸多麻煩,dlib也是優(yōu)雅地安裝好了。安裝過(guò)程也可參考博主的B站視頻,完整文件夾中有一鍵安裝的bat文件可以幫助安裝。
pip install -r requirements.txt --no-index --find-links=./mylib/
????????配置好環(huán)境和導(dǎo)入依賴后,可以正式開(kāi)始代碼的介紹了。首先我們載入dlib中的幾個(gè)模型方法,其實(shí)現(xiàn)代碼如下:
path_face_dir = "./data/database_faces/"
person_list = os.listdir(path_face_dir)
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('./data/data_dlib/shape_predictor_68_face_landmarks.dat')
face_reco_model = dlib.face_recognition_model_v1("./data/data_dlib"
"/dlib_face_recognition_resnet_model_v1.dat")
????????如上一章節(jié)介紹的,detector、predictor、face_reco_model分別是人臉檢測(cè)器、人臉對(duì)齊方法、人臉表示(特征提?。┠P?。接下來(lái)我們寫一個(gè)從圖片中提取人臉特征的函數(shù)extract_features,該函數(shù)讀取圖片利用人臉檢測(cè)器獲取人臉位置,通過(guò)深度卷積神經(jīng)網(wǎng)絡(luò)Resnet進(jìn)行特征提取,最終得到128維的特征向量。其代碼如下:
def extract_features(path_img):
img_rd = cv2.imdecode(np.fromfile(path_img, dtype=np.uint8), -1)
faces = detector(img_rd, 1)
if len(faces) != 0:
shape = predictor(img_rd, faces[0])
face_descriptor = face_reco_model.compute_face_descriptor(img_rd, shape)
else:
face_descriptor = 0
return face_descriptor
????????我們將每個(gè)人臉的圖像各建一個(gè)文件夾保存,將文件夾的名字作為該人臉的命名標(biāo)識(shí),如下圖所示。每個(gè)文件夾下可放置一張或多張同類人臉圖像,用以后面進(jìn)行人臉特征提取,可自行收集人臉圖像放置在對(duì)應(yīng)文件夾下:
????????接下來(lái)就可以進(jìn)行特征提取了,這樣遍歷上面目錄中的每類人臉文件夾下的所有圖像并提取特征,然后取均值保存在csv文件中即可完成特征提取并記錄,該代碼實(shí)現(xiàn)如下:
with open("./features_all_test.csv", "w", newline="") as csvfile:
writer = csv.writer(csvfile)
for person in person_list:
features_list = []
photos_list = os.listdir(path_face_dir + "/" + person)
if photos_list:
for photo in photos_list:
features_128D = extract_features(path_face_dir + "/" + person + "/" + photo)
print("圖片" + photo + "已錄入!")
if features_128D == 0:
continue
else:
features_list.append(features_128D)
if features_list:
features_mean = np.array(features_list).mean(axis=0)
else:
features_mean = np.zeros(128, dtype=int, order='C')
str_face = [person]
str_face.extend(list(features_mean))
writer.writerow(str_face)
print("已完成人臉?shù)浫耄?)
????????以上代碼運(yùn)行下來(lái),提取到的人臉特征信息被寫入csv文件中,部分信息如下圖所示,每行的128個(gè)特征表示一個(gè)人臉信息,第一列為該人臉的名字:
????????接下來(lái)利用提取到的特征進(jìn)行人臉匹配,讀取一張新的人臉圖片然后判斷其屬于庫(kù)中的那張人臉。同樣的新建一個(gè)py文件,首先導(dǎo)入需要的依賴包,代碼如下:
import os
import time
import warnings
import cv2
import dlib
import numpy as np
import pandas as pd
from PIL import Image, ImageDraw, ImageFont
????????由于后面需要在圖像中顯示中文,所以這里先利用PIL導(dǎo)入中文字體記為fontC,然后還是導(dǎo)入需要用到的三個(gè)模型,代碼如下:
fontC = ImageFont.truetype("./FaceRecUI/Font/platech.ttf", 14, 0)
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('./data/data_dlib/shape_predictor_68_face_landmarks.dat')
face_reco_model = dlib.face_recognition_model_v1("./data/data_dlib"
"/dlib_face_recognition_resnet_model_v1.dat")
????????在匹配的過(guò)程中需要計(jì)算兩個(gè)人臉特征向量間的距離(相似度),這里先定義一個(gè)計(jì)算特征向量的歐氏距離函數(shù)euclidean_distance,返回兩個(gè)向量的距離值:
def euclidean_distance(feature_1, feature_2):
# 計(jì)算兩個(gè)128D向量間的歐式距離
feature_1 = np.array(feature_1)
feature_2 = np.array(feature_2)
dist = np.sqrt(np.sum(np.square(feature_1 - feature_2)))
return dist
????????另外,檢測(cè)和識(shí)別出的人臉結(jié)果需要標(biāo)記在圖像中,所以這里定義一個(gè)添加標(biāo)記的函數(shù)drawRectBox,即利用OpenCV和PIL在人臉位置處繪制標(biāo)記框和文字,其代碼如下:
def drawRectBox(img, rect_pos, addText):
cv2.rectangle(img, (int(round(rect_pos[0])), int(round(rect_pos[1]))),
(int(round(rect_pos[2])), int(round(rect_pos[3]))),
(0, 0, 255), 2)
cv2.rectangle(img, (int(rect_pos[0] - 1), int(rect_pos[1]) - 16), (int(rect_pos[0] + 75), int(rect_pos[1])), (0, 0, 255), -1,
cv2.LINE_AA)
img = Image.fromarray(img)
draw = ImageDraw.Draw(img)
draw.text((int(rect_pos[0] + 1), int(rect_pos[1] - 16)), addText, (255, 255, 255), font=fontC)
image_x = np.array(img)
return image_x
????????函數(shù)準(zhǔn)備就緒,開(kāi)始主函數(shù)部分,首先讀取一張人臉圖片:
if __name__ == '__main__':
filePath = "./FaceRecUI/test_img/樸信惠-1.jpeg"
img_rd = cv2.imdecode(np.fromfile(filePath, dtype=np.uint8), -1)
????????從csv文件讀取所有的人臉特征,將其保存在變量face_feature_exist中,用于后面的特征計(jì)算。這里讀取時(shí)采用逐行遍歷csv文件的方式,將每行的特征名和128維特征向量保存出來(lái),空數(shù)據(jù)的標(biāo)記為未知人臉。該部分代碼如下:
face_feature_exist = []
face_name_exist = []
flag = False
# 讀取已存入的人臉特征信息
if os.path.exists("./features_all_test.csv"):
path_features_known_csv = "./features_all_test.csv"
csv_rd = pd.read_csv(path_features_known_csv, header=None, encoding='gb2312')
for i in range(csv_rd.shape[0]):
features_someone_arr = []
for j in range(1, 129):
if csv_rd.iloc[i][j] == '':
features_someone_arr.append('0')
else:
features_someone_arr.append(csv_rd.iloc[i][j])
face_feature_exist.append(features_someone_arr)
if csv_rd.iloc[i][0] == '':
face_name_exist.append("未知人臉")
else:
face_name_exist.append(csv_rd.iloc[i][0])
exist_flag = True
else:
exist_flag = False
????????我們使用人臉檢測(cè)器獲取人臉位置,剪切出人臉區(qū)域;然后對(duì)人臉區(qū)域進(jìn)行特征提取并將其與庫(kù)中的特征進(jìn)行比較,逐個(gè)計(jì)算歐幾里得聚類,找出與之距離最小的庫(kù)人臉;將最小距離與設(shè)定的閾值(0.4)進(jìn)行比較,若小于0.4表示與該庫(kù)人臉匹配,否則視為未知人臉。此流程的代碼如下:
# 使用人臉檢測(cè)器進(jìn)行人臉檢測(cè)
image = img_rd.copy()
faces = detector(image, 0)
if len(faces) > 0:
# 矩形框 / Show the ROI of faces
face_feature_list = []
face_name_list = []
face_position_list = []
start_time = time.time()
for k, d in enumerate(faces):
# 計(jì)算矩形框大小 / Compute the size of rectangle box
height = (d.bottom() - d.top())
width = (d.right() - d.left())
hh = int(height / 2)
ww = int(width / 2)
y2 = d.right() + ww
x2 = d.bottom() + hh
y1 = d.left() - ww
x1 = d.top() - hh
# 判斷人臉區(qū)域是否超出畫面范圍
if y2 > img_rd.shape[1]:
y2 = img_rd.shape[1]
elif x2 > img_rd.shape[0]:
x2 = img_rd.shape[0]
elif y1 < 0:
y1 = 0
elif x1 < 0:
x1 = 0
# 剪切出人臉
crop_face = img_rd[x1: x2, y1: y2]
# 獲取人臉特征
shape = predictor(img_rd, d)
face_feature_list.append(face_reco_model.compute_face_descriptor(img_rd, shape))
current_face = crop_face
if exist_flag: # 獲取已存在人臉的特征
for k in range(len(faces)):
# 初始化
face_name_list.append("未知人臉")
# 每個(gè)捕獲人臉的名字坐標(biāo)
face_position_list.append(tuple(
[faces[k].left(), int(faces[k].bottom() + (faces[k].bottom() - faces[k].top()) / 4)]))
# 對(duì)于某張人臉,遍歷所有存儲(chǔ)的人臉特征
current_distance_list = []
for i in range(len(face_feature_exist)):
# 如果 person_X 數(shù)據(jù)不為空
if str(face_feature_exist[i][0]) != '0.0':
e_distance_tmp = euclidean_distance(face_feature_list[k],
face_feature_exist[i])
current_distance_list.append(e_distance_tmp)
else:
# 空數(shù)據(jù) person_X
current_distance_list.append(999999999)
# 尋找出最小的歐式距離匹配
min_dis = min(current_distance_list)
similar_person_num = current_distance_list.index(min_dis)
if min_dis < 0.4:
face_name_list[k] = face_name_exist[similar_person_num]
end_time = time.time()
fps_rec = int(1.0 / round((end_time - start_time), 3))
for k, d in enumerate(faces):
# 計(jì)算矩形框大小 / Compute the size of rectangle box
height = (d.bottom() - d.top())
width = (d.right() - d.left())
hh = int(height / 2)
ww = int(width / 2)
rect = (d.left(), d.top(), d.right(), d.bottom())
image = drawRectBox(image, rect, face_name_list[k])
cv2.imshow('Stream', image)
c = cv2.waitKey(0) & 0xff
????????除了以上介紹的人臉匹配流程,這部分代碼中還給出了識(shí)別出人臉后的標(biāo)記過(guò)程。如果檢測(cè)出人臉,則根據(jù)人臉的坐標(biāo)未知繪制矩形框,根據(jù)識(shí)別結(jié)果在矩形框上方添加識(shí)別結(jié)果的文字,最后顯示標(biāo)記圖像在窗口中。其運(yùn)行結(jié)果如下圖所示:
????????有了以上實(shí)現(xiàn)的基礎(chǔ),我們可以把這部分功能進(jìn)行改進(jìn),添加進(jìn)UI界面中方便我們選擇圖像和管理人臉庫(kù)。打開(kāi)QtDesigner軟件,拖動(dòng)以下控件至主窗口中,調(diào)整界面樣式和控件放置,人臉識(shí)別系統(tǒng)的界面設(shè)計(jì)如下圖所示:
????????控件界面部分設(shè)計(jì)好,接下來(lái)利用PyUIC工具將.ui文件轉(zhuǎn)化為.py代碼文件,通過(guò)調(diào)用界面部分的代碼同時(shí)加入對(duì)應(yīng)的邏輯處理代碼。博主對(duì)其中的UI功能進(jìn)行了詳細(xì)測(cè)試,最終開(kāi)發(fā)出一版流暢得到清新界面,就是博文演示部分的展示,完整的UI界面、測(cè)試圖片視頻、代碼文件,以及Python離線依賴包(方便安裝運(yùn)行,也可自行配置環(huán)境),均已打包上傳,感興趣的朋友可見(jiàn)參考文章或參考視頻。
下載鏈接
????????若您想獲得博文中涉及的實(shí)現(xiàn)完整全部程序文件(包括測(cè)試圖片、視頻,py, UI文件等,如下圖),這里已打包上傳至博主的面包多平臺(tái)和CSDN下載資源。本資源已上傳至面包多網(wǎng)站和CSDN下載資源頻道,可見(jiàn)參考文章或視頻,已將所有涉及的文件同時(shí)打包到里面,點(diǎn)擊即可運(yùn)行,完整文件截圖如下:
????在文件夾下的資源顯示如下,其中包含了Python的離線依賴包,讀者可在正確安裝Anaconda和Pycharm軟件后,點(diǎn)擊bat文件進(jìn)行安裝,詳細(xì)演示也可見(jiàn)本人B站視頻。
注意:本資源已經(jīng)過(guò)調(diào)試通過(guò),下載后可通過(guò)Pycharm運(yùn)行;運(yùn)行界面的主程序?yàn)?font color="red">runMain.py,測(cè)試圖片腳本可運(yùn)行testFaceDemo.py,測(cè)試人臉特征提取可運(yùn)行testGetFeatures.py。為確保程序順利運(yùn)行,請(qǐng)配置Python版本:3.8,請(qǐng)勿使用其他版本,詳見(jiàn)requirements.txt文件,如下:???
blurhash == 1.1.4
boost == 0.1
certifi == 2021.10.8
charset-normalizer == 2.0.12
cmake == 3.22.2
decorator == 5.1.1
dlib == 19.19.0
greenlet == 1.1.2
idna == 3.3
joblib == 1.1.0
Mastodon.py == 1.5.1
numpy == 1.19.5
opencv-python == 4.1.2.30
pandas == 1.2.5
Pillow == 8.3.0
pyqt5 == 5.15.5
python-dateutil == 2.8.2
python-magic == 0.4.25
pytz == 2021.3
requests == 2.27.1
scikit-learn == 1.0.2
scipy == 1.8.0
six == 1.16.0
SQLAlchemy == 1.4.31
threadpoolctl == 3.1.0
urllib3 == 1.26.8
wincertstore == 0.2
參考博客文章:https://www.cnblogs.com/sixuwuxian/p/16161143.html
參考視頻演示:https://www.bilibili.com/video/BV1XB4y1U73S/
結(jié)束語(yǔ)
????????由于博主能力有限,博文中提及的方法即使經(jīng)過(guò)試驗(yàn),也難免會(huì)有疏漏之處。希望您能熱心指出其中的錯(cuò)誤,以便下次修改時(shí)能以一個(gè)更完美更嚴(yán)謹(jǐn)?shù)臉幼樱尸F(xiàn)在大家面前。同時(shí)如果有更好的實(shí)現(xiàn)方法也請(qǐng)您不吝賜教。
-
徐怡彤, 王梅霞, 張培培. Dlib人臉識(shí)別在教師考勤中的應(yīng)用[J]. 電腦編程技巧與維護(hù), 2022(2):3. ??
-
Kazemi V, Sullivan J. One millisecond face alignment with an ensemble of regression trees[C]//Proceedings of the IEEE conference on computer vision and pattern recognition. 2014: 1867-1874. ??文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-808259.html
-
He K, Zhang X, Ren S, et al. Deep residual learning for image recognition[C]//Proceedings of the IEEE conference on computer vision and pattern recognition. 2016: 770-778. ??文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-808259.html
到了這里,關(guān)于基于深度學(xué)習(xí)的人臉識(shí)別與管理系統(tǒng)(UI界面增強(qiáng)版,Python代碼)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!