视频去雨滴任务的目标是从连续帧中估计并移除附着在镜头表面的雨滴退化分量。与单帧雨线去除不同,视频序列提供了相邻帧的背景信息,但雨滴本身的运动规律与场景深度、镜头参数耦合,使得简单的背景差分容易把真实运动边缘误判为雨滴。基于注意力机制的修复网络通过对特征图重新加权,将有限算力聚焦在雨滴覆盖区域,同时抑制无雨滴区域的错误扰动。

雨滴退化与普通雨线的关键差异
高空雨线通常表现为方向一致的细长条纹,具备明显的稀疏性和全局方向先验,单帧去雨线方法可以利用这种先验直接分离。而雨滴附着在镜头保护玻璃表面,形成的是局部大尺寸遮挡、模糊和折射。雨滴的形状、透明度以及对背景的扭曲程度会随焦距、对焦位置和入射光角度变化,远比雨线的叠加模型复杂。
如果直接沿用雨线去除中常用的加性模型,将观测帧表示为背景帧与雨滴残差的简单叠加,会在雨滴边缘产生高光残影。更合理的做法是把雨滴退化视为透明度图与空间变化模糊核的共同作用。但在端到端训练中,为了稳定收敛,多数模型仍输出雨滴残差图,再通过clean = input - residual的方式恢复背景。
这种残差学习路线需要网络准确判断哪些像素需要减去残差,以及减多少。如果对整幅图一视同仁,非雨滴区域容易被过度平滑。注意力机制恰好提供了一种软掩膜策略,让网络自动聚焦雨滴区域,避免了手工设计检测器的困难。
注意力机制如何定位并抑制雨滴
通道注意力的核心思想是判断哪些特征通道对雨滴更敏感。雨滴通常会引起局部高频变化、对比度异常和颜色偏移,这些信息可能集中在某些通道中。通过全局平均池化与最大池化提取通道统计量,再用一个小型卷积网络学习通道权重,可以增强有效通道并压缩冗余通道。
空间注意力则回答雨滴在图像中的具体位置。它对特征图沿通道方向做平均池化和最大池化,将两个二维图拼接后经过卷积和激活函数,生成与输入特征等宽高的空间权重图。该权重图与特征逐元素相乘,可以突出雨滴覆盖区域,同时抑制背景响应。
与纯卷积相比,注意力模块能够根据当前输入动态调整感受野内的响应强度。卷积核参数在空间上共享,对尺度变化和形状不规则雨滴的适应能力有限;而注意力通过全局上下文建模,对不同尺寸的雨滴具有更强的鲁棒性。实际项目中,轻量级的通道与空间注意力组合通常已能获得明显提升,若计算资源充足,可以进一步引入窗口自注意力或轴向注意力来捕获远程依赖。
视频时空建模与网络结构设计
单帧注意力无法区分静止雨滴与真实纹理,因此视频去雨滴必须利用时间维度。常见做法是取当前帧的前后相邻帧,通过光流或可变形卷积将邻帧特征对齐到当前帧。对齐后的特征保留了同一背景在不同时刻的观测,当某一位置被雨滴遮挡时,其他帧的对应区域可能不受影响。
典型网络采用编码器解码器结构,编码器提取多尺度特征,时序融合单元接收对齐后的多帧特征,注意力模块对融合特征重新加权,解码器最后重建残差图。时序融合单元可以选择ConvLSTM或GRU,它们能记忆雨滴在连续帧中的运动状态,但也带来额外显存开销。对于实时场景,可仅使用前一帧和后一帧构成三帧输入,并在编码器低分辨率特征层进行时序融合。
注意力模块在网络中的插入位置需要根据任务调整。若主干为U型结构,可以在编码器输出和跳连特征上分别施加通道注意力与空间注意力;若主干为循环结构,可以在每个时间步的融合特征之后施加注意力。这样能让注意力图随时间和尺度变化,而不是固定作用在单一特征层。
PyTorch实现:通道与空间注意力
下面先给出一个轻量级通道注意力与空间注意力的实现。代码中AdaptiveAvgPool2d和AdaptiveMaxPool2d负责提取全局统计信息,二者并用可以同时保留平均响应和雨滴造成的高亮峰值。
import torch
import torch.nn as nn
class ChannelAttention(nn.Module):
def __init__(self, channels, reduction=16):
super(ChannelAttention, self).__init__()
self.avg_pool = nn.AdaptiveAvgPool2d(1)
self.max_pool = nn.AdaptiveMaxPool2d(1)
self.fc = nn.Sequential(
nn.Conv2d(channels, channels // reduction, 1, bias=False),
nn.ReLU(inplace=True),
nn.Conv2d(channels // reduction, channels, 1, bias=False)
)
self.sigmoid = nn.Sigmoid()
def forward(self, x):
avg_out = self.fc(self.avg_pool(x))
max_out = self.fc(self.max_pool(x))
return self.sigmoid(avg_out + max_out)
class SpatialAttention(nn.Module):
def __init__(self, kernel_size=7):
super(SpatialAttention, self).__init__()
self.conv = nn.Conv2d(2, 1, kernel_size, padding=kernel_size // 2, bias=False)
self.sigmoid = nn.Sigmoid()
def forward(self, x):
avg_out = torch.mean(x, dim=1, keepdim=True)
max_out, _ = torch.max(x, dim=1, keepdim=True)
out = torch.cat([avg_out, max_out], dim=1)
out = self.conv(out)
return self.sigmoid(out)
第二个模块展示如何将通道注意力与空间注意力嵌入时空融合过程。输入包含当前帧特征和对齐后的相邻帧特征,先拼接融合,再依次经过通道注意力和空间注意力,最后与原特征做残差连接。
class RainDropAttentionFusion(nn.Module):
def __init__(self, in_channels):
super(RainDropAttentionFusion, self).__init__()
self.ca = ChannelAttention(in_channels)
self.sa = SpatialAttention()
self.fusion = nn.Sequential(
nn.Conv2d(in_channels * 2, in_channels, 3, padding=1),
nn.BatchNorm2d(in_channels),
nn.ReLU(inplace=True)
)
def forward(self, current_feat, temporal_feat):
concat_feat = torch.cat([current_feat, temporal_feat], dim=1)
fused = self.fusion(concat_feat)
ca_weight = self.ca(fused)
feat = fused * ca_weight
sa_weight = self.sa(feat)
feat = feat * sa_weight
return feat + current_feat
这段代码可以直接插入U-Net的跳连路径,也可以作为循环网络的时序融合模块。需要注意,通道注意力中的降维比例reduction不宜过小,否则会丢失信息;空间注意力卷积核大小通常取7,能在雨滴局部区域与计算量之间取得平衡。
损失函数与训练数据构建
视频去雨滴的监督数据通常需要成对的带雨滴视频和干净背景视频。真实采集时,可以用固定相机拍摄干净场景,再在镜头前放置滴水的透明玻璃板,控制水滴大小和分布。为了增加多样性,还可以改变玻璃板倾斜角度、水滴停留时间以及背景纹理类型。合成数据则通过物理渲染或生成对抗网络生成雨滴效果,但合成雨滴与真实雨滴在折射和模糊上仍存在差异。
训练损失一般由像素级损失、感知损失和对抗损失组成。像素级损失常用L1或L2约束残差图与真实雨滴残差接近,但单独使用容易造成背景平滑。感知损失利用预训练VGG网络提取特征,在特征空间比较重建结果与干净帧,有助于保留纹理和结构。对抗损失可以提升视觉自然度,但训练不稳定。对于注意力图,可以增加稀疏正则项或总变差正则项,避免注意力权重遍布整幅画面。
评估时除了PSNR和SSIM,还应该关注雨滴区域的局部重建质量。由于雨滴在画面中占比通常较小,全局PSNR可能掩盖雨滴去除不彻底的问题。可以预先标注雨滴掩膜,计算掩膜覆盖区域的PSNR,同时引入时间一致性误差来评估连续帧的抖动情况。
常见误区与调优建议
一个常见误区是把单帧雨线去除模型直接用于雨滴。雨线先验是方向稀疏,雨滴则是局部致密遮挡,二者退化机制不同。直接迁移会导致雨滴区域残留模糊,甚至在无雨滴区域出现伪影。改造时应优先引入时序融合模块,让模型利用相邻帧的干净背景信息。
另一个误区是只做单帧空间注意力,忽视时序对齐。未对齐的邻帧特征在融合时会产生重影,注意力图会错误地聚焦到运动边缘,而不是雨滴。光流估计的质量对最终效果影响很大,必要时可以使用轻量光流网络与去雨滴主干联合训练,让光流逐步适应雨滴区域。
调优时建议先在小尺寸输入上训练注意力模块,验证模块插入位置和损失权重,再逐步提高分辨率。混合精度和梯度裁剪有助于稳定训练,尤其在加入对抗损失后。对于实时视频任务,可以把通道注意力和空间注意力替换为更轻量的版本,并通过减少时序帧数或降低时序特征分辨率来控制延迟。