GAN图像修复毕设实战:源码结构与避坑指南
发布时间:2026/10/2 18:16:41来源:尧图网络
简介一套基于深度学习的图像修复算法Python源码及配套资料主要面向计算机视觉、人工智能等专业的毕业设计、课程设计与项目实战学习者。资源针对图像破损区域重建问题提供了完整的模型代码、训练/推理脚本、数据集与项目说明文档适合从入门到进阶的在校学生和开发者参考。包内共84个文件核心代码以Python.py及编译缓存.pyc为主辅以模型结构图、效果对比图等PNG/JPG图像并包含C/CUDA自定义算子、说明文档.md/.txt及数据集压缩包整体大小约3.57MB。目录按模块网络结构、数据生成、测试集等组织便于按需查看。目前已有253人学习下载。项目为作者高分毕业设计评审96.5分代码经测试运行成功并提供使用说明与预训练模型放置指引下载后如有运行问题可联系作者远程教学适合需要完整可运行方案作为毕设参考或练手项目的读者。1. 这份深度学习图像修复源码先别急着跑 demo拿到一份基于深度学习的图像修复算法 python 源码大多数人第一步是装环境跑 demo但我建议你先花二十分钟把目录结构过一遍。这个项目做的事是 GAN 图像修复它不是简单地把破损区域涂掉而是根据周边像素的纹理、结构和语义信息把缺失内容重新画出来。项目里自带 Places 和 CelebA-HQ 两个标准数据集有掩码生成脚本、CPU/GPU 双推理入口和 gradio 演示界面适合正在做毕设、课设、期末大作业的计算机相关专业学生也适合想完整走一遍 GAN 图像修复链路的 Python 开发者。这类资源最容易出现的情况是能跑通但不知道每一步在干什么。所以我这篇不打算只讲「双击运行」而是按我实际拆项目的顺序先把算法栈讲清楚再给可复现的命令、参数和避坑记录。读完之后你拿到的不是一堆 py 文件而是一条能自己控制的修复流水线。2. 拆开项目的骨架GAN 图像修复的模型结构、文件清单与选型理由2.1 从文件清单反推算法栈dnnlib、torch_utils 与 legacy 说明了什么打开 zip 包先看目录我的习惯是先找dnnlib、torch_utils、legacy.py这三个东西。dnnlib和torch_utils是 StyleGAN2 生态里的标准组件里面带着upfirdn2d.cpp、bias_act.cu、conv2d_gradfix.py这类自定义算子legacy.py负责把旧的.pkl权重文件转换并加载。这说明整个修复模型不是随便拼的 CNN而是基于预训练 GAN 生成器做的图像修复网络主体大概率是 StyleGAN2 的生成器结构修复过程依赖潜向量或特征约束来完成缺失区域的生成。这一点对写论文很重要。评审老师看你项目说明时最关心的不是「效果图多好看」而是「你是否理解修复为什么有效」。基于 GAN 的修复思路和基于 U-Net 的修复思路有本质区别U-Net 这类判别式模型擅长拟合已知到未知的映射对大面积缺失容易产生模糊GAN 生成器天然学过图像分布缺失区域由分布先验和周围条件共同决定纹理和结构更接近真实。这个项目选 GAN 路线在毕设答辩时讲「生成先验」这个概念比单纯报 PSNR 数字更有说服力。再看入口文件generate_image.py和generate_image_cpu.py分别是 GPU 和 CPU 的推理脚本mask_generator_512.py生成 512×512 的掩码fix_image_size.py统一图像尺寸legacy.py负责兼容。整个流程就是拿到一张图 → 生成掩码标记破损区 → 喂给 GAN 生成器 → 输出修复结果。pretrained目录里只放了说明.txt而不是直接放权重文件——这点后面避坑章节要重点讲很多人就是卡在这里。2.2 为什么用「生成器 掩码 数据集」这套组合图像修复本质是一个条件生成问题。给定一张带 mask 的图像生成器需要同时做两件事保持非 mask 区域像素不变在 mask 区域内生成与全局语义一致的内容。如果只用 L2 损失约束模型会选择「平均化」策略来降低误差结果就是一片模糊如果引入对抗损失生成器会学会输出锐利、真实的纹理。这个项目把 GAN 生成器作为主干掩码作为条件输入正好对应了「先分布后细节」的修复逻辑。数据集方面项目带了test_sets/Places和test_sets/CelebA-HQ两个测试集masks和images分开放。Places 是室外场景数据集纹理复杂、结构多样适合验证模型对大面积缺失的泛化能力CelebA-HQ 是高清人脸数据集人脸结构对称且先验强修复结果更容易看出语义是否正确。两个数据集叠加可以覆盖「场景」和「人脸」两种最常见的毕设展示场景。mask_generator_512.py生成掩码的方式是模拟笔画涂抹这种掩码比规则矩形块更接近真实应用。选型理由落到项目本身也很直接这是个人毕设项目不是工业级产品所以方案要「效果可展示、原理可讲述、资源可复现」。StyleGAN2 生态有成熟的预训练权重加载机制legacy.py可以直接兼容旧版 pkl省去从头训练生成器的时间generate_image_cpu.py的存在意味着没有 N 卡也能跑通全流程只是慢一些。下面这个表格是我拆完目录后整理的文件角色对照建议你保存下来写项目说明时直接照这个逻辑组织章节。文件/目录角色关键作用networks/basic_module.py网络定义生成器与判别器的骨架模块dnnlib/ torch_utils/基础设施自定义算子、权重管理、训练统计legacy.py权重兼容加载旧版本.pkl权重文件mask_generator_512.py掩码生成生成 512×512 的笔画式掩码generate_image.pyGPU 推理调用生成器做图像修复generate_image_cpu.pyCPU 推理无 GPU 环境下的推理入口fix_image_size.py预处理统一输入图像尺寸test_sets/测试数据Places、CelebA-HQ 的 images/masksshow_img/效果展示修复前后对比图写文档时可用2.3 网络结构图与 demo 图答辩材料怎么用项目里带了模型结构图.png、gradio演示1.png、cmd_demo.png这些展示文件。不要小看这几张图毕设答辩时老师最常问的三句话是网络结构是什么、数据怎么准备的、效果怎么验证。结构图直接回答第一问demo 图回答第三问。我一般会建议把模型结构图.png重新标注一遍把生成器、判别器、mask 输入的位置用箭头标清楚贴在项目说明第二章。cmd_demo.png是命令行运行截图写使用说明时可以作为「运行结果验证」的证据。gradio演示1.png展示的是浏览器界面说明项目带了可交互演示环境。这三类素材配合起来就是一份完整的成果展示链模型结构 → 命令行结果 → 交互界面。评审看到的是你不仅跑通了代码还做了可视化封装。3. 复现一条完整链路环境配置、掩码生成与修复推理的参数对照3.1 环境与依赖requirements.txt 里的关键项先看requirements.txt这个文件直接决定了你能不能把环境装起来。从项目使用的库来看核心依赖包括 PyTorch、NumPy、OpenCV 和 Gradio。目录里__pycache__同时出现了cpython-38和cpython-39说明作者在 Python 3.8 和 3.9 上都跑过你在这两个版本里选一个都行我建议直接用 3.8兼容性最稳。装环境时我通常用虚拟环境隔离避免把系统 Python 搅乱。常见做法是conda create -n inpaint python3.8 conda activate inpaint pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install -r requirements.txt这里--index-url指定 CUDA 11.8 版本的 PyTorch如果你的显卡驱动只支持 CUDA 12把cu118改成cu121再装一次。CPU 环境不需要这个参数直接pip install torch torchvision就行。装完后跑一句python -c import torch; print(torch.cuda.is_available())输出True说明 GPU 可用False也不用慌项目提供了 CPU 推理入口只是速度会慢一个量级。3.2 mask_generator_512掩码怎么生成、参数怎么调掩码生成是整个修复流程的起点。mask_generator_512.py做的事情是模拟涂抹痕迹在 512×512 的图上随机画白色笔触白色区域就是要修复的地方。这类掩码叫不规则掩码比规则矩形块更贴近真实场景——现实中照片破损、物体遮挡很少是正矩形。核心逻辑通常长这样import numpy as np import cv2 def generate_mask(size512, num_vertices8, brush_size12): mask np.zeros((size, size, 3), dtypenp.uint8) points [] for _ in range(num_vertices): points.append((np.random.randint(0, size), np.random.randint(0, size))) points np.array(points) cv2.fillPoly(mask, [points], color(255, 255, 255)) kernel np.ones((brush_size, brush_size), np.uint8) mask cv2.dilate(mask, kernel, iterations2) return mask[:, :, 0]这段代码先生成一个全黑掩码再用fillPoly画一个不规则多边形最后用膨胀操作加粗笔触让它看起来更像真实涂抹。num_vertices控制涂抹形状的复杂度值越大形状越不规则brush_size控制笔触粗细12对应 512 分辨率下大约能覆盖 2% 的区域。如果你想让破损面积更大把num_vertices调大到 12、brush_size调到 20生成的掩码区域会明显变大。在这个项目里掩码生成后要放进test_sets/Places/masks或test_sets/CelebA-HQ/masks和images目录下的原图一一对应。文件名必须一致否则后续加载时配对不上。我第一次跑的时候在这个环节翻过车图叫001.png掩码叫001_mask.png结果掩码找不到对应原图输出一片黑。3.3 修复推理generate_image_cpu / generate_image 的入口与输出推理入口有两个文件generate_image.py走 GPUgenerate_image_cpu.py走 CPU。两者的区别本质上只在设备指定上其余参数逻辑基本一致。GPU 版本的调用方式大概是这样python generate_image.py \ --network pretrained/your_model.pkl \ --image test_sets/CelebA-HQ/images/00001.png \ --mask test_sets/CelebA-HQ/masks/00001.png \ --outdir results/ \ --seed 42拆开看每个参数--network指向预训练权重文件.pkl是 GAN 生态的标准权重格式由legacy.py负责加载--image是待修复原图路径--mask是对应的掩码路径白色区域会被修复--outdir是输出目录--seed控制随机数种子固定后结果可复现写论文时需要固定这个值。CPU 版本调用方式几乎一样只是把脚本名换成generate_image_cpu.pypython generate_image_cpu.py \ --network pretrained/your_model.pkl \ --image test_sets/Places/images/00001.png \ --mask test_sets/Places/masks/00001.png \ --outdir results/注意pretrained目录里目前只是说明文件。运行之前要把训练好的权重文件下载后放进去权重文件名保持和代码里引用的一致。加载权重时legacy.py会做一次版本检查如果报AssertionError: The network is not compatible with the current code说明权重文件的格式和当前代码不匹配通常需要在命令行加--legacy 1强制走兼容加载这在老项目里是常见操作。输出结果会写到--outdir目录文件名一般保留原图文件名。项目里的samples目录就是用来放修复效果图的修复好的图片会出现在这里.txt这个文件名本身就是个提示输出路径不要乱改。3.4 gradio 演示脚本把修复结果拉到浏览器里看项目里有多张gradio演示1.png、gradio演示2.png说明作者用 Gradio 封装了可视化界面。这个封装对毕设答辩很加分——老师可以看到你上传一张破损图界面自动返回修复结果而不是冷冰冰的命令行输出。Gradio 脚本的核心结构通常是这样import gradio as gr import torch from generate_image_cpu import inpaint_single def inpaint_wrapper(image_path, mask_path): result inpaint_single( image_pathimage_path, mask_pathmask_path, networkpretrained/your_model.pkl ) return result gr.Interface( fninpaint_wrapper, inputs[gr.Image(typefilepath, label破损图), gr.Image(typefilepath, label掩码图)], outputsgr.Image(label修复结果), titleGAN 图像修复演示 ).launch()gr.Image(typefilepath)会把上传的图片转成文件路径再传给修复函数inpaint_single是推理脚本里封装的单图修复函数你可以把它理解成命令行参数缺省版本的封装。启动后浏览器打开http://127.0.0.1:7860就能看到交互界面。我一般建议把演示录一段短视频答辩 PPT 里放视频比放截图更能说明问题。4. 在毕设项目里最容易踩的五个坑现象、原因与解决4.1 预训练权重放错位置一运行就报找不到文件现象是运行generate_image.py立刻报FileNotFoundError提示找不到pretrained/xxx.pkl。原因很直接zip 包里pretrained目录只有说明文本没有实际权重文件需要你自己下载后放进去。很多第一次拿到这个项目的人没注意下载训练好的文件放在这里.txt直接运行自然报错。解决方法是先读pretrained目录下的说明文件按里面指定的文件名和放置路径把权重放好。如果说明文件没给下载源去项目对应社区或论文主页找同名.pkl。放进去后验证一次加载是否成功python里执行import legacy; legacy.load_network_pkl(open(pretrained/xxx.pkl,rb))看到网络结构输出说明加载成功。4.2 Python 版本与 pyc 缓存冲突同代码两种结果项目__pycache__里同时存在cpython-38.pyc和cpython-39.pyc这是作者先后用两个 Python 版本运行留下的。现象是你用自己的 Python 版本跑时偶尔会报缓存文件损坏或者行为诡异的结果。原因是有时候.pyc缓存和当前解释器版本不匹配Python 虽然会自动重新编译但旧缓存干扰了导入路径。解决方法是清掉整个__pycache__目录再跑命令是find . -type d -name __pycache__ -exec rm -rf {} Windows 上直接手动删。注意删缓存不影响源码只影响编译后的字节码。从那以后我每拿到一个新项目第一件事就是清一遍__pycache__避免历史残留干扰。4.3 mask 与图像尺寸对不上修复区域整块错位现象是生成结果里修复区域明显偏移mask 画在左脸修复痕迹出现在右脸。原因在于mask_generator_512.py固定生成 512×512 掩码但测试集图像可能不是这个分辨率而加载图像时如果做了 resizemask 没有同步 resize坐标就全错位了。解决方法是先跑一遍fix_image_size.py统一所有输入图像尺寸。这个脚本的作用就是把test_sets里的图像和掩码都处理成同一尺寸。执行时注意脚本默认读目录、写目录需要确认输入输出路径参数。如果脚本没给参数自己写两行代码同步 resizeimport cv2 def resize_pair(image_path, mask_path, out_size512): img cv2.imread(image_path) mask cv2.imread(mask_path, 0) img cv2.resize(img, (out_size, out_size)) mask cv2.resize(mask, (out_size, out_size), interpolationcv2.INTER_NEAREST) return img, maskmask 的 resize 要用INTER_NEAREST保持掩码边缘硬边不能出现灰度插值否则掩码就不是纯 0/255 二值图后续处理会出问题。4.4 CUDA 算子编译失败upfirdn2d 编不过去现象是 GPU 环境下运行报错指向upfirdn2d.cpp或bias_act.cu编译失败。原因是项目依赖的 CUDA 自定义算子需要和当前 PyTorch 版本匹配新版本 PyTorch 改了接口旧算子代码编不过。这种问题在新旧环境切换时非常典型。解决办法有两个一是把 PyTorch 版本降到项目开发时的版本常见做法是装 1.8 或 1.9二是切换到generate_image_cpu.py做纯 CPU 推理绕开 CUDA 算子编译。CPU 推理慢但至少能把流程跑通。如果毕设演示只需要几张图的效果CPU 完全够用。4.5 修复结果发糊或纹理重复掩码密度与生成参数没配合现象是修复区域像被涂抹过没有细节纹理或者出现重复的几何图案。原因通常不是模型坏了而是掩码面积过大、生成器需要重建的区域太宽已经超出了它能合理推断的范围另一个常见原因是随机种子固定后生成器对特定 mask 的采样结果不理想。解决方法是先缩小掩码面积把mask_generator_512.py里的brush_size调低或者减少num_vertices然后是换--seed多跑几个随机种子选效果最好的。我的习惯是每个测试图跑三个 seed对比后再定稿写进论文里的结果永远是可复现的最佳值而不是第一次运行的值。5. 更进一步批量修复脚本、gradio 界面与换数据集验证5.1 一个 40 行的批量修复脚本单图推理跑通之后下一步通常是要批量处理测试集用于统计修复效果。手动一条条敲命令太慢我一般会写一个批量脚本把测试集里所有配对好的图像和掩码扫一遍逐个推理并保存结果import os import sys import glob image_dir test_sets/Places/images mask_dir test_sets/Places/masks out_dir results/places os.makedirs(out_dir, exist_okTrue) image_paths sorted(glob.glob(os.path.join(image_dir, *.png))) for img_path in image_paths: name os.path.basename(img_path) mask_path os.path.join(mask_dir, name) if not os.path.exists(mask_path): print(fskip {name}: mask not found) continue cmd ( fpython generate_image_cpu.py f--network pretrained/your_model.pkl f--image {img_path} f--mask {mask_path} f--outdir {out_dir} f--seed 7 ) print(fprocessing {name}) os.system(cmd)脚本逻辑不复杂glob扫出所有原图匹配同名掩码缺失的直接跳过然后用os.system调推理脚本。这里三个变量值得留意out_dir每次跑完检查一下是否有输出避免掩码没配对但脚本静默跳过--seed在批量场景下固定保证一批结果的随机性一致mask_path用os.path.exists做存在性检查路径写错立刻暴露。5.2 换数据集验证模型的泛化能力如果你有自定义数据不要直接丢进测试集先跑两遍流程第一遍用fix_image_size.py把图像统一到 512×512第二遍用mask_generator_512.py生成掩码。原图放images掩码放masks保持文件名一致。验证时先跑 3 张看整体效果再决定要不要全量跑——全量跑人脸数据集比跑场景数据集耗时多因为人脸细节对生成器的计算压力更大。我在自己的项目里养成了一个习惯任何模型换数据集先过一张图看两件事——掩码区域边界清不清晰、非掩码区域有没有被改动。前者看修复能力后者看约束能力。一个合格的修复模型应该做到掩码区完全重绘、非掩码区像素不变如果非掩码区也变了说明条件注入没锁住原图内容要回头检查输入拼接逻辑。从那以后我每次跑批处理前都强制走一遍「单图三连」一张原图、一张掩码、一张结果确认三者对应关系无误才敢继续。这个习惯让我省了至少十次「跑完整个测试集才发现掩码错了」的翻车事故希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网