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