复现超分辨率技术在农田图像的应用研究
为了学习超分算法,本人复现了SRCNN、ESPCN、FSRCNN三种轻量级超分模型,每个模型训练次数300轮,采用农业公开训练集。同时在ESPCN算法里加入了简化后的SE注意力模块,并且使 MSE与 SSIM组合的损失函数实现优化。
1. 数据集构建
-
收集 7000 张 RGB 图像,按 7:2:1 划分为训练集、验证集、测试集
-
模拟农田退化:高斯模糊(7×7, σ=1.6)+ 4 倍下采样 + 高斯噪声(σ=0.01)
2. 模型复现与优化
-
复现三种轻量级超分模型:SRCNN、ESPCN、FSRCNN(各训练 300 轮)
-
对 ESPCN 进行优化:
-
加入简化版 SE 通道注意力模块(压缩比设为 8)
-
损失函数改为 MSE + SSIM 组合损失
-
4. 评估与测试
-
客观指标:PSNR、SSIM
-
主观视觉:对比重建效果
-
下游任务:病害分类 Top-1 准确率
一、项目文件结构
farmland_sr/
├── config.py # 所有配置参数(路径、尺寸、退化、训练超参数)
├── data_utils.py # 数据集类与加载器(动态生成LR/HR对,支持裁剪)
├── models.py # SRCNN、ESPCN、FSRCNN、ESPCN+SE 模型定义
├── utils.py # 退化函数、PSNR/SSIM计算、SSIM损失类
├── train.py # 训练主循环(含早停、保存最佳模型、自动记录loss)
├── evaluate.py # 评估模型:计算PSNR/SSIM/推理时间,保存重建图
├── demo.py # 单张图片超分演示(支持指定模型类型)
├── plot_loss.py # 读取loss_log.csv并绘制收敛曲线
├── data/
│ └── high_res/ # 存放原始高分辨率图片(256×256)
└── output/ # 保存模型权重、loss记录、测试结果
二、环境配置
要安装 Anaconda(一个管理 Python 环境的工具)和 PyTorch(深度学习框架)
# 创建并激活conda环境
conda create -n sr python=3.8
conda activate sr
# 安装核心依赖
pip install torch==2.1.0 torchvision==0.16.0 --index-url https://download.pytorch.org/whl/cu118
pip install opencv-python numpy scikit-image tqdm matplotlib pandas
三、数据准备
-
将全部高分辨率图片(256×256,RGB)放入
data/high_res/下(可包含子文件夹)。 -
代码会在训练时动态生成低分辨率图像(采用退化模型:高斯模糊→下采样→加噪声),无需预先成对存储。
-
数据集划分:
7:2:1(训练:验证:测试),按图像分组(同一图片的4个patch进入同一集合)
四、核心代码模块说明
1. config.py – 关键参数(示例)
HR_SIZE = 256 # 高分辨率尺寸
LR_SIZE = 64 # 低分辨率尺寸
SCALE_FACTOR = 4
# 退化参数(强退化,模拟农田真实情况)
GAUSSIAN_SIGMA = 1.6
NOISE_STD = 0.01
# 训练参数
BATCH_SIZE = 8
EPOCHS = 400
LEARNING_RATE = 1e-3
USE_COMBINED_LOSS = True
SSIM_LOSS_WEIGHT = 0.2
MODEL_TYPE = 'espcn_se' # 可选 'srcnn', 'espcn', 'fsrcnn', 'espcn_se'
2. utils.py – 退化与评价
-
degrade_image(hr, scale, sigma, noise_std): HR → LR(模糊→下采样→加噪声) -
calculate_psnr(img1, img2): 调用skimage.metrics.peak_signal_noise_ratio -
calculate_ssim(img1, img2): 调用structural_similarity,指定channel_axis=2,动态调整窗口 -
SSIMLoss: 可微分的SSIM损失,用于训练
3. data_utils.py – 数据集
-
FarmlandSRDataset: 读取所有图片,支持不重叠裁剪(每张256×256 → 4个128×128 patch)或整图使用。__getitem__中调用degrade_image生成LR,并执行随机翻转/旋转增强。 -
get_dataloaders: 按原始图像路径分层划分,保证同一图像的所有patch进入同一集合,返回DataLoader。
4. models.py – 网络结构
-
SRCNN: 先上采样→三层卷积(9,5,5)→输出HR -
ESPCN: 低分辨率空间卷积→亚像素卷积上采样 -
FSRCNN: 收缩-映射-扩张结构→转置卷积上采样 -
ESPCNWithSE: ESPCN + 简化的SE通道注意力(通道缩减比=8)
5. train.py – 训练流程
-
损失函数:
combined_loss = MSE + weight * SSIMLoss -
优化器:Adam,余弦退火学习率调度
-
早停:验证损失连续
PATIENCE轮不下降则停止 -
自动记录:每个epoch将
(epoch, train_loss, val_loss)写入output/loss_log.csv -
保存最佳模型:验证损失最小时保存
{MODEL_TYPE}_best.pth
6. evaluate.py – 评估
-
加载测试集,batch_size=1,记录推理时间
-
计算每张图的PSNR、SSIM,保存SR图到
output/test_results/ -
输出平均PSNR、SSIM、推理时间、FPS
7. demo.py – 单图超分
bash
python demo.py 图片路径 [模型名] # 模型名可选:srcnn, espcn, fsrcnn, espcn_se(默认)
生成 sr_result_{模型名}.png 和对比图。
五、完整操作流程
第1步:准备图片
将你的7000张256×256图片放入 data/high_res/。
第2步:修改配置(可选)
根据需要修改 config.py 中的退化参数、训练轮数、模型类型等。
第3步:训练模型
打开 Anaconda Prompt 并进入项目目录
-
打开 Anaconda Prompt。
-
输入
conda activate sr并回车。 -
输入
cd C:\Users\你的用户名\Desktop\farmland_sr(注意把“你的用户名”换成你自己的) -
运行训练脚本
python train.py
然后按回车。
你会看到以下输出(类似):
text
然后按回车。
你会看到以下输出(类似):
使用设备: cuda
找到 7000 张高分辨率图片
训练集: 4900 张, 验证集: 1400 张, 测试集: 700 张
模型: espcn_se, 参数量: 37.58 KB
训练中: 0%| | 0/2450 [00:00<?, ?it/s]
-
训练会持续很久(可能几个小时),你可以挂机。
-
每完成一个“轮次”(epoch),会打印当前损失和验证损失,例如
Epoch 001 | 训练损失: 0.115765 | 验证损失: 0.094575。 -
当验证损失连续多轮不再下降时,程序会自动停止(早停),并保存最佳模型到
output文件夹 -
随时可以按
Ctrl + C停止训练(不会损坏模型,但最好让它跑完)。 -
如果想查看训练进度,可以打开
output文件夹,里面有一个loss_log.csv文件,记录了每个 epoch 的损失。
第4步:评估模型
bash
python evaluate.py
输出PSNR、SSIM、推理时间,重建图保存在 output/test_results/。
这会:
-
自动加载
output文件夹中当前MODEL_TYPE对应的最佳模型。 -
对测试集(700 张图片)进行超分重建。
-
计算平均 PSNR、SSIM、每张图的推理时间。
-
输出结果,例如:
PSNR: 24.85 dB
SSIM: 0.5704
平均推理时间: 2.80 ms/张
每秒可处理: 357.1 张
超分结果已保存至: output\test_results
-
同时,会在
output\test_results中生成test_xxxx_sr.png(重建的高清图)和test_xxxx_lr.png(低分辨率输入图),你可以打开看看重建效果。
如果你想评估不同模型(如 SRCNN):修改 config.py 中的 MODEL_TYPE = 'srcnn',保存后再次运行 python evaluate.py(前提是你已经训练过该模型,即 output/srcnn_best.pth 存在)
第5步:单张图片超分演示
bash
python demo.py test4.jpg espcn_se
程序会:
-
将这张图片缩放到 64×64(模拟低分辨率输入)。
-
加载模型进行 4 倍超分,得到 256×256 的高清图。
-
在当前目录下生成
sr_result.png(超分结果)和sr_result_compare.png(对比图,显示原始、低分辨率、超分结果)。 -
如果系统支持,还会弹出一个窗口显示对比图。
你可以用图片查看器打开 sr_result.png,看看病斑和纹理是否更清晰。
第6步:绘制损失曲线(可选)
bash
python plot_loss.py
生成 output/loss_curve.png
运行程序会生成如下图片
六、常见问题快速排查
| 问题 | 解决办法 |
|---|---|
NameError: name 'lr_size' is not defined |
在 data_utils.py 中将 lr_size 改为 self.lr_size |
| 模型加载尺寸不匹配 | 检查 models.py 中的通道数与保存的权重是否一致;若不匹配,删除旧权重重新训练 |
SSIM计算报错 win_size exceeds image extent |
在 utils.py 的 calculate_ssim 中动态调整窗口,并指定 channel_axis=2 |
| 训练时显存不足 | 减小 BATCH_SIZE(例如 4)或降低图像尺寸 |
常见问题与解决方法
| 问题现象 | 可能原因 | 解决方法 |
|---|---|---|
python 不是内部或外部命令 |
没有安装 Python 或没有激活环境 | 确保你已经在 Anaconda Prompt 中激活了 sr 环境 |
ModuleNotFoundError: No module named 'torch' |
没有安装 PyTorch | 执行 pip install torch... 那一行 |
NameError: name 'lr_size' is not defined |
代码中变量名错误 | 在 data_utils.py 中将 lr_size 改为 self.lr_size |
CUDA out of memory |
显存不足 | 修改 config.py 中 BATCH_SIZE = 4(或更小),重新运行 |
| 训练时验证损失一直不下降 | 可能是学习率太大或模型有问题 | 将 LEARNING_RATE = 1e-4 试试 |
评估时报错 win_size exceeds image extent |
SSIM 窗口太大 | 已修复,请使用最新的 utils.py(其中 calculate_ssim 会自适应窗口) |
RuntimeError: Error(s) in loading state_dict |
模型结构与权重不匹配 | 删除 output 中的旧 .pth 文件,重新训练;或者恢复 models.py 到旧版本 |
七、论文数据对应关系
| 表格 | 数据来源 |
|---|---|
| 损失收敛曲线 | 运行 plot_loss.py |
| 主观效果对比图 | 运行 demo.py 对典型图片 |
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)