張杜娟,丁莉,吳玉蓮
(西安醫(yī)學(xué)院衛(wèi)生管理學(xué)院,陜西西安 710021)
人臉識別是利用人臉視覺特征信息的分析比較結(jié)果進(jìn)行身份認(rèn)證的一種生物特征識別技術(shù)[1],是計算機(jī)視覺中圖像識別技術(shù)的應(yīng)用典范,也是近幾年人工智能的熱點之一,機(jī)器對人臉的識別率比人眼識別率高。2015 年Google 研究人員訓(xùn)練了一個深度神經(jīng)網(wǎng)絡(luò)進(jìn)行人臉識別,在LFW 數(shù)據(jù)測試集上的精確度為99.63%,而目前人類眼睛的識別率約為95%。通過人臉進(jìn)行身份確定或身份查找,可以避免證件、磁卡、IC 卡和密碼等傳統(tǒng)身份鑒別技術(shù)缺陷。人臉識別可以大大減少人工的工作量,目前在金融、安防、車站、無人商店、公安系統(tǒng)等領(lǐng)域都有廣泛的應(yīng)用[2]。
該文詳細(xì)論述了深度學(xué)習(xí)及基于卷積神經(jīng)網(wǎng)絡(luò)的人臉識別算法,以此為基礎(chǔ)采用Python+Dlib 實現(xiàn)人臉檢測和識別。
人臉識別包括人臉檢測、特征點提取、人臉校準(zhǔn)、人臉比對等過程[3]。通過對視頻流中每幀人臉圖像或靜態(tài)圖片中人臉進(jìn)行檢測、跟蹤和分析,按照卷積神經(jīng)網(wǎng)絡(luò)二分類原理對圖片進(jìn)行卷積和池化,采用softmax 激活函數(shù)計算并判斷人臉分類,從而檢測出圖片中是否包含一張或多張人臉,根據(jù)神經(jīng)網(wǎng)絡(luò)回歸問題定位算法對已檢測到的人臉采用矩形框進(jìn)行位置標(biāo)定;對圖片進(jìn)行灰度化,提取人臉特征,對得到的特征點進(jìn)行選取,利用仿射變換進(jìn)行人臉校正;將特征數(shù)值化,按照神經(jīng)網(wǎng)絡(luò)中相似度計算方法對校準(zhǔn)后的人臉與自身的訓(xùn)練數(shù)據(jù)庫中的人臉進(jìn)行比對,判斷被檢測的人臉是否能被識別。其算法流程圖如圖1 所示。

圖1 人臉識別算法流程
深度學(xué)習(xí)是機(jī)器學(xué)習(xí)的一個分支,基于對大量數(shù)據(jù)集的訓(xùn)練,學(xué)習(xí)表征這些數(shù)據(jù)的最佳特征。基于卷積神經(jīng)網(wǎng)絡(luò)(CNN)的深度學(xué)習(xí)方法是一類包含卷積計算且具有深度結(jié)構(gòu)的前饋神經(jīng)網(wǎng)絡(luò)算法,已廣泛應(yīng)用在人臉特征提取及識別方面[4]。該原理是對人臉圖像進(jìn)行裁剪后輸入到輸入層,輸出與對應(yīng)剪裁矩陣大小相同的二維向量;在卷積層輸入數(shù)據(jù),用卷積核作為一個滑動窗口在圖像矩陣上滑動,將與卷積核相似的特征放大,卷積核提取向量的特征,然后池化降低卷積層輸出特征向量規(guī)模,經(jīng)過若干個卷積和池化層后,最終通過全連接層輸出人臉的特征,實現(xiàn)人臉比對[5]。
OpenCV 庫是跨平臺的計算機(jī)視覺庫,其自帶的人臉檢測分類器基于HAAR 算法,通過對創(chuàng)建灰度圖像直方圖均衡化,采用HaarDetectObjects 針對級聯(lián)分類器檢測人臉標(biāo)定矩形區(qū)域,收集所需數(shù)據(jù)并訓(xùn)練分類器[6]。通過實驗發(fā)現(xiàn),使用分類器文件有漏檢和誤檢現(xiàn)象,因此該研究使用Dlib 庫進(jìn)行人臉檢測和識別,調(diào)用OpenCV 庫的圖像處理函數(shù)對圖片進(jìn)行圖像化處理。
Dlib 庫包含大量機(jī)器學(xué)習(xí)算法和圖形模型算法并支持?jǐn)?shù)值算法[7],使用該庫其實是調(diào)用對應(yīng)的神經(jīng)元網(wǎng)絡(luò)結(jié)構(gòu),再把預(yù)先訓(xùn)練好的參數(shù)傳給該網(wǎng)絡(luò)。它包括人臉檢測器、已訓(xùn)練好的人臉關(guān)鍵點檢測器和人臉識別模型,提供Python 接口,方便調(diào)用。使用Dlib 深度學(xué)習(xí)人臉識別技術(shù)構(gòu)建,在戶外臉部檢測數(shù)據(jù)庫準(zhǔn)確率為99.38%。
使用Dlib 庫實現(xiàn)人臉識別前期環(huán)境配置較多,相對繁瑣,但安裝所需軟件及庫是必備的,要遵循配置次序,開發(fā)環(huán)境配置如圖2 所示。

