AI美颜-AI瘦脸的N种方法
本文介绍了AI美颜中自动瘦脸的N种可行方案,并给出了相关方案的模型设计与代码验证,分享给有需要的同学们!
注:本文所用原始图像为避免侵权,均为AIGC生成;
瘦脸功能是影楼修图中非常高频的一个功能算法,也是几乎所有人像修图软件或应用必备的一个功能。但是,这个功能通常主要是手动调节的方式出现,如何实现根据用户照片自动或者智能瘦脸效果,是一个非常值得研究的话题。
当前像素蛋糕和美图云修,百度网盘AI修图也都是提供的手动调节方式的瘦脸功能,以百度为例,界面如下:
本文从个人经验角度,给出几种可行的方案,并针对其中一种进行详细讲解,给出相关的代码示例。
方案一 传统瘦脸参数自适应
思路:在基于传统图像处理构建的瘦脸变形算法基础上,通过平均脸构建自适应的参数计算,然后对瘦脸算法进行调节,得到瘦脸效果;
实现方案推荐:
输入:原始人脸+人脸点位检测(瘦脸关键点)
自适应瘦脸算法:
-
可根据模特脸的五官比例,计算用户图点位对应的五官比例,根据比例偏差来计算瘦脸程度,根据瘦脸程度调用瘦脸变形算法,得到瘦脸效果;
-
可构建平均脸(可通过N张模特图构建),将用户人脸点位映射到平均脸,得到新的点位,根据映射前后点位差,计算瘦脸程度,调用瘦脸变形算法,得到瘦脸效果;
输出:瘦脸参数,按参数给出对应瘦脸效果
优点:不需要模型训练,速度快;
缺点:效果一般,无法真正根据用户特有的脸型,得到最佳的瘦脸效果;
方案二 Image-to-Image Translation条件生成
思路:这种方法主要基于GAN网络,根据输入用户人像照片,直接输出人脸瘦脸之后的效果图。
实现方案推荐:Pix2Pix
-
输入:原始人脸 + 瘦脸强度 Mask/编码(可选)
-
输出:瘦脸后人脸
-
优点:自动学习皮肤纹理补偿,避免拉伸伪影
-
缺点:需要 paired 数据(原脸→瘦脸 GT),数据制作是个难点,数据的好坏直接影响效果的好坏;
这类算法,目前用于一般性的手机修图没有问题,但是对于影楼修图行业,人脸图像区域>1000×1000的情况,效果就显得比较模糊,可以看出生成痕迹,分辨率越大,对比越明显;
方案三 关键点回归
思路:我们通过深度学习网络来学习瘦脸关键点,用户输入一张照片,进行人脸关键点检测,网络输入人脸关键点信息,自动输出瘦脸后的关键点,然后根据瘦脸前后关键点做人脸变形,得到瘦脸效果图。
实现方案推荐:
-
网络结构:MLP 或 轻量 UNet-like Graph 网络
-
输入:原图关键点(可归一化到 [0,1])
-
输出:瘦脸关键点,根据关键点得到瘦脸效果图
-
损失函数:
-
优点:实现简单,训练数据量不需要太大,可用于影楼高分辨率大图的处理;
以68个人脸关键点为例,网络结构举例如下:
# 关键点输入: [batch, 68*2]
# 输出: [batch, 68*2]
import tensorflow as tf
from tensorflow.keras import layers, models
def build_landmark_mapper(num_points=68):
inputs = layers.Input(shape=(num_points*2,))
x = layers.Dense(256, activation='relu')(inputs)
x = layers.Dense(256, activation='relu')(x)
x = layers.Dense(num_points*2)(x)
return models.Model(inputs, x, name="LandmarkMapper")
方案四 偏移学习
思路:基于方案二,我们不进行关键点的直接回归,而是进行关键点偏移量的学习,将人脸关键点输入网络,输出要达到瘦脸效果所对应的关键点偏移量,然后,根据偏移量对图像进行Warp,得到瘦脸效果;
与直接回归相比,学习形变偏移更稳定,训练模型预测偏移量,再与原点位相加得到瘦脸点位。
偏移量计算:
同时,也可添加强度控制:
模型训练
原理
数据集构建
我们以68人脸关键点为例,假设你有以下 numpy 数据文件:
可以先计算偏移量 ΔK:
import numpy as np
orig = np.load('orig_landmarks.npy') # [M, N, 2]
slim = np.load('slim_landmarks.npy') # [M, N, 2]
delta = slim - orig # 偏移量 [M, N, 2]
# 展平到 [M, N*2]
X = orig.reshape(len(orig), -1)
Y = delta.reshape(len(delta), -1)
# 数据归一化(可选)
X_min, X_max = X.min(axis=0), X.max(axis=0)
X_norm = (X - X_min) / (X_max - X_min + 1e-8)
np.save('X.npy', X_norm)
np.save('Y.npy', Y)
模型构建
这里我们使用简单的 MLP 预测关键点偏移量,大家也可以自行使用更为复杂的网络设计,这里仅做举例:
import tensorflow as tf
from tensorflow.keras import layers, models
def build_landmark_offset_model(num_points=68):
inputs = layers.Input(shape=(num_points*2,))
x = layers.Dense(256, activation='relu')(inputs)
x = layers.Dense(256, activation='relu')(x)
x = layers.Dense(128, activation='relu')(x)
outputs = layers.Dense(num_points*2, activation='linear')(x)
return models.Model(inputs, outputs, name="LandmarkOffsetNet")
num_points = 68
model = build_landmark_offset_model(num_points)
model.summary()
模型训练
import numpy as np
from tensorflow.keras.callbacks import ModelCheckpoint
X = np.load('X.npy') # [M, 136]
Y = np.load('Y.npy') # [M, 136]
model.compile(optimizer='adam', loss='mse')
checkpoint = ModelCheckpoint(
'landmark_offset_best.h5',
monitor='val_loss', save_best_only=True
)
model.fit(
X, Y,
validation_split=0.1,
epochs=200,
batch_size=32,
callbacks=[checkpoint]
)
推理与瘦脸效果关键点合成
# 读取训练归一化参数
X_min = X.min(axis=0)
X_max = X.max(axis=0)
def predict_slim_landmarks(orig_landmarks):
# orig_landmarks: [N, 2]
x = orig_landmarks.reshape(1, -1)
x_norm = (x - X_min) / (X_max - X_min + 1e-8)
delta_pred = model.predict(x_norm)[0].reshape(-1, 2)
slim_pred = orig_landmarks + delta_pred
return slim_pred
# 示例
orig_landmarks = np.array([
[100, 120], [110, 118], ... # 68 个关键点
])
slim_landmarks = predict_slim_landmarks(orig_landmarks)
print(slim_landmarks)
瘦脸变形
有了瘦脸前后的关键点,我们就可以使用 Thin Plate Spline (TPS) 或 Piecewise Affine Warp来进行人脸变形,得到最终的瘦脸效果:
from skimage.transform import PiecewiseAffineTransform, warp
def warp_face(image, src_points, dst_points):
tform = PiecewiseAffineTransform()
tform.estimate(dst_points, src_points) # src→dst 映射
warped = warp(image, tform, output_shape=image.shape)
return (warped*255).astype(np.uint8)
# 示例
warped_image = warp_face(user_image, orig_landmarks, slim_landmarks)
上面就是基于瘦脸关键点偏移学习的AI瘦脸方案的完整介绍。最后,给个效果示例(原图-瘦脸效果图):
本文介绍的几种方案,都是个人在实践经验积累中,感觉相对而言比较可行,可用的方案。其中对于关键点部分,并不局限于2D关键点,也可使用3D关键点,在3D空间进行Warp,效果会更好。
实际上,大家对于人脸美型类的研究一直都未停止,除了本文的几种方法,还有很多其他的方法和论文,比如以下几篇论文:
《Deep Shapely Portraits》
《Face shape transfer via semantic warping》
《Parametric Weight-change Reshaping for Portrait Images》
大家有兴趣可自行研究。
更多推荐
所有评论(0)