賴奕然 林澤浩 伍紹鋒 唐一星



摘要:自2006年開始,深度學(xué)習(xí)算法開始出現(xiàn),人工智能技術(shù)獲得飛速發(fā)展,人工智能的春天悄然來臨,一時間各大深度學(xué)習(xí)平臺宛如雨后春筍般涌現(xiàn),由百度開發(fā)的PaddlePaddle深度學(xué)習(xí)平臺就是其中的佼佼者。為了實現(xiàn)給人像實時添加趣味貼圖的功能,此項目通過使用PaddlePaddle框架的預(yù)訓(xùn)練集PaddleHub來提取圖像的關(guān)鍵點數(shù)據(jù),再使用PaddlePaddle庫、OpenCV庫和Python語言得到的關(guān)鍵點分類、選擇,最后與經(jīng)過預(yù)處理的貼紙匹配,即可得到貼紙人臉趣味圖像。實驗結(jié)果表明:本方法可以很好地對人臉圖像進行識別并將貼圖貼至指定位置,具有極高的準確率。
關(guān)鍵詞:人工智能;深度學(xué)習(xí);PaddlePaddle;人臉識別;圖像識別
中圖分類號:TP391? ? ? 文獻標(biāo)識碼:A
文章編號:1009-3044(2022)25-0073-03
開放科學(xué)(資源服務(wù)) 標(biāo)識碼(OSID) :
1 概述
圖像識別是人工智能的一個重要領(lǐng)域,其目的是讓計算機代替人類去處理大量的視覺信息。隨著時代的發(fā)展,人類自身識別能力已經(jīng)滿足不了需求,需要計算機的圖像識別技術(shù)幫助實現(xiàn)一些人類無法完成的工作[1]。
本項目基于PaddlePaddle平臺,通過調(diào)用 PaddleHub 的接口實現(xiàn)人臉邊框的檢測,為了方便使用,首先對檢測到的人臉圖像關(guān)鍵點進行分類,從分類好的關(guān)鍵點中取出左眉毛最左的點和右眉毛最右的點來計算角度,根據(jù)計算得到的角度來把效果貼紙旋轉(zhuǎn)至與人臉圖像匹配的角度,最后將參考點與人臉對應(yīng)的一個點進行融合得到最終結(jié)果。
2 技術(shù)介紹與主要流程
2.1 技術(shù)介紹
本項目采用深度學(xué)習(xí)框架飛槳(PaddlePaddle) 進行項目實現(xiàn)。百度從2012年開始研發(fā)具備完全自主知識產(chǎn)權(quán)的深度學(xué)習(xí)框架飛槳,并建成了國內(nèi)唯一的集深度學(xué)習(xí)訓(xùn)練和預(yù)測框架、模型庫、工具組件等為一體的開源深度學(xué)習(xí)平臺[2]。同時也是國內(nèi)唯一功能完備的端到端開源深度學(xué)習(xí)平臺,擁有兼顧靈活性和高性能的開發(fā)機制、工業(yè)級應(yīng)用效果的模型、超大規(guī)模并行深度學(xué)習(xí)能力、推理引擎一體化設(shè)計以及系統(tǒng)化服務(wù)支持的五大優(yōu)勢[3]。
PaddleHub是飛槳生態(tài)下的預(yù)訓(xùn)練模型的管理工具,PaddleHub作為模型管理和遷移學(xué)習(xí)工具,采用了飛槳領(lǐng)先的核心框架,精選效果優(yōu)秀的算法快速地實現(xiàn)模型的預(yù)測、升級等功能。到目前為止,PaddleHub的預(yù)訓(xùn)練模型覆蓋了用于圖像分類、圖像生成、關(guān)鍵點檢測等主流模型[4]。
開源計算機視覺庫(OpenCV:Open Source Computer Vision Library)實現(xiàn)了計算機視覺相關(guān)的許多算法,同時也實現(xiàn)了圖像處理很多常見的通用算法。它輕量級而且高效——由一系列 C 函數(shù)和少量 C++ 類構(gòu)成,同時提供了Python、Ruby、Matlab等語言的接口,實現(xiàn)了圖像處理和計算機視覺方面的很多通用算法[5-6]。
功能框架圖如圖1所示。
2.2 具體步驟
2.2.1 獲取圖像和圖片預(yù)處理
通過Python語言獲取需要檢測的目標(biāo)圖像。再使用OpenCV庫,對圖像進行預(yù)處理,例如顏色通道轉(zhuǎn)換、切片、分離顏色通道,中值濾波處理等操作。
2.2.2 檢測人臉并疊加目標(biāo)貼紙
接下來是人臉關(guān)鍵點檢測,它在人臉識別和分析領(lǐng)域中是十分關(guān)鍵的一步,也是絕大部分人臉相關(guān)問題的前提和突破口。
導(dǎo)入PaddleHub模型庫中的face_landmark_localization模型和ultra_light_fast_generic_face_detector_1mb_320模型進行圖像的人臉檢測,返回人臉云點陣圖和人臉面框識別結(jié)果。人臉云點陣圖如圖2所示。
再使用OpenCV庫,將目標(biāo)貼紙圖像導(dǎo)入,并把人臉云點陣圖區(qū)分為幾個部分,比如鼻、眼睛、嘴巴、額頭等,以便于后續(xù)的位置計算。
2.2.3 旋轉(zhuǎn)貼紙
確定好要放置的人臉圖像,計算兩點之間的角度數(shù)據(jù)。通過計算兩標(biāo)記點的XY軸的差值,再用角度ATAN函數(shù)計算兩點之間的角度,以下計算兩點之間角度函數(shù)以方便后續(xù)計算參考點的位置。確定了位置數(shù)據(jù)后,將貼紙圖像進行一定角度的旋轉(zhuǎn),并返回旋轉(zhuǎn)圖像和相應(yīng)的旋轉(zhuǎn)矩陣。
2.2.4 貼紙位置
根據(jù)貼紙上一個點作為參考點,通過計算兩眼標(biāo)記的中心點,確定眼鏡照片的中心點。為了計算兩眼中間點之間的長度,將兩眼坐標(biāo)帶入求范數(shù)函數(shù)(np.Linalg.norm) ,求出兩眼之間的長度,再用旋轉(zhuǎn)矩陣計算旋轉(zhuǎn)之后相對應(yīng)的中心位置。
2.2.5 放置貼紙
根據(jù)人臉的寬度與貼紙圖像進行尺寸的核對以及修改,同時計算修改尺寸之后的圖像相對應(yīng)的位置信息數(shù)據(jù)。調(diào)整旋轉(zhuǎn)矩陣用于之后的平移操作,并將眼鏡圖片和仿射變化矩陣數(shù)組和調(diào)整后的圖片高度及寬度帶入cv2.warpAffine函數(shù)進行仿射變化,最后得到旋轉(zhuǎn)后圖像。
2.2.6 顯示結(jié)果
將獲取到的參考點與人臉需要貼近的部分對應(yīng)的坐標(biāo)點進行融合,導(dǎo)入人臉部圖片和眼鏡圖片,并且設(shè)立數(shù)組來存放眼鏡圖片的各項具體信息。將得到的坐標(biāo)系數(shù)帶入計算眼鏡左邊位置坐標(biāo)的函數(shù)中,將人臉圖片和眼鏡圖片以及由上述操作中得到的位置坐標(biāo)代入將貼紙圖片貼入圖片的函數(shù)中,將人臉圖片導(dǎo)入,從而獲取最終的圖像結(jié)果。效果圖如圖3、圖4所示。
3 功能詳細設(shè)計
3.1 面部關(guān)鍵點和人臉面框識別
主要基于PaddlePaddle框架的PaddleHub模型實現(xiàn)面部關(guān)鍵點點陣圖的繪制和人臉面框的識別。首先導(dǎo)入依賴庫,定義兩個全局變量,Labels 用于表示人臉的每個部分,Colors用于對不同的關(guān)鍵點進行顏色標(biāo)記;通過基于PaddlePaddle開發(fā)的預(yù)訓(xùn)練模型管理工具PaddleHub的face_landmark_localization模型,可以快速提供人臉部的68個關(guān)鍵點(人臉輪廓17個點,左、右眉毛各5個點,左、右眼睛各6個點,鼻子9個點,嘴巴20個點) ,并返回68個人臉關(guān)鍵點數(shù)據(jù),再通過自定義函數(shù)調(diào)用Paddle Hub的ultra_light_fast_generic_face_detector_1mb_320模型,實現(xiàn)人臉編輯框的檢測,返回人臉框左上角的點坐標(biāo)和邊框的寬和高;為了方便使用,將68個人臉關(guān)鍵點分成了人臉的各個部分。部分代碼如下所示:
module=hub.Module(name="face_landmark_localization")
result=module.keypoint_detection(images=[src_img])
face_detector=hub.Module(name="ultra_light_fast_generic_face_detector_1mb_320")
result = face_detector.face_detection(images=[img])
3.2 圖片的預(yù)處理
主要使用OpenCV庫對圖片進行預(yù)處理。第一步是顏色通道的轉(zhuǎn)換,使用cv2.cvtColor將BRG轉(zhuǎn)換成BGRA,以便于后續(xù)圖片處理;然后進行切片處理,以保證貼圖和原圖片尺寸大小一致;接下來是對貼圖的處理。將貼圖的4個顏色通道分離,分為B、G、R、A四個通道,再使用cv2.medianBlur對貼圖的A通道進行中值濾波處理,以盡可能消除椒鹽噪點的影響,并使之作為cv2.bitwise中的掩膜。部分代碼如下所示:
if bg_img.shape[2] == 3:
bg_img = cv2.cvtColor(bg_img, cv2.COLOR_BGR2BGRA)
b, g, r, a = cv2.split(img_to_overlay_t)
mask = cv2.medianBlur(a, 5)
h, w, _ = img_to_overlay_t.shape
roi = bg_img[int(y - h / 2):int(y + h / 2), int(x - w / 2):int(x + w / 2)]
3.3 原圖片和貼圖的疊加
原圖片和貼圖的疊加,主要也是使用OpenCV庫進行操作。第一步先利用cv2.bitwise_and將人臉和貼圖部分提取出來,再使用cv2.add將兩張?zhí)幚磉^后的圖片疊加在一起,最后合成圖片的顏色通道從BGRA轉(zhuǎn)換為BRG。部分代碼如下所示:
img1_bg=cv2.bitwise_and(roi.copy(),roi.copy(),mask=cv2.bitwise_not(mask))
img2_fg=cv2.bitwise_and(img_to_overlay_t,img_to_overlay_t,mask=mask)
bg_img[int(y - h / 2):int(y + h / 2), int(x - w / 2):int(x + w / 2)]= cv2.add(img1_bg, img2_fg)
bg_img = cv2.cvtColor(bg_img, cv2.COLOR_BGRA2BGR)
3.4 計算兩個標(biāo)記點的角度
編寫函數(shù),函數(shù)功能是計算兩個標(biāo)記點的位置和角度,以便對應(yīng)貼紙的放置位置和旋轉(zhuǎn)角度,為后期做貼紙放置做準備。
通過計算兩標(biāo)記點的XY軸的差值,再用角度atan函數(shù)計算兩點之間的角度,以下為計算兩點之間角度函數(shù):
Def angle_between(p1,p2) :
X-diff=p2[0]-p1[0]
Y-diff=p2[0]-p1[0]
Return degrees(atan2(y_diff,x_diff)
3.5 將貼紙圖片貼入圖片中
編寫函數(shù),函數(shù)功能是將貼紙圖片通過函數(shù)進行偏轉(zhuǎn),并貼到相應(yīng)位置;函數(shù)需要的參數(shù)分別是左眼中心點坐標(biāo)(eye_left_center) 和右眼中心點坐標(biāo)(eye_right_center) 以及眼鏡圖片(glasses) 的各項數(shù)據(jù)包括眼鏡圖片的高度(glasses-h) 眼鏡圖片的寬度(glasses-w) 。通過計算兩眼標(biāo)記的中心點,確定眼鏡照片的中心點(glasses-center) 。為了計算兩眼中間點之間的長度,將兩眼坐標(biāo)帶入求范數(shù)函數(shù)(np.Linalg.norm) 求出兩眼之間的長度,在此基礎(chǔ)上乘以2,得到眼鏡照片的大小(glasses-size) 。
現(xiàn)將左右眼中心點坐標(biāo)代入上述計算兩點坐標(biāo)角度的函數(shù)中(angle-between) ,得到兩眼之間的角度(angle) ,再對眼鏡圖片的寬度和高度進行切片操作。用高度和寬度確定眼鏡圖片的中心點(glasses-c) ,再通過getRotationMatrix2D函數(shù)獲得仿射變化矩陣(M) ,最后通過中心點和兩眼之間的角度,得出角度的cos和sin數(shù)值,再通過將圖片的高度和寬度與偏轉(zhuǎn)角度相乘,得出偏轉(zhuǎn)之后的圖片高度(nH) 和寬度(nW) 。
再調(diào)整旋轉(zhuǎn)矩陣用于之后的平移操作,并將眼鏡圖片和仿射變化矩陣數(shù)組,和調(diào)整后的圖片高度及寬度帶入cv2.warpAffine函數(shù)進行仿射變化,得到旋轉(zhuǎn)后的眼鏡圖片(rotated-glasses) ,最后帶入上述融合兩張圖片的函數(shù)圖像函數(shù)(overlay-transparent) 中,并輸入融合后的圖片(image) 。
3.6 計算眼鏡位置坐標(biāo)
編寫函數(shù),函數(shù)功能是計算眼鏡的坐標(biāo)位置,用于計算出貼紙的尺寸和位置,為融合兩張圖片作準備,以下是函數(shù)的代碼:
def get_eye_center_point(landmarks, idx1, idx2):
center_x = (landmarks[idx1][0] + landmarks[idx2][0]) // 2
center_y = (landmarks[idx1][1] + landmarks[idx2][1]) // 2
return (center_x, center_y)
3.7 主函數(shù)
首先是要導(dǎo)入人臉部圖片和眼鏡圖片,并且設(shè)立數(shù)組來存放眼鏡圖片的各項具體信息。將人臉圖片導(dǎo)入。導(dǎo)入預(yù)處理函數(shù)對圖片進行預(yù)處理,并代入result,得出識別標(biāo)記點的函數(shù)如下:
result = module.keypoint_detection(images=[image])
landmarks = result[0]['data'][0]
將得到的坐標(biāo)系數(shù)帶入,計算眼鏡左邊位置坐標(biāo)的函數(shù)(get_eye_enter_point)中:eye_left_point=get_eye_ center_point(landmarks, 36, 39)
eye_right_point = get_eye_center_point(landmarks, 42, 45)
將人臉圖片(image) 、眼鏡圖片(glasses) 以及由上述操作中得到的位置坐標(biāo)代入,將貼紙圖片貼入圖片的函數(shù)中:
image=wear_glasses(image, glasses, eye_left_point, eye_right_point)
最后,將圖片進行優(yōu)化,并最終展示生成的圖片:
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
im = plt.imshow(image, animated=True)
4 總結(jié)與展望
為了確保對目標(biāo)圖形對象的準確識別,本項目在PaddlePaddle平臺提供的運行庫上進行了調(diào)整,提高了識別精準度,并利用了OpenCV基礎(chǔ)庫來完善與實現(xiàn)人臉圖像識別,在經(jīng)過了反復(fù)測試后,擁有了較高的準確率和有效性,但在一些模糊的人臉照片或非全臉照片時,魯棒性有待提高,因此有待于進一步研究,提高其魯棒性。
參考文獻:
[1] 季秀怡.淺析人工智能中的圖像識別技術(shù)[J].電腦知識與技術(shù),2016,12(14):147-148.
[2] 馬艷軍,于佃海,吳甜,等.飛槳:源于產(chǎn)業(yè)實踐的開源深度學(xué)習(xí)平臺[J].數(shù)據(jù)與計算發(fā)展前沿,2019,1(5):105-115.
[3] 袁穎,李論,楊英倉.基于FPN-SE-Capsule網(wǎng)絡(luò)的指紋圖像識別算法[J].工業(yè)控制計算機,2021,34(1):45-47,50.
[4] 唐心雨,陳霜霜,路鵬,等.基于PaddleHub的人臉口罩識別系統(tǒng)[J].海南師范大學(xué)學(xué)報(自然科學(xué)版),2021,34(2):177-184
[5] 羅懷榮.基于Web3D的多平臺溫室監(jiān)測系統(tǒng)設(shè)計[D].重慶:西南大學(xué),2017.
[6] 王浩,許志聞,謝坤,等.基于OpenCV的雙目測距系統(tǒng)[J].吉林大學(xué)學(xué)報(信息科學(xué)版),2014,32(2):188-194.
【通聯(lián)編輯:唐一東】