圖2 開發(fā)環(huán)境配置
Dlib 庫的安裝依賴于編譯環(huán)境CMake 和Boost庫。其使用的庫需編譯成靜態(tài)庫,要預(yù)安裝CMake,將它的bin 路徑配置到系統(tǒng)環(huán)境變量并測試安裝正確性。Boost 庫可以提高開發(fā)效率,運行bootstrap.bat會生成 三個文 件:b2.exe、bjam.exe、project-config.jam,在cmd 中當(dāng)前目錄運行并編譯后生成bin.v2 和stage 子目錄,將已安裝完成的boost 文件添加到環(huán)境變量BOOST_LIBRARYDIR 和BOOST_ROOT 中[8]。
安裝Dlib 前,先在Python37Libsite-packages 下安裝wheel,便于Python 模塊安裝。在cmd 中將當(dāng)前路徑定位到dlib 目錄下,執(zhí)行:pip install dlib 進(jìn)行安裝,使用pip list 在列表中查看是否成功安裝。采用Dlib 做人臉識別,所需其他庫可執(zhí)行pip install+庫名稱安裝在如上目錄。
人臉檢測是人臉識別的預(yù)處理,為了能在復(fù)雜場景中檢測到是否有人臉,將人臉圖像的位置和區(qū)域準(zhǔn)確標(biāo)定出來,在人臉識別時必須首先進(jìn)行人臉檢測。這一過程首先進(jìn)行圖像輸入掃描,從靜態(tài)圖片或動態(tài)視頻每幀圖像中檢測人臉,然后實施人臉判別,如果查找到人臉,對人臉?biāo)趨^(qū)域進(jìn)行全局檢測,按輸入的圖像信息標(biāo)定出所有人臉的位置,輸出人臉框坐標(biāo)[9]。
該文使用基于卷積神經(jīng)網(wǎng)絡(luò)的人臉檢測原理,在進(jìn)行人臉檢測時,通過調(diào)用Dlib 庫中人臉識別庫face_recognition 和圖像處理庫opencv-python,利用Dlib庫正向人臉檢測器dlib.get_frontal_face_detector()來實現(xiàn)。face_detector()是基于HOG(方向梯度直方圖)+回歸樹的方法,對顏色空間歸一化,劃分檢測窗口成大小相同的細(xì)胞單元,利用梯度信息反映圖像目標(biāo)的邊緣信息并通過局部梯度的大小將圖像局部的外觀和形狀特征化,結(jié)合了線性分類器、圖像金字塔和滑動窗口檢測方案[10]。采用Dlib 中enumerate(faces)函數(shù)查找并計算圖片中的人臉數(shù)目,通過循環(huán)算法,遍歷所有人臉并標(biāo)定人臉區(qū)域、獲取矩形框的坐標(biāo)并輸出(如圖3)。

