You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何先对齐再提取:用RetinaFace实现无黑边人脸对齐

解决RetinaFace倾斜人脸对齐后裁剪黑边问题

要实现按眼水平线对齐→提取人脸→无黑边裁剪的流程,需拆分RetinaFace的默认操作逻辑,手动处理检测、对齐和裁剪步骤,避免强制填充黑边:

步骤1:检测人脸关键点与边界框

先获取人脸的边界框和关键点(双眼、鼻子等),为后续对齐提供基础:

import matplotlib.pyplot as plt
import cv2
import numpy as np
from retinaface import RetinaFace

img_path = "/content/drive/img/0036.jpg"
# 检测人脸,返回包含边界框和关键点的字典
detected_faces = RetinaFace.detect_faces(img_path)
# 读取并转换图像格式
img = cv2.imread(img_path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

步骤2:按眼水平线手动对齐人脸

基于双眼连线的角度旋转校正人脸,确保眼水平线水平,同时避免引入黑边:

for face_key in detected_faces:
    face_info = detected_faces[face_key]
    # 获取双眼关键点坐标
    left_eye = face_info['landmarks']['left_eye']
    right_eye = face_info['landmarks']['right_eye']
    
    # 计算双眼连线的倾斜角度
    dx = right_eye[0] - left_eye[0]
    dy = right_eye[1] - left_eye[1]
    angle = np.degrees(np.arctan2(dy, dx))
    
    # 获取原始人脸边界框
    x1, y1, x2, y2 = face_info['facial_area']
    face_width = x2 - x1
    face_height = y2 - y1
    
    # 以人脸中心为旋转轴
    center = ((x1 + x2) // 2, (y1 + y2) // 2)
    # 生成旋转矩阵,保持缩放比例为1
    rotation_matrix = cv2.getRotationMatrix2D(center, angle, 1.0)
    
    # 计算旋转后图像的尺寸,确保人脸完整显示
    cos = np.abs(rotation_matrix[0, 0])
    sin = np.abs(rotation_matrix[0, 1])
    new_width = int((face_height * sin) + (face_width * cos))
    new_height = int((face_height * cos) + (face_width * sin))
    
    # 调整旋转矩阵的平移参数,让人脸居中
    rotation_matrix[0, 2] += (new_width / 2) - center[0]
    rotation_matrix[1, 2] += (new_height / 2) - center[1]
    
    # 对人脸区域进行旋转对齐
    aligned_face = cv2.warpAffine(img, rotation_matrix, (new_width, new_height), flags=cv2.INTER_CUBIC)

步骤3:无黑边裁剪对齐后的人脸

基于旋转后的双眼位置,定位真实人脸区域,裁剪掉多余的空白部分:

# 计算旋转后双眼的坐标
    rotated_left_eye = cv2.transform(np.array([[left_eye]]), rotation_matrix)[0][0]
    rotated_right_eye = cv2.transform(np.array([[right_eye]]), rotation_matrix)[0][0]
    
    # 以双眼为基准,确定裁剪范围(可根据需求调整比例)
    eye_y = (rotated_left_eye[1] + rotated_right_eye[1]) / 2
    crop_top = max(0, int(eye_y - face_height * 0.6))
    crop_bottom = min(new_height, int(eye_y + face_height * 0.8))
    crop_left = max(0, int(min(rotated_left_eye[0], rotated_right_eye[0]) - face_width * 0.2))
    crop_right = min(new_width, int(max(rotated_left_eye[0], rotated_right_eye[0]) + face_width * 0.2))
    
    # 执行裁剪
    cropped_face = aligned_face[crop_top:crop_bottom, crop_left:crop_right]
    
    # 显示结果
    plt.imshow(cropped_face)
    plt.axis('off')
    plt.show()

核心逻辑说明

  • 拆分detect_faces与手动对齐流程,替代extract_faces的默认黑边填充逻辑
  • 旋转时计算适配尺寸,确保人脸区域完整,再通过关键点定位只保留真实人脸像素
  • 对齐基准为双眼连线水平,而非图像垂直边缘,符合姿态校正需求

内容的提问来源于stack exchange,提问作者Victor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 16:16:28