4. 人脸对齐与归一化
任务说明
本案例实现人脸对齐与归一化:给定一张人脸图像及其5个关键点(左眼、右眼、鼻尖、左嘴角、右嘴角),通过仿射变换将人脸旋转到水平标准姿态,并统一裁剪为112×112像素的标准尺寸。该操作是人脸识别流程中特征提取前的必要预处理步骤。
实现方案
采用基于双眼坐标的相似变换(旋转+缩放+平移)完成对齐。核心思路:计算双眼连线与水平方向的夹角作为旋转角,以两眼中心为基准点进行旋转,再按固定比例缩放使两眼间距映射到目标值,最后裁剪出112×112区域。代码使用OpenCV的estimateAffinePartial2D函数,通过源关键点与目标关键点的对应关系直接求解仿射矩阵,避免手动推导旋转矩阵。
代码实现
import cv2
import numpy as np
# 标准人脸模板关键点坐标(112×112)
TEMPLATE_POINTS = np.array([
[38.2946, 51.6963], # 左眼
[73.5318, 51.5014], # 右眼
[56.0252, 71.7366], # 鼻尖
[41.5493, 92.3655], # 左嘴角
[70.7299, 92.2041] # 右嘴角
], dtype=np.float32)
def align_face(image, landmarks):
"""
人脸对齐与归一化
Args:
image: BGR图像 (numpy数组)
landmarks: 5个关键点坐标 [[x,y],...] 顺序与TEMPLATE_POINTS一致
Returns:
aligned: 112×112对齐后图像,若关键点无效返回None
"""
if image is None or landmarks is None:
return None
src_pts = np.array(landmarks, dtype=np.float32).reshape(5, 2)
# 使用部分仿射变换(旋转+缩放+平移)求解变换矩阵
transform_matrix, inliers = cv2.estimateAffinePartial2D(
src_pts, TEMPLATE_POINTS, method=cv2.RANSAC, ransacReprojThreshold=5.0
)
if transform_matrix is None:
return None
# 应用仿射变换并统一尺寸
aligned = cv2.warpAffine(
image, transform_matrix, (112, 112),
flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT, borderValue=(0, 0, 0)
)
return aligned
# 示例:加载图像并定义关键点(以实际检测结果替换)
if __name__ == "__main__":
# 假设已通过检测器获得以下关键点(单位:像素)
sample_landmarks = [
[112.5, 98.3], # 左眼
[168.2, 95.7], # 右眼
[142.0, 138.6], # 鼻尖
[118.4, 176.2], # 左嘴角
[160.8, 174.9] # 右嘴角
]
# 读取图像(请替换为实际路径)
img = cv2.imread("face.jpg")
if img is None:
print("图像读取失败,请检查路径")
else:
result = align_face(img, sample_landmarks)
if result is not None:
cv2.imwrite("aligned_face.jpg", result)
print("对齐完成,输出尺寸:", result.shape)
else:
print("对齐失败:关键点无效或变换求解失败")
关键说明
TEMPLATE_POINTS采用人脸识别领域广泛使用的标准模板坐标(源自公开数据集统计),保证不同输入人脸对齐后具有一致的几何分布。代码中estimateAffinePartial2D仅估计4自由度(旋转、缩放、平移),不包含剪切变形,符合人脸刚性对齐需求。RANSAC参数用于剔除异常关键点,若关键点质量可靠可改用cv2.LMEDS或直接使用最小二乘求解。
落地与验证
依赖安装:pip install opencv-python numpy
运行方式:将代码保存为face_align.py,准备一张包含正脸人脸的图像命名为face.jpg,将sample_landmarks替换为实际检测到的关键点坐标,执行python face_align.py。
验证方法:观察输出的aligned_face.jpg是否满足:①图像尺寸为112×112;②双眼处于同一水平线(y坐标接近);③人脸居中且尺度统一。可通过在输出图像上叠加模板关键点位置进行定量检查——若对齐正确,两眼中心应落在约(56, 51)附近,鼻尖在(56, 72)附近。