圖3 人臉檢測結(jié)果
為了對檢測到的人臉圖像獲取更多信息,需要進(jìn)行特征點定位。人臉特征點定位是計算機(jī)對人臉圖像分析的一種技術(shù),通過定位可獲取人臉面部外輪廓邊界點、眉毛、眼睛、鼻尖、嘴角等部位特征點,可以精確指明人臉位置。利用Dlib 庫訓(xùn)練好的人臉關(guān)鍵點檢測器模型進(jìn)行68 特征點標(biāo)定并存入各點坐標(biāo),利用OpenCV 進(jìn)行圖像化處理,采用cv2.circle()函數(shù)在人臉上畫出68 個點,cv2.putText()函數(shù)標(biāo)出數(shù)字序號1-68。遍歷人臉標(biāo)定點坐標(biāo)前,將讀入的圖片加載為數(shù)組后轉(zhuǎn)化為灰度圖片,在OpenCV 中圖像是按反序BGR 顏色通道存儲,與訓(xùn)練集采用的傳統(tǒng)RGB 顏色通道不同,要通過平均法實施轉(zhuǎn)化,使同一個像素位置的三個通道的值都相等[11],采用cv2.cvtColor(pic,cv2.COLOR_RGB2GRAY)實現(xiàn)顏色空間的轉(zhuǎn)換。每張靜態(tài)人臉圖片和視頻中每幀圖片都能標(biāo)記出68 個特征點[12],如圖4 所示。

圖4 靜態(tài)和動態(tài)人臉檢測及特征點定位
圖片中的人臉可能存在多種姿態(tài),如抬頭、正臉、側(cè)臉等,要提取到正確的人臉特征,需要對人臉進(jìn)行對齊操作,擺正人臉,使其處于圖像中央,盡量消除誤差,輸出的人臉特征更具可比性,提升比對的精度和準(zhǔn)確率,減小比對時計算的壓力。通常以標(biāo)定的68 個特征點為基準(zhǔn),選取部分特征點,通過仿射變換矩陣實施人臉校正。這種校正方式對傾斜人臉信息提高有一定幫助,側(cè)臉因缺少部分臉部信息不能實現(xiàn)正面化[13]。
進(jìn)行人臉校正前,根據(jù)68 個特征點標(biāo)定信息,可以定位出校正所用到的五個關(guān)鍵點(左眼,右眼,鼻尖,嘴的左角,嘴的右角)為(36,45,30,48,54)[14],以此為基礎(chǔ)計算出偏離角度和中心點坐標(biāo),通過仿射變換函數(shù)進(jìn)行角度矯正,不斷迭代直到算法收斂。圖像的仿射變換是通過一系列原子變換復(fù)合來實現(xiàn),它是從二維坐標(biāo)到二維坐標(biāo)之間的線性變化且保持了圖形的“平直性”和“平行性”。使用getRotationMatrix2D(center,angle,scale)函數(shù)獲得變換矩陣M,center 表示旋轉(zhuǎn)的中心點,angle 表示旋轉(zhuǎn)角度,scale 表示縮放因子,獲得的矩陣如公式(1):
其中,α=scale×cos(angle),β=scale×sin(angle),(center.x,center.y)表示旋轉(zhuǎn)軸心。進(jìn)行仿射變換算法思路:首先,計算參數(shù),然后,進(jìn)行仿射矩陣計算,最后,以此仿射矩陣為參數(shù),采用warpAffine()函數(shù)進(jìn)行仿射變換。實現(xiàn)效果如圖5 所示。

