简介:本资源为基于Python深度学习框架的GFPGAN图片修复算法实现源码,面向具备一定Python编程与深度学习基础、希望深入研究图像修复与生成对抗网络的开发者及研究人员。项目聚焦面部图像的高质量修复与美化,可应用于老旧照片修复、数字取证及艺术作品数字化等场景。压缩包共62个文件,约6.22MB,其中26个py文件承载算法核心实现与训练推理逻辑,8个yml与2个yaml配置文件负责参数与实验设置,5个md文档提供说明与常见问题解答,另含png、jpg示例图、mdb数据集、pth权重及license等辅助文件。目录涵盖模型架构、数据加载、训练脚本与测试用例等模块,结构完整。目前已有429人学习下载,适合作为图像修复方向的实践参考与二次开发基础。
1. 从一张糊到看不清五官的老照片说起:GFPGAN 源码包能干什么
翻出十年前的合影,人脸区域糊成一团,放大后全是噪点和马赛克——这是很多人做图片修复时最典型的起点。基于 Python 深度学习的 GFPGAN 图片修复算法实现源码,解决的正是这类问题:它不是简单锐化或插值放大,而是用生成对抗网络把退化的人脸「重建」回接近真实的样子。这套源码包把 GFPGAN 的完整实现、预训练模型加载逻辑、推理脚本和训练配置都摊开给你,适合两类人:一是想直接跑通修复效果的 Python 开发者,二是想拆开看 GAN 人脸先验怎么落到代码里的深度学习学习者。它不承诺一键修所有图,但对人脸区域的修复能力,在开源方案里属于第一梯队。
2. 拆开源码包:GFPGAN 的架构分层与文件职责
2.1 从 gfpgan/ 目录看推理链路
拿到源码包,先别急着python inference_gfpgan.py。花十分钟把gfpgan/目录的调用关系理清楚,后面调参和排错会省很多时间。核心链路是这样的:inference_gfpgan.py负责解析命令行参数、读图、调用模型、保存结果;gfpgan/utils.py里的GFPGANer类是真正的门面,它把人脸检测、对齐、修复、背景融合串在一起;gfpgan/models/gfpgan_model.py定义训练和推理时的网络组装逻辑;gfpgan/archs/下面才是各个网络结构的实现。
archs目录里有几个文件值得单独说。gfpganv1_arch.py是原始 GFPGAN 的生成器结构,包含退化消除模块和人脸生成器;gfpganv1_clean_arch.py是去掉了训练专用组件的干净版本,推理时更轻;stylegan2_clean_arch.py是 StyleGAN2 的干净实现,作为生成器的骨干;arcface_arch.py是 ArcFace 人脸识别网络,训练时用来算身份损失,保证修复后的人还是同一个人。restoreformer_arch.py是后来加入的 RestoreFormer 结构,属于扩展选项。
理解这个分层后,你就能判断改哪里:想换生成器骨干,动stylegan2_clean_arch.py;想调修复强度,看gfpganv1_clean_arch.py里通道数和残差块数量;想加自己的损失函数,去gfpgan_model.py找gfpgan_forward和gfpgan_backward。
2.2 配置文件与预训练模型怎么对应
源码包里options/目录下的 YAML 文件决定了训练和推理的行为。train_gfpgan_v1.yml是完整训练配置,train_gfpgan_v1_simple.yml是简化版,适合显存有限的机器。推理时虽然不直接读这些 YAML,但GFPGANer初始化时会根据你传入的模型版本选择对应的网络结构,所以配置文件和模型权重必须匹配。
常见做法是:先看experiments/pretrained_models/里有没有现成权重,没有的话按PaperModel.md里的说明下载对应版本。inference_gfpgan.py默认会去这个目录找模型。如果你把权重放在别处,用--model_path指定绝对路径,别用相对路径,否则从不同工作目录运行时容易找不到。
# 查看源码包内预训练模型目录结构 ls -la experiments/pretrained_models/ # 典型输出会包含 detection、arcface、gfpgan 等子目录 # detection 放人脸检测模型,arcface 放身份特征模型,gfpgan 放修复主模型这段命令的作用是确认模型文件是否齐全。detection目录通常需要 RetinaFace 或类似的人脸检测权重,arcface目录放 ArcFace 的.pth文件,gfpgan目录放主修复模型。缺任何一个,推理时都会在对应环节报错。参数上,--upscale控制输出放大倍数,默认 2;--bg_upsampler控制背景放大方式,可选realesrgan或None。
2.3 推理脚本的参数体系
inference_gfpgan.py的参数不多,但每个都影响结果。-i指定输入,可以是单张图也可以是目录;-o指定输出目录;-v指定模型版本,常用1.3和1.4;-s是放大倍数;--only_center_face只修复画面中心人脸;--aligned表示输入已经是对齐好的人脸,跳过检测对齐步骤。
python inference_gfpgan.py \ -i inputs/whole_imgs \ -o results \ -v 1.4 \ -s 2 \ --bg_upsampler realesrgan这段命令的逻辑是:读inputs/whole_imgs下的所有图,用 1.4 版模型修复,输出放大 2 倍,背景用 Real-ESRGAN 放大。-v 1.4对应gfpganv1_clean_arch.py的结构,如果你只有 1.3 的权重却传 1.4,加载时会报unexpected key或missing key。--bg_upsampler realesrgan需要额外安装realesrgan包,不装就设成None,否则初始化阶段直接抛ImportError。
3. 跑通第一次修复:环境、权重与推理全流程
3.1 环境依赖的版本边界
这套源码对版本比较敏感,尤其是 PyTorch 和 CUDA 的搭配。requirements.txt里列了基础依赖,但没锁死版本。血泪经验是:PyTorch 1.8 到 1.13 之间兼容性最好,2.0 以上部分算子行为有变化,stylegan2_clean_arch.py里的upfirdn2d可能报错。Python 用 3.8 或 3.9,3.10 以上有些旧版basicsr装不上。
# 建议的安装顺序,先建虚拟环境 conda create -n gfpgan python=3.9 -y conda activate gfpgan # 装 PyTorch,按你的 CUDA 版本选 pip install torch==1.13.1+cu117 torchvision==0.14.1+cu117 -f https://download.pytorch.org/whl/torch_stable.html # 再装项目依赖 pip install -r requirements.txt # 单独装 basicsr 和 facexlib,这两个容易版本冲突 pip install basicsr==1.4.2 facexlib==0.2.5逻辑说明:先固定 Python 和 PyTorch,再装项目依赖,最后单独处理basicsr和facexlib。参数上,torch==1.13.1+cu117里的cu117表示 CUDA 11.7 编译版,你的驱动要支持对应 CUDA 版本。如果装完basicsr后 import 报cannot import name 'degradations',说明版本不对,降到 1.4.2 通常能解决。
3.2 权重文件的放置与校验
预训练权重不随源码包直接提供,需要按PaperModel.md的指引获取。常见做法是建一个experiments/pretrained_models目录,把下载的.pth文件按子目录放好。放完后用一段小脚本校验加载是否正常。
import torch # 校验 GFPGAN 主模型权重能否被干净架构加载 from gfpgan.archs.gfpganv1_clean_arch import GFPGANv1Clean # 注意:这里只加载结构,不跑推理,用来确认权重和架构匹配 model = GFPGANv1Clean( out_size=512, num_style_feat=512, channel_multiplier=2, decoder_load_path=None, fix_decoder=False, num_mlp=8, input_is_latent=True, different_w=True, narrow=1, sft_half=True ) state_dict = torch.load('experiments/pretrained_models/gfpgan/GFPGANv1.4.pth', map_location='cpu') # strict=False 允许部分 key 不匹配,但要看 missing 和 unexpected 的数量 model.load_state_dict(state_dict, strict=False) print('权重加载完成,可以进入推理阶段')这段代码的作用是提前暴露权重和架构不匹配的问题。参数channel_multiplier=2对应 1.4 版,1.3 版通常是 1。sft_half=True也是 1.4 的特征。如果load_state_dict报大量 missing keys,说明你下的权重版本和代码里的架构对不上,换权重或换-v参数。
3.3 单张图与批量修复的实操差异
单张图修复直接指定文件路径就行,批量修复把-i指向目录。但批量时有个坑:如果目录里混了非图片文件,inference_gfpgan.py会直接崩。我一般先过滤一遍。
# 批量修复前先清理输入目录,只保留图片 mkdir -p inputs/clean find inputs/whole_imgs -type f \( -iname "*.jpg" -o -iname "*.png" -o -iname "*.jpeg" \) -exec cp {} inputs/clean/ \; # 再跑批量推理 python inference_gfpgan.py -i inputs/clean -o results_batch -v 1.4 -s 2逻辑说明:find命令按扩展名筛选图片并复制到干净目录,避免推理脚本读到.DS_Store或.txt时抛异常。参数-iname忽略大小写,覆盖.JPG和.jpg。批量输出会按原文件名保存在results_batch下,同时生成cropped_faces和restored_faces子目录,方便对比修复前后的人脸区域。
4. 避坑与排查:GFPGAN 跑不起来时先看这几条
4.1 报错ModuleNotFoundError: No module named 'basicsr'
现象是运行inference_gfpgan.py时直接提示找不到basicsr,即使pip list里显示已安装。原因通常是basicsr装到了系统 Python 而不是当前虚拟环境,或者装完后没重启终端导致路径没刷新。解决方法是先which python确认当前解释器路径,再pip show basicsr看安装位置是否一致。不一致就python -m pip install basicsr==1.4.2强制装到当前环境。装完还报错,检查basicsr依赖的torch版本是否被降级覆盖了。
4.2 推理结果人脸区域出现绿色或紫色色块
现象是修复后的人脸部分颜色异常,背景正常。原因是--bg_upsampler和主修复模型的输出通道顺序不一致,常见于 Real-ESRGAN 版本不匹配。解决方法是先把--bg_upsampler设为None跑一遍,确认主修复模型输出正常。如果正常,再单独升级realesrgan到与basicsr兼容的版本。另一个可能是输入图是 CMYK 模式,cv2.imread读进来通道错乱,用 PIL 转成 RGB 再存一次。
4.3 显存不足导致CUDA out of memory
现象是处理稍大一点的图就崩,报显存不够。原因是 GFPGAN 默认按整图处理,人脸检测后裁剪的区域如果分辨率高,生成器中间特征图占用很大。解决方法是加--upscale 1先不放大,或者把输入图长边缩到 1024 以内再跑。如果还不行,在GFPGANer初始化时把bg_upsampler关掉,背景不放大能省不少显存。批量处理时改成逐张循环,别一次性把所有图读进内存。
4.4 修复后的人脸不像本人
现象是修复效果清晰了,但五官和原图差异大,像换了个人。原因是--weight参数(身份损失权重)在推理时不可调,模型默认偏向生成「标准好看脸」。解决方法是换用 1.3 版模型,它的身份保持通常比 1.4 更稳;或者在gfpganv1_clean_arch.py里把sft_half设为False再跑,减少对原始特征的修改。如果对身份保持要求极高,建议只修复背景,人脸区域用原图叠加。
4.5 输出目录生成了文件但打不开
现象是results目录下有文件,但双击提示损坏。原因是推理脚本保存时用了cv2.imwrite,而输出路径包含中文或空格,OpenCV 在部分系统上处理不了非 ASCII 路径。解决方法是把输出目录改成纯英文路径,或者把保存逻辑换成PIL.Image.fromarray(...).save(...)。另外检查磁盘空间,写了一半空间满也会产生损坏文件。
5. 进阶技巧:用 parse_landmark 和 convert 脚本做可控修复
源码包里scripts/目录下有两个容易被忽略但很有用的脚本:parse_landmark.py和convert_gfpganv_to_clean.py。前者用来提取人脸关键点,后者用来把训练版权重转成推理版干净架构。掌握这两个,你就能做更精细的控制。
parse_landmark.py的用法是传入一张人脸图,输出 68 个关键点坐标。这些坐标可以用来判断人脸姿态:如果关键点分布明显偏转,说明侧脸角度大,GFPGAN 的修复效果会下降。我一般会在批量修复前先跑一遍关键点检测,把侧脸超过 30 度的图单独挑出来,避免修复后五官错位。
from scripts.parse_landmark import parse_landmark import cv2 # 读取图片并提取关键点 img = cv2.imread('inputs/cropped_faces/Adele_crop.png') landmarks = parse_landmark(img) # landmarks 是 68x2 的数组,前 17 个是下颌线,后面是眉毛、鼻子、眼睛、嘴巴 # 用左右眼关键点估算偏转角 left_eye = landmarks[36:42].mean(axis=0) right_eye = landmarks[42:48].mean(axis=0) eye_center = (left_eye + right_eye) / 2 nose = landmarks[30] # 鼻尖偏离双眼中心越多,侧脸角度越大 offset = abs(nose[0] - eye_center[0]) / (right_eye[0] - left_eye[0]) print(f'侧脸偏移比例: {offset:.2f},超过 0.3 建议人工检查')这段代码的逻辑是用眼睛和鼻子的相对位置估算侧脸程度。参数上,landmarks[36:42]是左眼六个点,landmarks[42:48]是右眼六个点,landmarks[30]是鼻尖。offset超过 0.3 时,GFPGAN 的正面先验会强行「掰正」人脸,导致不像本人。这时候要么换一张更正的图,要么在GFPGANer里把only_center_face打开,只修最正的那张脸。
convert_gfpganv_to_clean.py解决的是权重格式问题。有些渠道拿到的权重是训练版保存的,包含判别器和优化器状态,直接加载到推理架构会报 key 不匹配。这个脚本把训练版权重里的生成器部分抽出来,重新映射到干净架构的 key 名。
# 把训练版权重转成推理版 python scripts/convert_gfpganv_to_clean.py \ --src experiments/pretrained_models/gfpgan/GFPGANv1.4_train.pth \ --dst experiments/pretrained_models/gfpgan/GFPGANv1.4_clean.pth # 转换后再跑推理,指定 clean 权重 python inference_gfpgan.py -i inputs/whole_imgs -o results -v 1.4 -s 2逻辑说明:--src是原始训练权重路径,--dst是转换后保存路径。转换脚本会打印映射了多少个 key,如果有大量 key 没映射上,说明源权重版本和脚本预期的不一致。转换完成后,inference_gfpgan.py会自动优先加载_clean后缀的权重。这个步骤在换用非官方渠道权重时特别有用,能避免直接加载时的玄学报错。
从那以后我每次拿到新的 GFPGAN 权重,都强制先跑一遍convert_gfpganv_to_clean.py再推理,不管它文件名里有没有clean。这个习惯帮我省掉了至少三次「权重明明在却加载失败」的排查时间。希望帮到你。
本文还有配套的精品资源,点击获取