【GitHub】GFPGAN 深度解析:基于生成式面部先验的真实世界盲人脸修复算法

1 阅读12分钟

作者:来源于源码深度分析
论文:GFP-GAN: Towards Real-World Blind Face Restoration with Generative Facial Prior
机构:腾讯 ARC(Applied Research Center)
开源地址github.com/TencentARC/…


一、概述

人脸修复(Face Restoration)是计算机视觉中的经典难题。传统方法在低质量输入图像面前往往捉襟见肘——尤其是面对真实世界中复杂混合的退化(模糊、噪声、压缩伪影等)时,修复效果有限且细节缺失。

GFPGAN(Generative Facial Prior GAN) 是腾讯 ARC 提出的突破性算法,其核心创新在于:

将预训练 StyleGAN2 蕴含的丰富生成式面部先验知识引入退化人脸修复,通过创新的空间特征变换(SFT)机制,在保真度与感知质量之间取得优异平衡。

本文将从项目结构、核心算法、关键代码实现三个维度,对 GFPGAN 进行全面深度的技术解析。


二、项目结构总览

GFPGAN-master/
├── gfpgan/                         # 核心模块包
│   ├── archs/                      # 网络架构定义
│   │   ├── gfpganv1_arch.py        # GFPGAN v1(原版,需要CUDA扩展)
│   │   ├── gfpganv1_clean_arch.py  # GFPGAN v1 Clean(纯PyTorch,跨平台)
│   │   ├── gfpgan_bilinear_arch.py # GFPGAN 双线性插值版本
│   │   ├── arcface_arch.py         # ArcFace 人脸识别网络(用于身份损失)
│   │   ├── restoreformer_arch.py   # RestoreFormer(Transformer-based)
│   │   ├── stylegan2_bilinear_arch.py # StyleGAN2 双线性版本
│   │   └── stylegan2_clean_arch.py  # StyleGAN2 纯净版本
│   ├── data/
│   │   └── ffhq_degradation_dataset.py  # FFHQ退化数据集(在线动态生成LQ)
│   ├── models/
│   │   └── gfpgan_model.py         # 训练模型(损失计算、优化器管理)
│   ├── utils.py                    # GFPGANer 推理助手类
│   └── train.py                    # 训练入口
├── inference_gfpgan.py             # 命令行推理脚本
├── options/
│   ├── train_gfpgan_v1.yml         # 完整训练配置(含面部判别器、身份损失)
│   └── train_gfpgan_v1_simple.yml  # 简化训练配置
├── scripts/
│   ├── convert_gfpganv_to_clean.py # 模型转换脚本
│   └── parse_landmark.py           # 关键点预处理脚本
├── tests/                          # 单元测试
├── inputs/                         # 示例输入图像
├── results/                        # 推理结果输出
└── requirements.txt                # 依赖列表

项目依赖

basicsr>=1.4.2      # 腾讯开源图像修复基础库
facexlib>=0.2.5     # 人脸检测/对齐库
torch>=1.7          # PyTorch 深度学习框架
opencv-python       # 图像处理
torchvision         # 视觉工具
lmdb                # 高效数据库(训练数据)

三、核心算法思想

3.1 问题定义:盲人脸修复

给定退化低质量图像 yy,目标是恢复高质量图像 x^\hat{x}

y=(xk)s+ny = (x \otimes k) \downarrow_s + n

其中 kk 为模糊核,s\downarrow_s 为下采样,nn 为噪声与压缩伪影。由于退化参数未知(即"盲"),这是一个严重欠约束问题。

3.2 核心创新:生成式面部先验(GFP)

GFPGAN 的关键洞察是:预训练的 StyleGAN2 模型已经学习了高质量人脸的完整先验分布,包括纹理细节、面部组件位置、光照等。

通过将退化图像"对准"StyleGAN2 的潜在空间,可以借助其生成能力补全缺失的细节。

3.3 整体网络架构:U-Net 编码器 + StyleGAN2 解码器

输入低质量图 (LQ)
        │
   ┌────▼────────────────────────────────────────────┐
   │              U-Net 编码器                        │
   │  512×51225612864321684×4  │
   │  (逐步下采样,保存各级 skip 特征)                 │
   └─────────────────────────────────────────────────┘
        │ 风格码 style_code (512维)
        │ 各层 SFT 条件 conditions
        │
   ┌────▼─────────────────────────────────────────────┐
   │          StyleGAN2 解码器(含SFT调制)              │
   │   4×48163264128256512×512  │
   │   每层注入 SFT 条件(scale + shift)                │
   └──────────────────────────────────────────────────┘
        │
   高质量修复图 (HQ)

