|
|
星级打分
平均分:NAN 参与人数:0 我的评分:未评
本帖最后由 day270010678 于 2026-1-28 18:22 编辑
很多人碰到侧脸的问题(我说的侧脸不是提取侧脸特征点哈,说的是遮罩的时候,那个侧脸的问题),分析原因
if self.face_type == sample.face_type:
# 直接resize
img_np = cv2.resize(img_np, (self.resolution, self.resolution))
mask = cv2.resize(mask, (self.resolution, self.resolution))
else:
# 使用landmarks变换
mat = LandmarksProcessor.get_transform_mat(sample.landmarks, self.resolution, self.face_type)
img_np = cv2.warpAffine(img_np, mat, (self.resolution, self.resolution))
mask = cv2.warpAffine(mask, mat, (self.resolution, self.resolution))
face_type 只能是 h/mf/f/wf/head,无法区分侧脸角度(例如60度侧脸还是80度侧脸),导致:
侧脸因为face_type不匹配,被强制warpAffine变换
变换矩阵基于landmarks计算,但没考虑姿态角度
极端侧脸可能对齐失败,mask边界错误
结合deepfacelab的实际,想要修改面小一点的话,最佳方法就是加入姿态估计,两种方法
第一中就是使用 Mediapipe Face Mesh,这种缺点就是轻量级姿态估计
import mediapipe as mp
class XSegPoseEstimator:
def __init__(self):
self.face_mesh = mp.solutions.face_mesh.FaceMesh(
max_num_faces=1,
refine_landmarks=True,
min_detection_confidence=0.5
)
def get_face_angle(self, img, landmarks):
"""计算yaw/pitch/roll角度"""
# 使用3D landmarks计算欧拉角
# yaw: 左右转头角度
# pitch: 上下点头角度
# roll: 左右歪头角度
return yaw, pitch, roll
第二种就是在线姿态估计(重量级姿态估计),这种方法最大缺点就是需要训练HRNet与XSeg并行,也就是两种架构
第一步:离线计算姿态角度(一次)
def __init__(self, paths, debug=False, batch_size=1, resolution=256, face_type=None):
# ... 现有代码 ...
# 计算所有样本的姿态角度(只需一次)
self.sample_angles = self.compute_face_angles(samples)
# 根据角度筛选侧脸样本
self.profile_idxs = [i for i, angle in enumerate(self.sample_angles)
if abs(angle) > 30] # 30度以上为侧脸
第二步:动态调整face_type
修改 gen_img_mask 方法:
def gen_img_mask(self, sample, sample_idx):
yaw, _, _ = self.sample_angles[sample_idx]
# 根据角度选择face_type
if abs(yaw) > 60: # 极端侧脸
target_face_type = FaceType.WHOLE_FACE # 使用更大区域
elif abs(yaw) > 30: # 中度侧脸
target_face_type = FaceType.FULL
else: # 正面
target_face_type = self.face_type
# 使用动态face_type进行变换
mat = LandmarksProcessor.get_transform_mat(sample.landmarks, self.resolution, target_face_type)
img_np = cv2.warpAffine(img_np, mat, (self.resolution, self.resolution))
mask = cv2.warpAffine(mask, mat, (self.resolution, self.resolution))
第三步:数据增强
对侧脸样本增加旋转增强:
if abs(yaw) > 30:
# 对侧脸增加小角度旋转,提高泛化能力
angle = np.random.uniform(-10, 10)
M = cv2.getRotationMatrix2D((resolution//2, resolution//2), angle, 1.0)
img_np = cv2.warpAffine(img_np, M, (resolution, resolution))
mask = cv2.warpAffine(mask, M, (resolution, resolution))
如果想大动干戈的重构整个deepfacelab是另外的说法。这些仅仅在不大动干戈的情况下提高侧脸。
|
|