使用Python,OpenCV,面部标志进行面部对齐
這一節(jié)延續(xù)面部識(shí)別的主題,關(guān)于面部識(shí)別、面部標(biāo)志識(shí)別、眨眼檢測(cè)、疲勞駕駛檢測(cè)、視頻流中的面部標(biāo)志識(shí)別,可以看我之前的博客。
這篇博客將探索面部對(duì)齊;面部對(duì)齊可以使得人臉檢測(cè)模型更加的準(zhǔn)確;
使用Python、OpenCV、面部標(biāo)志進(jìn)行面部對(duì)齊(Face Alignment)
面部對(duì)齊目標(biāo):
給定一組面部標(biāo)志(輸入坐標(biāo)),就可以將圖像變形并轉(zhuǎn)換為輸出坐標(biāo)空間。在此輸出坐標(biāo)空間中,整個(gè)數(shù)據(jù)集的所有臉部應(yīng)
- 在圖像中居中;
- 旋轉(zhuǎn)以使眼睛位于水平線上;
- 經(jīng)過一定的縮放比例,以使面部的大小大致相同;
下邊的gif 效果更直觀一些,用了我喜歡的美照:
圖像中有一張人臉的可以對(duì)齊,多張面孔的也可以分別對(duì)齊;
使用python制作動(dòng)圖可參考我的另倆篇博客:
-
給人物帶一個(gè)墨鏡🕶的動(dòng)圖
-
使用OpenCV、Python制作動(dòng)圖
一、面部對(duì)齊步驟
大致分倆步
- 識(shí)別數(shù)字圖像中人臉的幾何結(jié)構(gòu);
- 嘗試基于平移、縮放、旋轉(zhuǎn)獲得人臉的規(guī)范對(duì)齊;
細(xì)致分10步:
- 首先使用人臉識(shí)別,進(jìn)行面部標(biāo)志檢測(cè);
- 提取倆只眼睛的坐標(biāo);
- 計(jì)算每只眼睛👀的中心及眼睛質(zhì)心的角度(該角度是對(duì)齊圖像的關(guān)鍵部分,使我們能夠校正旋轉(zhuǎn))
- 根據(jù)【反正切線獲取眼睛之間的旋轉(zhuǎn)角度】
- 根據(jù)左眼的坐標(biāo)計(jì)算期望的右眼的坐標(biāo)
- 通過獲取當(dāng)前圖像中眼睛的距離與所需圖像中眼睛的距離之比來獲得縮放的比例(計(jì)算縮放比例因子)
- 計(jì)算倆只眼睛👀連線的中心點(diǎn)(鼻子上方的中心點(diǎn),用于旋轉(zhuǎn)臉部的點(diǎn))
- 計(jì)算用于旋轉(zhuǎn)及縮放臉部的旋轉(zhuǎn)矩陣【中心點(diǎn),角度,比例】
M = cv2.getRotationMatrix2D(eyesCenter, angle, scale) - 更新矩陣的平移分量(translation component),以使得放射變換后人臉仍在圖像中
- 應(yīng)用仿射變換(affine transformation)對(duì)齊面部
二、面部對(duì)齊方式
人臉對(duì)齊有多種方式:
- 嘗試強(qiáng)加(預(yù)定義的)3D模型,然后將變換應(yīng)用于輸入圖像,以使輸入圖片上的面部標(biāo)志與3D模型上的標(biāo)志匹配;
- 其他更簡單的方法(比如本博客文章中討論的方法)僅依賴于面部標(biāo)志本身(特別是眼睛區(qū)域)來獲取臉部的標(biāo)準(zhǔn)化旋轉(zhuǎn),平移和縮放表示。
使用歸一化的原因是許多面部識(shí)別算法(包括Eigenfaces,用于面部識(shí)別的LBP,Fisherfaces和深度學(xué)習(xí)/度量方法)都可以在嘗試識(shí)別面部之前從面部對(duì)齊中受益。
面部對(duì)齊可以看作是“數(shù)據(jù)標(biāo)準(zhǔn)化”的一種形式。就像在訓(xùn)練機(jī)器學(xué)習(xí)模型時(shí)通過對(duì)一組特征向量進(jìn)行零中心化或縮放到單位范數(shù)進(jìn)行歸一化一樣,在訓(xùn)練人臉識(shí)別器之前對(duì)齊數(shù)據(jù)集中的人臉是很普遍的操作;
三、面部對(duì)齊原理
使用OpenCV,Python和面部標(biāo)記對(duì)齊面部。核心是使用仿射變換(affine transformation)對(duì)齊面部;
note:仿射變換用于旋轉(zhuǎn),縮放,平移等。方法均封裝在cv2.warpAffine中,最主要的是創(chuàng)建旋轉(zhuǎn)矩陣M;
output = cv2.warpAffine(image, M, (w, h),flags=cv2.INTER_CUBIC)
- image:臉部圖片
- M:平移、旋轉(zhuǎn)、縮放矩陣
- (w, h):期待的臉部寬度、高度
- flags:可選,用于變形的插值算法,在這種情況下為INTER_CUBIC
四、源碼
# python align_faces.py --shape-predictor shape_predictor_68_face_landmarks.dat --image images/example_03.jpg
# 導(dǎo)入必要的包
from imutils.face_utils import FaceAligner
from imutils.face_utils import rect_to_bb
import argparse
import imutils
import dlib
import cv2# 構(gòu)建參數(shù)解析器和命令行參數(shù)
# --shape-predictor: 必需 dlbi面部標(biāo)志檢測(cè)器
# --image:包含面部的圖片
ap = argparse.ArgumentParser()
ap.add_argument("-p", "--shape-predictor", required=True,help="path to facial landmark predictor")
ap.add_argument("-i", "--image", required=True,help="path to input image")
args = vars(ap.parse_args())# 初始化基于HOG的dlib面部檢測(cè)器、面部標(biāo)志檢測(cè)器(dlib預(yù)先訓(xùn)練好的)
# 通過fa來使用面部對(duì)齊類,并給定256像素的照片寬度
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(args["shape_predictor"])
fa = FaceAligner(predictor, desiredFaceWidth=256)# 加載輸入圖像、保持寬高比的縮放原始圖像、轉(zhuǎn)為灰度圖
image = cv2.imread(args["image"])
image = imutils.resize(image, width=600)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 展示初始圖像,用灰度圖檢測(cè)人臉面部,該方法返回人臉的列表
cv2.imshow("Input", image)
rects = detector(gray, 2)# 遍歷所有人臉,對(duì)齊,并顯示原圖及對(duì)齊后的圖像
for rect in rects:# 提取原始圖的ROI區(qū)域,使用面部標(biāo)志對(duì)齊面部# 轉(zhuǎn)換每個(gè)邊界框?yàn)?#xff08;x,y,w,h)格式(x, y, w, h) = rect_to_bb(rect)# 保持寬高比的縮放矩形框到256像素的寬度faceOrig = imutils.resize(image[y:y + h, x:x + w], width=256)# 對(duì)齊圖像,指定圖像,灰度圖像和矩形faceAligned = fa.align(image, gray, rect)# 展示圖像cv2.imshow("Original", faceOrig)cv2.imshow("Aligned", faceAligned)cv2.waitKey(0)
總結(jié)
以上是生活随笔為你收集整理的使用Python,OpenCV,面部标志进行面部对齐的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用Python、OpenCVImage
- 下一篇: 使用Python,dlib中新型、更快、