四、核心架构深度解析

4.1 U-Net 编码器(Degradation Removal)

4.1.1 下采样路径

# gfpganv1_clean_arch.py - GFPGANv1Clean.__init__()

# 通道配置(narrow=1时)
channels = {
    '4': 256,   '8': 256,   '16': 256,  '32': 256,
    '64': 256,  '128': 128, '256': 64,  '512': 32, '1024': 16
}

# 第一层卷积
self.conv_body_first = nn.Conv2d(3, channels[f'{first_out_size}'], 1)

# 下采样残差块链
self.conv_body_down = nn.ModuleList()
for i in range(self.log_size, 2, -1):  # 从大到小(512→256→...→8)
    out_channels = channels[f'{2**(i - 1)}']
    self.conv_body_down.append(ResBlock(in_channels, out_channels, mode='down'))

每个 ResBlock(mode='down') 包含:

  • Conv1 → LeakyReLU → 双线性下采样 → Conv2 → LeakyReLU
  • Skip 连接:双线性下采样 → 1×1 Conv

4.1.2 风格码提取

# final_linear 将 4×4 特征图 flatten 后映射为风格码
self.final_linear = nn.Linear(channels['4'] * 4 * 4, linear_out_channel)

# forward() 中:
style_code = self.final_linear(feat.view(feat.size(0), -1))
# 当 different_w=True 时,为每个 StyleGAN2 层生成不同的 w code
if self.different_w:
    style_code = style_code.view(style_code.size(0), -1, self.num_style_feat)

different_w 选项允许为 StyleGAN2 的不同层提供各自的风格码,增强了修复灵活性。

4.1.3 上采样路径(生成 SFT 条件)

# 上采样路径:逐级恢复空间分辨率
self.conv_body_up = nn.ModuleList()
for i in range(3, self.log_size + 1):  # 从小到大(8→16→...→512)
    out_channels = channels[f'{2**i}']
    self.conv_body_up.append(ResBlock(in_channels, out_channels, mode='up'))

# SFT 条件生成网络(scale 和 shift 各一组)
self.condition_scale = nn.ModuleList()
self.condition_shift = nn.ModuleList()
for i in range(3, self.log_size + 1):
    self.condition_scale.append(
        nn.Sequential(
            nn.Conv2d(out_channels, out_channels, 3, 1, 1),
            nn.LeakyReLU(0.2, True),
            nn.Conv2d(out_channels, sft_out_channels, 3, 1, 1)))
    self.condition_shift.append(
        nn.Sequential(
            nn.Conv2d(out_channels, out_channels, 3, 1, 1),
            nn.LeakyReLU(0.2, True),
            nn.Conv2d(out_channels, sft_out_channels, 3, 1, 1)))

forward() 中的上采样流程:

for i in range(self.log_size - 2):
    feat = feat + unet_skips[i]        # U-Net 跳跃连接
    feat = self.conv_body_up[i](feat)  # 上采样
    scale = self.condition_scale[i](feat)
    shift = self.condition_shift[i](feat)
    conditions.append(scale.clone())
    conditions.append(shift.clone())   # 交替存放 scale, shift

4.2 空间特征变换(Spatial Feature Transform, SFT)

SFT 是 GFPGAN 的核心创新点,用于将编码器提取的图像退化信息注入 StyleGAN2 生成器的各个层:

Fout=Fin×scalecondition+shiftconditionF_{out} = F_{in} \times \text{scale}_{condition} + \text{shift}_{condition}

