You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何实现人脸对齐与裁剪?基于dlib裁剪后的人脸对齐方法问询

人脸对齐:用dlib从检测到对齐的完整流程

嘿,我太懂这种感觉了——用dlib做基础人脸检测简直手到擒来,但一涉及到人脸对齐就突然懵了,尤其是看到faceswap那种复杂代码的时候,完全不知道从哪下手!其实核心逻辑没那么难,咱们一步步来拆解。

首先得明白:人脸对齐的本质是把不同角度、位置的人脸,通过几何变换映射到一个标准的正脸模板上,这样后续的人脸识别、特征提取或者换脸才能更准确。dlib本身就提供了实现对齐的关键工具——形状预测器,配合OpenCV的变换就能搞定。

第一步:准备工具

你需要先下载dlib官方提供的预训练68点人脸关键点模型(文件名一般是shape_predictor_68_face_landmarks.dat),这个模型能精准定位人脸的眼睛、鼻子、嘴巴等关键部位的坐标。

第二步:完整代码实现

结合你已有的检测代码,我把对齐的步骤整合进去了,直接就能用:

import dlib
import cv2
import numpy as np

# 初始化人脸检测器和形状预测器
face_detector = dlib.get_frontal_face_detector()
# 替换成你的模型文件路径
shape_predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")

def detect_and_align_faces(image):
    # 先检测人脸(就是你原来的代码逻辑)
    detected_faces = face_detector(image, 1)
    aligned_faces = []
    
    for face_rect in detected_faces:
        # 1. 提取当前人脸的68个关键点
        shape = shape_predictor(image, face_rect)
        landmarks = np.array([[p.x, p.y] for p in shape.parts()])
        
        # 2. 选几个关键的点来做对齐(左眼、右眼、鼻尖是核心,加嘴角更稳定)
        src_key_points = landmarks[[36, 45, 30, 48, 54]]  # 对应左眼中心、右眼中心、鼻尖、左嘴角、右嘴角
        
        # 3. 定义标准正脸的模板位置(这里设定的是256x256的人脸尺寸,可按需调整)
        target_size = (256, 256)
        target_key_points = np.array([
            [60, 80],    # 左眼预期位置
            [196, 80],   # 右眼预期位置
            [128, 136],  # 鼻尖预期位置
            [60, 192],   # 左嘴角预期位置
            [196, 192]   # 右嘴角预期位置
        ], dtype=np.float32)
        
        # 4. 计算仿射变换矩阵(用前3个点就够,仿射变换只需要3组对应点)
        transform_matrix = cv2.getAffineTransform(
            src_key_points[:3].astype(np.float32), 
            target_key_points[:3].astype(np.float32)
        )
        
        # 5. 应用变换,得到对齐后的人脸
        aligned_face = cv2.warpAffine(image, transform_matrix, target_size)
        aligned_faces.append(aligned_face)
    
    return aligned_faces

第三步:代码逻辑解释

  • 关键点提取:dlib的形状预测器能精准定位68个关键点,我们挑了最影响人脸姿态的几个,保证对齐后的人脸是正脸姿态。
  • 仿射变换:这是实现对齐的核心,它能把倾斜、偏移的人脸“拉”到我们设定的标准位置,同时保留人脸的形状比例。
  • 灵活性:你可以根据自己的需求调整target_sizetarget_key_points的坐标,比如要更大的人脸就把尺寸调大,或者调整眼睛、鼻子的位置适配特定任务。

为什么faceswap的代码看起来那么复杂?

你提到的faceswap里的复杂逻辑,主要是因为它做了更多的优化:

  • 可能用到了全部68个关键点来做更精细的变换(比如相似变换或者局部变形)
  • 加入了人脸分割、边缘平滑、颜色匹配等预处理步骤,为了让换脸后的效果更自然
  • 针对批量处理、实时性做了工程化优化,所以代码结构更复杂

但如果只是需要基础的人脸对齐,上面的代码完全够用,而且逻辑清晰,容易调试。

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

火山引擎 最新活动