圖5 人臉校準(zhǔn)
將矯正后的人臉?biāo)腿肴四樂诸愖R別網(wǎng)絡(luò)中,提取分類網(wǎng)絡(luò)中的某個層作為人臉的特征層,得到人臉特征。通過卷積神經(jīng)網(wǎng)絡(luò)進(jìn)行量化和計算特征產(chǎn)生128D 特征向量,用數(shù)字化代表每張人臉。每張人臉圖片是由一定的像素構(gòu)成,每個像素具有R、G、B三個通道,每個像素取值范圍是0~255 字節(jié),累計矩陣字節(jié)數(shù)作為輸入數(shù)據(jù),在深度學(xué)習(xí)中是生成一個近似函數(shù)f*(x),把輸入數(shù)據(jù)轉(zhuǎn)化為可用作特征分類的多個數(shù)值組成的向量特征值。
該文使用Dlib 已訓(xùn)練好的深度殘差網(wǎng)絡(luò)(ResNet)模型接口dlib_face_recognition_resnet_model_v1.dat,它是人臉特征提取的分類網(wǎng)絡(luò),利用它可以將人臉圖像轉(zhuǎn)換為128D 特征向量,通過return_128d_features()返回值列表。這樣使相似人臉比較相近,不相似人臉比較遠(yuǎn)[15]。
一個人不同時期的照片是有差異的,裁截的人臉做檢測有可能降低識別率,要想得出可靠的特征向量,需計算128D 特征向量的平均值(如式(2)),形成此人的平均臉方便辨識,以排除部分照片將人臉某部分特征放大或縮小,將結(jié)果保存為M行128 列的CSV 文件。
其中,xi表示第i個人臉的一維向量,M表示人臉采樣數(shù),φ表示平均臉向量。
人臉識別是通過將待識別人臉的特征和測試庫中人臉特征做相似度比對,根據(jù)人臉相似程度進(jìn)行身份信息判斷。128D 特征向量提取后,根據(jù)待識別人臉的特征矩陣和數(shù)據(jù)訓(xùn)練庫中人臉特征矩陣計算歐式距離,當(dāng)距離小于指定閾值,其特征相似性較高,則認(rèn)為是同一人;當(dāng)距離大于指定閾值,其特征相似性較低,則認(rèn)為不是同一人,通過多次迭代,若結(jié)果始終不是同一人,則認(rèn)為在數(shù)據(jù)庫中找不到此人。一般來說,歐氏距離越大,兩個特征值相似度越低,屬于同一個人的可能性越小。當(dāng)比對身份為1∶N時,N(N表示數(shù)據(jù)庫中的人臉數(shù))越大表示數(shù)據(jù)庫中特征向量越多,人臉識別效率越低。
在識別人臉目標(biāo)時,需要進(jìn)行集合內(nèi)特征比對,采用歐氏距離計算特征向量間的相似性,設(shè)兩個向量分別為x、y,n=128,其歐氏距離計算公式[16]如下:
Dlib 庫中采用face_recognition.face_distance(tpk_encodings,img_test_encoding)作為接口計算歐氏距離,采用face_recognition.compare_faces()人臉匹配函數(shù)對待測圖片和測試庫中圖片編碼列表進(jìn)行比對,該函數(shù)根據(jù)閾值確認(rèn)是否為同一人臉,默認(rèn)判別閾值為0.6,閾值過高,人臉比對通過率低,經(jīng)反復(fù)測試此處閾值修改為0.4。主要算法思想:導(dǎo)入face_recognition,使用FOR 循環(huán)加載同一測試庫文件夾下所有圖片及待測圖片,將所有加載圖片像素轉(zhuǎn)化為人臉面部編碼,采用循環(huán)算法計算歐氏距離并比對待測圖片與測試庫中所有圖片的相似性,用邏輯值表達(dá)結(jié)果。關(guān)鍵代碼:
其中,face_distances 表示比較的面部的歐氏距離,results 是一個True/False 數(shù)組,表示待測圖像的面部與已知測試庫數(shù)組中每個人的匹配結(jié)果。結(jié)果發(fā)現(xiàn),待測人臉與第二張圖片中人臉歐氏距離為0.223 201<0.4,即待測圖片與該圖中是同一個人,執(zhí)行結(jié)果如圖6 所示。

圖6 歐氏距離計算及比對結(jié)果
文中提出了采用Python+Dlib 方法進(jìn)行人臉識別,有效克服了OpenCV 的漏檢、誤檢等問題,算法簡便,其優(yōu)勢在于使用開源庫作為Python 接口,對于靜態(tài)圖片、動態(tài)視頻及實時攝像頭視頻均可較好地實現(xiàn)人臉檢測和識別,效率和精度較高。對于側(cè)臉、偏轉(zhuǎn)較大、顏色與環(huán)境較相似的人臉檢測算法及檢測耗時長等問題要做進(jìn)一步研究,以提高檢測效果和檢測效率。