人脸增强任务要解决的并不仅仅是分辨率数字的上升,更重要的是把低清图中已经丢失的皮肤纹理、睫毛走向和五官边缘重新补出来。传统超分方法例如双三次插值或早期 CNN 模型,在处理较大倍率放大时容易产生平滑假脸,因为它们缺少对真实人脸结构的约束。GPEN 的关键设计是把预训练生成对抗网络中的人脸先验嵌入修复网络,让输出不再只是像素逼近,而是符合真实人脸分布的高频细节。

GPEN 的 GAN 先验是怎样嵌入的
GPEN 的主干可以看成一个编码器-解码器结构。编码器从低质量人脸中提取多尺度特征,解码器在上采样阶段并不是简单反卷积,而是通过调制卷积把 StyleGAN 的中间潜在向量注入到特征图中。这种方式让每一层恢复的细节都受到生成先验的约束:眼睛区域会趋向于生成更像真实眼睛的结构,皮肤区域会带上自然的毛孔和光影变化,而不是从训练集中平均出来的模糊纹理。
训练过程中,GPEN 需要成对的低清与高清人脸数据。它先准备大量高质量人脸,再通过随机模糊、下采样、加噪和 JPEG 压缩构建退化版本,让网络学习从严重退化图像回到原始高清图。这个退化生成环节很关键,因为实际输入可能是视频截图、社交平台压缩图或旧照片扫描件,如果只用理想下采样训练,模型在真实模糊上很容易失效。
训练完成后,推理阶段不会直接生成随机人脸,而是以输入人脸为条件,先提取内容特征,再逐步用 GAN 先验补充细节。因此 GPEN 不像纯 StyleGAN 那样会改变人脸身份,也不像传统超分那样只能做平滑放大。它在保持身份、姿态、背景基本一致的前提下,把五官和肤质修复到更自然的状态。
环境配置与权重准备
GPEN 官方实现基于 PyTorch,推理不需要训练代码,但需要准备 Python 3.8 或 3.9 环境。建议使用虚拟环境隔离依赖,避免与已有项目中的 opencv 或 torch 版本冲突。安装依赖时注意 GPU 版 PyTorch 要和 CUDA 版本匹配,如果只是测试 CPU 推理,也可以安装 CPU 版本,但处理速度会明显变慢。
python -m venv gpen_env gpen_env\Scripts\activate pip install torch torchvision opencv-python numpy scipy pip install gdown
然后获取 GPEN 仓库并下载预训练权重。权重文件通常包括人脸增强模型和可选的超分模型,比如 GPEN-BFR-512 负责 512 分辨率人脸修复,realesrnet 用于进一步超分。下载完成后,需要把权重文件放到仓库的 weights 目录下,代码加载时会根据文件名查找。
git clone https://github.com/yangxy/GPEN.git cd GPEN mkdir weights # 将手动下载的 GPEN-BFR-512.pth 放入 weights 目录
仓库里同时提供了命令行脚本 run_enhancement.py,初学者可以直接用它验证环境。命令中需要指定输入目录、输出目录、模型类型和是否启用超分。遇到权重加载失败时,先检查文件名和目录结构,再确认下载的权重是否完整,部分网盘链接可能需要手动下载后放入对应位置。
单人脸增强的 Python 调用
命令行脚本适合快速验证,但实际项目里更常用 Python 接口。下面的代码演示了如何加载 512 模型,读取一张本地图片,执行增强并保存结果。使用 FaceEnhancer 对象时,use_sr 参数控制是否先经过超分模型放大,aligned 参数表示输入是否已经做过人脸对齐裁剪。
import cv2
from gpen import FaceEnhancer
# 初始化增强器,加载 GPEN-BFR-512 权重
enhancer = FaceEnhancer(
size=512,
model='GPEN-BFR-512',
use_sr=False,
sr_model='rrdb_realesrnet_psnr'
)
# 读取本地图片,注意 Windows 路径使用原始反斜杠
img_path = r"C:\Users\test\face.jpg"
img = cv2.imread(img_path)
# 执行人脸增强,aligned=False 表示输入为未裁剪的普通照片
result = enhancer.process(img, aligned=False)
# 保存增强结果
out_path = r"C:\Users\test\face_enhanced.jpg"
cv2.imwrite(out_path, result)
print("saved to", out_path)
如果输入图片中只有一张人脸,并且人脸占画面比例较大,可以直接使用上述代码。对于包含全身照、多人合影或人脸占比较小的图像,建议先用检测器裁剪出人脸区域,再进行增强,否则模型可能因为输入中有效人脸像素太少而无法恢复细节。GPEN 仓库提供了 face_detect 相关函数,也可以使用 MTCNN 或 RetinaFace 完成检测。
当 use_sr=True 时,流程会先通过超分模型提升分辨率,再交给 GPEN 做人脸修复。这种组合适合低分辨率人脸,例如 64 到 128 像素的人脸区域。优点是输出更清晰,缺点是计算量增大,且如果超分模型过强,可能在背景上引入伪影。可以先保持 use_sr=False 跑通基础流程,再根据实际效果决定是否开启。
批量处理与参数调优
批量处理时,不要每张图片都重新初始化模型。模型权重只需加载一次,之后循环调用 process 即可。下面例子遍历输入目录中的常见图片后缀,将增强结果输出到指定目录。因为人脸修复非常耗时,建议在循环中记录处理时间和文件名,便于定位异常图片。
import os
import cv2
from gpen import FaceEnhancer
input_dir = r"C:\data\faces"
output_dir = r"C:\data\faces_out"
os.makedirs(output_dir, exist_ok=True)
enhancer = FaceEnhancer(size=512, model='GPEN-BFR-512', use_sr=True)
for name in os.listdir(input_dir):
if not name.lower().endswith(('.jpg', '.png', '.jpeg', '.bmp')):
continue
in_path = os.path.join(input_dir, name)
out_path = os.path.join(output_dir, name)
img = cv2.imread(in_path)
if img is None:
print('skip unreadable', name)
continue
result = enhancer.process(img, aligned=False)
cv2.imwrite(out_path, result)
print('processed', name)
调参时最常改的是 size、use_sr 和 aligned 三个参数。size 决定模型内部处理分辨率,512 适合大多数单人头像,256 速度更快但细节偏弱,1024 显存占用会明显上升。显存不足时可以先降低尺寸或关闭超分,再逐步增加。
另一个容易忽略的点是色彩空间。OpenCV 默认以 BGR 顺序读取图像,GPEN 的 process 方法通常内部会处理颜色转换,但如果你自己用其他库加载图像后传进去,要确认是否转换成 RGB。否则输出肤色可能偏蓝。遇到颜色异常时,可以先用 cv2.cvtColor 转回 RGB 再可视化对比。
对于身份证件照、监控截图这类退化严重的图像,GPEN 能改善清晰度,但不能无中生有地恢复被遮挡或完全抹掉的细节。尤其是眼睛闭合、强光过曝、运动模糊过大的情况,修复结果可能更像合理的人脸重构而不是原始信息还原。这类场景下建议配合人脸检测、关键点对齐和人工审核,避免在正式业务中直接使用增强结果。
整体来说,GPEN 的价值在于把 GAN 先验从生成任务迁移到修复任务,让低清人脸增强不再只是锐化边缘,而是恢复结构合理的细节。部署时关键是理解退化训练、权重匹配和参数取舍,配合真实业务图片做小批量验证,比盲目追求高分辨率更加重要。