基于深度学习的老照片修复Python源码解析:从模型推理到Web部署全流程

发布时间:2026/9/28 13:49:35
基于深度学习的老照片修复Python源码解析:从模型推理到Web部署全流程
简介这是一份面向计算机、电子信息等专业学生与深度学习入门者的老照片修复项目源码基于深度学习模型实现图像上色与修复并自带简洁的Web交互页面可直接运行体验。资源包共20个文件约2.1MB包含7个Python源码文件、3个HTML页面模板、5个PNG与2个JPG示例图片以及说明文档和缓存文件覆盖模型定义、工具函数、表单处理与前端展示等模块结构清晰便于二次开发。项目适合作为课程设计、期末大作业或毕业设计的参考案例也可用于学习图像修复与Web部署的完整流程。目前已有306人学习下载读者可从中获取模型搭建、页面调用与调试排错的整体思路快速理解深度学习项目从代码到可视化的落地方式。1. 老照片修复源码拆包一份能跑起来的深度学习落地样本翻硬盘翻出一张 2003 年的全家福人脸糊得像隔了层毛玻璃这种场景估计不少人都遇到过。这份「基于深度学习的老照片修复 python 源码」就是冲着这个痛点来的——它把 colorizers 模型、Flask 风格的 web 页面、上传预测流程打包成一个 zip解压就能跑。目录里能看到colorizers、models.py、util.py、service.py、color_transformer.py、templates下的upload.html、layout.html、predict.html还有imgs里几张测试图。说白了它解决的是「想验证深度学习图像上色效果又不想从零搭环境」这件事。适合计算机、电子信息专业的课程设计和毕设参考也适合刚入门深度学习、想找一个完整 web 项目练手的人。下面我按拆包、跑通、调参、避坑的顺序把这份源码里里外外讲一遍。2. 环境与依赖把 zip 跑起来需要几步2.1 先看清目录结构再动手解压之后别急着python service.py先花两分钟把目录扫一遍。这份源码的结构大致是这样路径作用colorizers/模型核心含__init__.py、util.py、models.pyutils/辅助模块含__init__.py、form_models.pytemplates/前端页面upload.html、layout.html、predict.htmlservice.pyweb 服务入口color_transformer.py图像预处理与转换逻辑imgs/测试图2.jpg、old_img.png、11.pngout/、out1.png、out2.png输出目录与示例结果readme.md项目说明colorizers这个命名不是随便起的它对应的是图像上色colorization任务属于深度学习里比较经典的一类。models.py里通常放着网络结构定义util.py放权重加载和预处理函数。service.py是 web 层负责接收上传、调用模型、返回结果。理解这个分层后面改代码才不会迷路。2.2 依赖安装与版本对齐这份源码没有附带requirements.txt这是第一个要自己补的地方。根据colorizers和service.py的常见写法依赖大致是这些# 建议在虚拟环境里装避免污染全局 python -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate pip install torch torchvision pip install flask pip install opencv-python pip install numpy pillow pip install scikit-image逻辑说明torch和torchvision是模型推理的底座flask撑起 web 页面opencv-python和pillow负责图像读写scikit-image常用于颜色空间转换比如 RGB 转 Lab。参数上torch版本建议选 1.10 以上太老的版本对torchvision.transforms支持不全。如果你机器没有 GPU装 CPU 版即可这份源码的模型规模不大CPU 推理单张图大概几秒到十几秒。提示装torch时别直接pip install torch就完事去官网选对应 CUDA 版本的命令否则可能装到不匹配的包。2.3 启动服务与首次验证依赖装完后启动命令通常是这样python service.py如果service.py里用的是 Flask 默认配置终端会打印类似Running on http://127.0.0.1:5000的信息。浏览器打开这个地址应该能看到upload.html渲染的上传页面。选一张imgs/old_img.png传上去点预测等几秒看结果。这一步常见的翻车点是端口占用和路径问题。如果报Address already in use改service.py里的app.run(port5001)如果报找不到模板检查templates目录是否和service.py同级。首次跑通比什么都重要先别管效果好不好能出图就说明链路是通的。3. 模型推理链路从上传到出图中间发生了什么3.1 预处理图像进模型前被做了什么老照片修复的核心不是「修复」两个字而是「上色 增强」。这份源码走的是 colorization 路线模型输入通常不是原始 RGB而是转换到 Lab 颜色空间后的 L 通道。color_transformer.py大概率就是干这个的。典型流程是这样import cv2 import numpy as np def preprocess(img_path, size256): # 读图并转 RGB img cv2.imread(img_path) img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 缩放到模型输入尺寸 img cv2.resize(img, (size, size)) # 转 Lab取 L 通道作为输入 lab cv2.cvtColor(img, cv2.COLOR_RGB2Lab) L lab[:, :, 0] # 归一化到 [-1, 1] L L / 255.0 * 2 - 1 return L, img逻辑说明Lab 空间把亮度L和颜色a、b分离模型只需要根据 L 预测 a、b任务难度比直接预测 RGB 低很多。参数size256是常见输入尺寸改大能保留更多细节但显存和耗时上升。归一化到[-1, 1]是多数生成式模型的惯例具体看models.py里的定义如果模型用的是[0, 1]这里要跟着改。3.2 模型加载与推理models.py里定义网络util.py里通常有个load_model之类的函数。调用方式大概是这样import torch from colorizers import models, util # 加载模型结构 net models.ColorNet() # 加载权重map_location 保证 CPU 也能跑 state torch.load(colorizers/weights.pth, map_locationcpu) net.load_state_dict(state) net.eval() # 推理 with torch.no_grad(): L_tensor torch.from_numpy(L).unsqueeze(0).unsqueeze(0).float() ab net(L_tensor)逻辑说明eval()必须调用否则 BatchNorm 和 Dropout 会按训练模式走结果不稳定。unsqueeze两次是把(H, W)变成(1, 1, H, W)符合卷积网络输入格式。torch.no_grad()省显存也提速。如果state_dict加载报 key 不匹配多半是模型结构和权重不是同一版检查models.py里的层命名。3.3 后处理与结果保存拿到预测的 ab 通道后要和原 L 通道拼回去再转回 RGB# ab 形状通常是 (1, 2, H, W)取出来 ab ab.squeeze(0).permute(1, 2, 0).numpy() ab ab * 128 # 反归一化 # 拼回 Lab lab_out np.concatenate([L[:, :, None], ab], axis2) lab_out lab_out.astype(np.uint8) rgb_out cv2.cvtColor(lab_out, cv2.COLOR_Lab2RGB) cv2.imwrite(out/result.png, cv2.cvtColor(rgb_out, cv2.COLOR_RGB2BGR))逻辑说明ab 通道的取值范围和归一化方式必须和训练时一致这里按[-1, 1]反推到[-128, 127]再转uint8。如果出来的图偏色严重八成是这一步的缩放系数不对。保存时 OpenCV 用 BGR别忘了转回去。out/目录如果不存在imwrite会静默失败先os.makedirs(out, exist_okTrue)。4. Web 层与前端交互service.py 和 templates 怎么配合4.1 路由设计与文件上传service.py是整份源码的入口它把模型推理包装成 HTTP 接口。典型结构是这样from flask import Flask, render_template, request, redirect, url_for import os app Flask(__name__) UPLOAD_FOLDER uploads os.makedirs(UPLOAD_FOLDER, exist_okTrue) app.config[UPLOAD_FOLDER] UPLOAD_FOLDER app.route(/) def index(): return render_template(upload.html) app.route(/predict, methods[POST]) def predict(): file request.files[image] if not file: return no file, 400 save_path os.path.join(app.config[UPLOAD_FOLDER], file.filename) file.save(save_path) result_path run_model(save_path) # 调用推理 return render_template(predict.html, resultresult_path) if __name__ __main__: app.run(debugTrue, port5000)逻辑说明request.files[image]里的image必须和upload.html里input typefile nameimage的 name 一致不一致会直接 400。debugTrue方便开发但部署时要关掉。run_model是你需要确认的函数名源码里可能叫别的去service.py里搜一下实际调用。4.2 模板变量与结果展示predict.html负责把结果图渲染出来。常见写法!-- predict.html 片段 -- div classresult img src{{ url_for(static, filenameresult) }} alt修复结果 /div逻辑说明result是后端传过来的路径如果图片存在static目录下用url_for最稳。如果源码里直接返回文件路径字符串那src就写{{ result }}。这里容易踩的坑是路径分隔符Windows 下反斜杠在 HTML 里会被转义统一用/。4.3 上传页面与表单校验upload.html和layout.html是前端骨架layout.html通常放公共的 head、导航upload.html继承它。表单部分大概长这样form action/predict methodpost enctypemultipart/form-data input typefile nameimage acceptimage/* required button typesubmit开始修复/button /form逻辑说明enctypemultipart/form-data是文件上传的硬性要求漏了后端收不到文件。acceptimage/*只是前端过滤后端仍要做类型校验否则传个 txt 进去模型会直接崩。required防止空提交。5. 避坑与排查跑这份源码最容易翻车的五个地方5.1 现象启动报 ModuleNotFoundError: No module named colorizers原因在错误的目录下执行python service.py或者colorizers目录里缺__init__.py。解决确认终端当前目录是项目根目录且colorizers/__init__.py存在。如果缺失手动建一个空文件即可。Python 靠__init__.py识别包这个文件没有导入必挂。5.2 现象上传图片后页面卡住终端无报错原因模型推理在 CPU 上耗时较长或者run_model里有死循环/阻塞调用。解决先在run_model入口加print确认是否进入。如果是 CPU 慢把输入尺寸从 256 降到 128 试试。另外检查service.py是否开了多线程Flask 默认单线程并发上传会排队。5.3 现象输出图片全灰或全绿原因Lab 通道拼接时维度顺序错了或者 ab 反归一化系数不对。解决打印ab.shape和L.shape确认是(H, W, 2)和(H, W)。常见错误是permute顺序写反导致通道错位。系数方面如果模型输出是[0, 1]反归一化应该是ab * 255 - 128不是ab * 128。5.4 现象torch.load 报 UnpicklingError 或 key 不匹配原因权重文件损坏或者模型结构定义和权重不是同一版本。解决先确认权重文件大小是否正常几 MB 到几十 MB太小说明下载不完整。key 不匹配时用print(state.keys())和print(net.state_dict().keys())对比看是哪层对不上。如果是module.前缀问题用state {k.replace(module., ): v for k, v in state.items()}去掉。5.5 现象浏览器访问 127.0.0.1:5000 显示连接被拒绝原因服务没启动成功或者端口被占用后 Flask 静默退出。解决看终端有没有Running on字样。没有的话往上翻报错。端口占用就换端口app.run(port5001)。另外有些环境127.0.0.1不通试localhost或0.0.0.0。6. 进阶调参与效果验证让修复结果更可控跑通只是第一步真正要用这份源码做课程设计或毕设得知道怎么调。第一个可调的是输入尺寸。color_transformer.py里的size参数直接决定细节保留程度256 是平衡点512 细节更好但 CPU 上可能等半分钟。第二个是模型权重的选择colorizers这类结构通常有多个预训练权重换权重比改结构见效快。第三个是后处理里的锐化如果输出偏糊在转 RGB 后加一道cv2.detailEnhance或简单的 USM 锐化# 轻度锐化提升观感 blur cv2.GaussianBlur(rgb_out, (0, 0), 3) sharp cv2.addWeighted(rgb_out, 1.5, blur, -0.5, 0)逻辑说明addWeighted里 1.5 和 -0.5 是锐化强度和必须为 1。数值越大越锐但超过 2.0 会出现白边。验证效果别只看一张图把imgs里的2.jpg、old_img.png、11.png都跑一遍对比out1.png、out2.png的差异心里就有数了。我自己的习惯是每次改完参数先跑old_img.png这张因为它人脸区域大偏色和糊一眼能看出来。从那以后我每次调完模型都强制走一遍「三图对比」省得改了半天结果只对某一张图有效。希望帮到你。本文还有配套的精品资源点击获取