# StyleGAN2GeneratorCSFT.forward() 中的 SFT 调制
if i < len(conditions):
    if self.sft_half:  # 仅对一半通道应用SFT
        out_same, out_sft = torch.split(out, int(out.size(1) // 2), dim=1)
        out_sft = out_sft * conditions[i - 1] + conditions[i]
        out = torch.cat([out_same, out_sft], dim=1)
    else:              # 对全部通道应用SFT
        out = out * conditions[i - 1] + conditions[i]

SFT 的设计哲学

  • 保留 StyleGAN2 先验:不修改 StyleGAN2 的权重(fix_decoder=True),而是通过 SFT 将图像信息"注入"到生成过程
  • 空间自适应:scale 和 shift 具有与生成特征相同的空间分辨率,允许像素级精细控制
  • sft_half 模式:只对一半通道应用 SFT,保留另一半的生成先验,平衡修复与生成质量

4.3 StyleGAN2 调制卷积(ModulatedConv2d)

StyleGAN2 的调制卷积是风格注入的核心机制:

# stylegan2_clean_arch.py
class ModulatedConv2d(nn.Module):
    def forward(self, x, style):
        b, c, h, w = x.shape
        # 风格调制权重
        style = self.modulation(style).view(b, 1, c, 1, 1)
        # weight: (1, c_out, c_in, k, k); style: (b, 1, c, 1, 1)
        weight = self.weight * style  # (b, c_out, c_in, k, k)
        if self.demodulate:
            # 去调制(归一化),确保风格不影响特征图统计量
            demod = torch.rsqrt(weight.pow(2).sum([2, 3, 4]) + self.eps)
            weight = weight * demod.view(b, self.out_channels, 1, 1, 1)
        # reshape 为分组卷积
        weight = weight.view(b * self.out_channels, c, self.kernel_size, self.kernel_size)
        x = x.view(1, b * c, h, w)
        out = F.conv2d(x, weight, padding=self.padding, groups=b)
        return out.view(b, self.out_channels, *out.shape[-2:])

调制流程

  1. 风格码通过全连接层映射为每个输入通道的缩放系数
  2. 与卷积权重相乘(调制)
  3. 去调制(demodulate)进行归一化,避免特征图方差失控
  4. 执行卷积

4.4 ArcFace 身份网络(ResNetArcFace)

用于计算身份保留损失(Identity Loss),确保修复后的人脸与原始人脸身份一致:

class ResNetArcFace(nn.Module):
    """基于 ResNet 的 ArcFace 人脸识别网络
    输入: 128×128 灰度图
    输出: 512 维身份特征向量
    """
    def __init__(self, block, layers, use_se=True):
        self.conv1 = nn.Conv2d(1, 64, kernel_size=3, padding=1, bias=False)
        self.layer1 = self._make_layer(block, 64,  layers[0])
        self.layer2 = self._make_layer(block, 128, layers[1], stride=2)
        self.layer3 = self._make_layer(block, 256, layers[2], stride=2)
        self.layer4 = self._make_layer(block, 512, layers[3], stride=2)
        self.fc5 = nn.Linear(512 * 8 * 8, 512)  # 输出512维特征

    def forward(self, x):
        # x: (B, 1, 128, 128) 灰度图
        x = self.layer1(self.maxpool(self.prelu(self.bn1(self.conv1(x)))))
        x = self.layer4(self.layer3(self.layer2(x)))
        x = self.fc5(x.view(x.size(0), -1))
        return self.bn5(x)

IRBlock(改进残差块)中引入了 SEBlock(通道注意力):

class SEBlock(nn.Module):
    """Squeeze-and-Excitation Block"""
    def forward(self, x):
        b, c, _, _ = x.size()
        y = self.avg_pool(x).view(b, c)           # 全局平均池化
        y = self.fc(y).view(b, c, 1, 1)           # 两层全连接 + Sigmoid
        return x * y                               # 通道重标定

4.5 面部组件判别器(FacialComponentDiscriminator)

用于单独判别眼睛、嘴巴区域的真实性,提供精细化的面部细节约束:

class FacialComponentDiscriminator(nn.Module):
    """VGG 风格架构,处理裁剪出的眼部/嘴部区域"""
    def __init__(self):
        self.conv1 = ConvLayer(3,   64,  3, downsample=False)  # 80×80
        self.conv2 = ConvLayer(64,  128, 3, downsample=True)   # 40×40
        self.conv3 = ConvLayer(128, 128, 3, downsample=False)
        self.conv4 = ConvLayer(128, 256, 3, downsample=True)   # 20×20
        self.conv5 = ConvLayer(256, 256, 3, downsample=False)
        self.final_conv = ConvLayer(256, 1, 3, activate=False) # 判别分数

    def forward(self, x, return_feats=False):
        feat = self.conv3(self.conv2(self.conv1(x)))
        rlt_feats = [feat.clone()]  # 用于风格损失
        feat = self.conv5(self.conv4(feat))
        rlt_feats.append(feat.clone())
        out = self.final_conv(feat)
        return out, rlt_feats if return_feats else None

五、数据管线:FFHQDegradationDataset

5.1 在线退化合成

GFPGAN 训练时使用 FFHQ(70,000 张高清人脸)数据集,并在线实时合成退化图像,避免了固定退化集的过拟合问题:

def __getitem__(self, index):
    img_gt = load_image(self.paths[index])   # 加载高清GT图

    # ① 随机水平翻转
    img_gt, status = augment(img_gt, hflip=True, rotation=False)

    # ② 随机混合模糊(各向同性/各向异性高斯核)
    kernel = random_mixed_kernels(
        kernel_list=['iso', 'aniso'],
        kernel_prob=[0.5, 0.5],
        blur_kernel_size=41,
        blur_sigma=[0.1, 10])
    img_lq = cv2.filter2D(img_gt, -1, kernel)

    # ③ 随机下采样(比例0.8~8倍)
    scale = np.random.uniform(0.8, 8)
    img_lq = cv2.resize(img_lq, (int(w//scale), int(h//scale)))

    # ④ 随机高斯噪声
    img_lq = random_add_gaussian_noise(img_lq, noise_range=[0, 20])

    # ⑤ 随机JPEG压缩
    img_lq = random_add_jpg_compression(img_lq, jpeg_range=[60, 100])

    # ⑥ 恢复原始尺寸
    img_lq = cv2.resize(img_lq, (w, h))

    # ⑦ 颜色抖动、灰度化(可选)
    ...
    return {'lq': img_lq, 'gt': img_gt, 'loc_left_eye': ..., 'loc_right_eye': ..., 'loc_mouth': ...}

5.2 面部组件坐标预处理

训练前通过 parse_landmark.py 提取 FFHQ 数据集中每张图的面部关键点(眼睛、嘴巴位置),存储为 .pth 文件,供训练时 ROI Align 使用:

def get_component_coordinates(self, index, status):
    components_bbox = self.components_list[f'{index:08d}']
    if status[0]:  # 水平翻转时交换左右眼
        tmp = components_bbox['left_eye']
        components_bbox['left_eye'] = components_bbox['right_eye']
        components_bbox['right_eye'] = tmp
    # 计算各组件的矩形坐标 [x1, y1, x2, y2]
    for part in ['left_eye', 'right_eye', 'mouth']:
        mean = components_bbox[part][0:2]
        half_len = components_bbox[part][2]
        loc = np.hstack((mean - half_len + 1, mean + half_len))

六、训练策略与损失函数

6.1 多判别器体系

判别器功能架构
net_d(主判别器)判别整张 512×512 人脸StyleGAN2Discriminator
net_d_left_eye判别左眼区域(80×80)FacialComponentDiscriminator
net_d_right_eye判别右眼区域(80×80)FacialComponentDiscriminator
net_d_mouth判别嘴巴区域(120×120)FacialComponentDiscriminator

6.2 损失函数体系

GFPGAN 使用了精心设计的多项损失:

# optimize_parameters() 核心部分

# 1. 像素级 L1 损失(权重 0.1)
l_g_pix = self.cri_pix(self.output, self.gt)    # L1(output, gt)

# 2. 图像金字塔损失(提前终止,前50k iter有效)
pyramid_gt = construct_img_pyramid()  # gt的多尺度版本
for i in range(self.log_size - 2):
    l_pyramid = cri_l1(out_rgbs[i], pyramid_gt[i]) * pyramid_loss_weight

# 3. 感知损失(VGG19特征匹配 + 风格损失)
# 使用 VGG19 的 conv1_2, conv2_2, conv3_4, conv4_4, conv5_4 层
l_g_percep, l_g_style = self.cri_perceptual(self.output, self.gt)
# 感知权重=1,风格权重=50

# 4. 对抗损失(wgan_softplus)
fake_g_pred = self.net_d(self.output)
l_g_gan = self.cri_gan(fake_g_pred, True, is_disc=False)  # 权重 0.1

# 5. 面部组件对抗损失(vanilla GAN)
# 使用 ROI Align 提取眼睛/嘴巴区域
all_eyes = roi_align(self.output, boxes=rois_eyes, output_size=eye_out_size)
fake_left_eye, fake_left_eye_feats = self.net_d_left_eye(left_eyes)
l_g_gan_left_eye = self.cri_component(fake_left_eye, True, is_disc=False)

# 6. 面部组件风格损失(Gram矩阵匹配)
def _comp_style(feat, feat_gt, criterion):
    return criterion(gram_mat(feat[0]), gram_mat(feat_gt[0]).detach()) * 0.5 \
         + criterion(gram_mat(feat[1]), gram_mat(feat_gt[1]).detach())
comp_style_loss = (_comp_style(left_feats, real_left_feats, cri_l1)
                 + _comp_style(right_feats, real_right_feats, cri_l1)
                 + _comp_style(mouth_feats, real_mouth_feats, cri_l1)) * 200

# 7. 身份损失(ArcFace特征距离)
out_gray = gray_resize_for_identity(self.output, size=128)  # 转灰度,缩放到128
gt_gray  = gray_resize_for_identity(self.gt, size=128)
l_identity = cri_l1(network_identity(out_gray), network_identity(gt_gray)) * 10

# 判别器训练(WGAN-softplus + R1正则)
l_d = cri_gan(real_d_pred, True) + cri_gan(fake_d_pred, False)
# R1 梯度惩罚(每16步一次)
l_d_r1 = r1_penalty(real_pred, self.gt) * r1_reg_weight / 2 * net_d_reg_every

6.3 总损失权重汇总

损失项权重说明
像素L1损失0.1低层次保真
图像金字塔损失1.0多尺度约束(前50k步)
VGG感知损失1.0高层特征匹配
VGG风格损失50纹理风格匹配
GAN对抗损失0.1整体感知质量
面部组件GAN损失1.0×3眼睛/嘴巴细节
面部组件风格损失200细节风格质量
身份损失10身份保持
R1梯度惩罚10判别器稳定性

6.4 EMA(指数移动平均)

# 用于稳定训练并获得更好的生成质量
self.model_ema(decay=0.5**(32 / (10 * 1000)))
# decay ≈ 0.9977

# 测试时使用 EMA 模型
if hasattr(self, 'net_g_ema'):
    self.net_g_ema.eval()
    self.output, _ = self.net_g_ema(self.lq)

七、推理流程解析

7.1 GFPGANer 类

GFPGANer 是推理阶段的核心封装类,集成了完整的处理流程:

class GFPGANer():
    def enhance(self, img, has_aligned=False, only_center_face=False,
                paste_back=True, weight=0.5):
        # 阶段1:人脸检测与对齐
        if not has_aligned:
            self.face_helper.read_image(img)
            self.face_helper.get_face_landmarks_5(...)  # 5点关键点检测
            self.face_helper.align_warp_face()          # 仿射变换对齐至512×512

        # 阶段2:逐脸修复
        for cropped_face in self.face_helper.cropped_faces:
            # 归一化到 [-1, 1]
            cropped_face_t = normalize(img2tensor(cropped_face/255.), (0.5,), (0.5,))
            # GFPGAN 推理
            output = self.gfpgan(cropped_face_t, return_rgb=False, weight=weight)[0]
            restored_face = tensor2img(output, rgb2bgr=True, min_max=(-1, 1))

        # 阶段3:粘贴回原图(含背景超分)
        if self.bg_upsampler is not None:
            bg_img = self.bg_upsampler.enhance(img, outscale=self.upscale)[0]
        self.face_helper.get_inverse_affine(None)
        restored_img = self.face_helper.paste_faces_to_input_image(upsample_img=bg_img)

推理流程图

原始图像
    │
    ▼
RetinaFace 人脸检测 → 检测到的人脸 bbox + 5 点关键点
    │
    ▼
仿射变换对齐 → 512×512 标准化人脸
    │
    ▼
归一化 [-1, 1]
    │
    ▼
GFPGAN 网络推理(U-Net编码器 + StyleGAN2解码器 + SFT)
    │
    ▼
逆归一化 → 修复后人脸
    │
    ▼
逆仿射变换 + 粘贴回原图(可选 RealESRGAN 背景超分)
    │
    ▼
最终修复结果

7.2 命令行推理

# 基本用法
python inference_gfpgan.py -i inputs/whole_imgs -o results -v 1.3 -s 2

# 参数说明
-v 1.3       # 选择模型版本(1.0/1.2/1.3/1.4/RestoreFormer)
-s 2         # 最终输出放大倍数
--aligned    # 输入已对齐的人脸(跳过检测步骤)
--bg_upsampler realesrgan  # 使用 RealESRGAN 超分背景
-w 0.5       # 调整修复强度权重

八、版本演进

版本架构主要特性
v1.0GFPGANv1(原版)需要 CUDA 自定义算子,使用 StyleGAN2 算子
v1.2GFPGANv1Clean纯 PyTorch 实现,去掉 CE(色彩增强),通道数×2
v1.3GFPGANv1Clean更自然的修复效果,对低质量/高质量输入均友好
v1.4GFPGANv1Clean更多细节 + 更好的身份保持
RestoreFormerTransformer-based基于 VQ-VAE 的 Transformer 架构,特征一致性更强

九、RestoreFormer 架构简介

作为 GFPGAN 项目中集成的另一方案,RestoreFormer 使用了完全不同的技术路线:

class VectorQuantizer(nn.Module):
    """VQ-VAE 离散特征量化器"""
    def forward(self, z):
        # 将连续特征映射为离散码本中最近的向量
        d = ||z - e||²  # 计算距离
        z_q = embedding[argmin(d)]  # 量化
        # Straight-through 梯度估计器
        z_q = z + (z_q - z).detach()
        return z_q

RestoreFormer 的优势在于使用 Transformer 的全局注意力机制处理面部特征,避免了 CNN 的局部感受野限制,在处理严重退化时具有更好的特征一致性。


十、训练配置关键设置

# train_gfpgan_v1.yml(部分)
network_g:
  type: GFPGANv1
  out_size: 512
  num_style_feat: 512
  channel_multiplier: 1
  fix_decoder: true          # 冻结 StyleGAN2 解码器
  input_is_latent: true      # 编码器输出直接作为 w 空间输入
  different_w: true          # 每层使用不同的 w code
  sft_half: true             # SFT 仅应用于一半通道

train:
  optim_g: {type: Adam, lr: 2e-3}
  optim_d: {type: Adam, lr: 2e-3}
  scheduler:
    type: MultiStepLR
    milestones: [600000, 700000]  # 在 60万、70万步降低学习率
    gamma: 0.5
  total_iter: 800000         # 总训练 80万步
  net_d_reg_every: 16        # 每16步进行一次 R1 正则化

十一、工程设计亮点

11.1 注册表机制

基于 BasicSR 的注册表系统,实现架构/模型/数据集的动态注册和实例化:

@ARCH_REGISTRY.register()
class GFPGANv1Clean(nn.Module): ...

@MODEL_REGISTRY.register()
class GFPGANModel(BaseModel): ...

@DATASET_REGISTRY.register()
class FFHQDegradationDataset(data.Dataset): ...

通过配置文件中的 type 字段即可动态实例化对应类,极大提升了扩展性。

11.2 模型转换脚本

# scripts/convert_gfpganv_to_clean.py
# 将原版 GFPGAN(含 CUDA 自定义算子)转换为 Clean 版本
# 实现跨平台(Windows/CPU)部署

11.3 Cog 部署支持

# cog.yaml - 用于 Replicate.com 云端部署
build:
  python_version: "3.8"
  run:
    - pip install basicsr facexlib gfpgan
predict: "cog_predict.py:Predictor"

十二、总结与展望

GFPGAN 的成功来自于以下几个关键设计决策:

  1. 善用预训练先验:不从头训练 StyleGAN2,而是冻结其权重并利用其已学习的高质量先验,大幅降低训练难度
  2. SFT 优雅注入:通过轻量的 scale+shift 操作将图像信息注入生成过程,兼顾保真度与感知质量
  3. 多粒度判别:整图判别器 + 眼睛/嘴巴局部判别器,确保全局结构与局部细节双重优化
  4. 身份保留约束:引入 ArcFace 特征距离,防止修复后"换脸"现象
  5. 在线退化合成:动态生成退化图像,提升对真实退化的泛化能力

局限性

  • 对非人脸内容(背景)需借助 RealESRGAN 等单独处理
  • 极端低质量输入(如严重遮挡)仍具挑战性
  • 修复结果有时过于"美颜化",身份特征可能轻微偏移

后续工作

  • RestoreFormer 引入 Transformer 进一步提升修复一致性
  • CodeFormer(NIPS 2022)在 GFPGAN 基础上引入可控保真度机制
  • DiffBIR 等扩散模型方法开始挑战 GAN-based 人脸修复的主导地位

参考文献

  1. Wang X, et al. "GFP-GAN: Towards Real-World Blind Face Restoration with Generative Facial Prior." CVPR 2021.
  2. Karras T, et al. "Analyzing and Improving the Image Quality of StyleGAN." CVPR 2020.
  3. Deng J, et al. "ArcFace: Additive Angular Margin Loss for Deep Face Recognition." CVPR 2019.
  4. Wang X, et al. "Real-ESRGAN: Training Real-World Blind Super-Resolution with Pure Synthetic Data." ICCVW 2021.
  5. Zhou S, et al. "Towards Real-World Blind Face Restoration with Generative Facial Prior." (RestoreFormer)

本文对 GFPGAN 项目代码进行了全面深入的技术解析,如有疏漏欢迎指正。喜欢请点赞收藏 ⭐