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



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