978 字
5 分钟
图像去雨:用深度学习让雨天照片变清晰

项目背景#

下雨天拍的照片总是被雨滴模糊?我开发了一个基于深度学习的单幅图像去雨系统,能够从一张带雨的照片中自动去除雨纹,恢复清晰画面。

效果#

输入一张雨天照片,输出一张干净的无雨图像。系统使用残差学习策略——网络预测的是「雨纹层」,然后从原图中减去:

去雨结果 = 输入图像 - 预测的雨纹

这种设计比直接预测干净图像更稳定,收敛更快。

三种网络架构#

1. U-Net(入门级)#

经典的编码器-解码器结构,带跳跃连接:

输入 → [编码器: 64→128→256→512] → [解码器: 512→256→128→64] → 输出
↓ skip connections ↓

简单但有效,适合理解去雨任务的基本原理。

2. DerainResNet(进阶级)#

基于 ResNet 的分组残差块设计:

  • 4 组残差块,每组 3 个 Block
  • 深度可分离卷积减少参数量
  • 提供 DerainResNetSmall 轻量版,适合移动端

3. MPRNet(SOTA 级)#

来自 CVPR 2021 论文《Multi-Stage Progressive Image Restoration》,这是目前效果最好的模型:

Stage 1: 4 个 1/4 尺寸 patch → 编码器-解码器 + CAB 注意力
↓ SAM(监督注意力模块)
Stage 2: 2 个 1/2 尺寸 patch + 跨阶段特征融合
↓ SAM
Stage 3: 全分辨率处理(ORSNet)

关键组件:

  • CAB(通道注意力块):自动学习哪些通道更重要
  • SAM(监督注意力模块):生成注意力图,聚焦关键区域
  • CSFF(跨阶段特征融合):让不同阶段的信息相互补充

总参数量约 3.6M,非常轻量。

合成雨纹数据生成#

训练数据是合成的。我实现了一个雨纹生成器,可以生成两种雨效:

线条雨(Streak)

  • 可配置:角度、长度、粗细、透明度
  • 支持运动模糊

雨滴(Drop)

  • 椭圆形雨滴
  • 可配置大小和密度

高级版还支持雾效、多种雨型混合、可变强度。

generator = AdvancedRainGenerator()
rainy_image = generator.generate(
clean_image,
rain_type='streak',
intensity=0.7,
angle=75,
length=30
)

训练流程#

Loss: L1 Loss
Optimizer: Adam (weight_decay=1e-5)
Scheduler: CosineAnnealingLR (eta_min=1e-6)
最优模型: 按验证集 PSNR 保存

数据增强:

  • 随机裁剪 256×256 patch
  • 随机水平/垂直翻转
  • 随机 90° 旋转

评估指标#

从零实现了两个经典指标:

PSNR(峰值信噪比)

psnr = 10 * log10(MAX² / MSE)

SSIM(结构相似性)

SSIM = (2μxμy + C1)(2σxy + C2) / ((μx² + μy² + C1)(σx² + σy² + C2))

提供 NumPy 和 PyTorch 两个版本,以及批量评估的 MetricCalculator 类。

Gradio Web UI#

一行命令启动交互式界面:

Terminal window
python app.py
# 或双击 启动去雨界面.bat

打开 http://127.0.0.1:7860,拖入照片就能看到去雨效果。

优雅降级#

系统设计了多层降级:

  1. 有 MPRNet 预训练权重 → 用 MPRNet(最佳效果)
  2. 有自训练的 U-Net/DerainResNet 权重 → 用自训练模型
  3. 没有任何权重 → 用简易 CNN 演示(效果有限但能跑)

技术栈#

组件技术
框架PyTorch
模型U-Net / DerainResNet / MPRNet
数据OpenCV + Pillow
评估PSNR + SSIM(手写实现)
训练可视化TensorBoard + Matplotlib
Web UIGradio

遇到的坑#

  1. 输入尺寸必须是 8 的倍数:网络有 3 层 2× 下采样,不对齐会报错
  2. DataParallel 权重前缀:多卡训练保存的权重有 module. 前缀,加载时需要去掉
  3. 合成数据不等于真实雨纹:合成雨纹训练的模型在真实雨天照片上效果会打折扣,需要 domain adaptation
  4. MPRNet 内存占用大:全分辨率推理需要较大显存,4K 图片需要先缩小

这个项目让我把「残差学习」从一个名词变成了直觉:让网络学减去什么,比让它学生成什么容易得多。三种架构从入门到 SOTA 的梯度安排,也很适合作为图像复原任务的入门路径——先跑通 U-Net 理解流程,再用 MPRNet 追求效果。

图像去雨:用深度学习让雨天照片变清晰
https://theywh.me/posts/image-deraining/
作者
鸢尾花
发布于
2026-06-03
许可协议
CC BY-NC-SA 4.0