图像去模糊:ECPeNet

paper csjcai.github.io
csjcai/ECPeNet github.com图标
该文是香港理工张磊团队提出的一种基于极限通道先验的动态场景去模糊方法。
深度学习方法在动态场景去模糊领域取得了极大的进步。作者认为: 这些方法在训练数据集上通过重建损失学习得到,集成合适的图像先验信息作为正则项可以进一步提升去模糊性能。为此,作者提出一种极限通道先验嵌入网络(ECPeNet)以集成极限通道先验信息(如亮度通道与暗通道先验信息)进一步提升去模糊性能,作者设计了一种新颖的可训练的极限通道先验计算单元,同时引入稀疏正则调控ECPeNet网络训练学习。更进一步,作者还设计了一个多尺度架构以更好探索跨尺度的信息传递。作者在GoPro与Kohler两个数据集上验证了所提方法的SOTA性能(定量分析与视觉效果,速度并不大哦)。

Abstract

​ 作者在文中提到:(1) 基于优化的方法可以集成各种正则先验信息辅助盲去模糊求解,但存在过于耗时与模糊和过于简单问题,这限制了其性能;(2) 基于深度学习的方法受益于端到端的训练可以快速而灵活的处理空间可变模糊问题,但这种端到端的方式可能会限制其职能学习特定的先验信息。为集成传统优化方法与深度学习两者的优点,作者提出:是否可以探索模型的先验信息以约束网络架构与损失而提升去模糊的性能

​ 为此,作者提出了本文的关键成分:极限通道先验嵌入计算单元。在这些先验信息熵添加稀疏正则化以正则化训练过程中的解空间,因而将极限通道先验集成到ECPeNet中。与此同时,还采用与其他去模糊方法类似的多尺度架构,进一步提升网络的去模糊性能。

​ 本文的主要贡献包含以下几个方面:

  • 提出一种新颖的可训练的计算单元:极限通道嵌入层。也许是去模糊领域首个先验信息;
  • 提出一种新的多尺度架构以充分探索不同尺度下的信息传递;
  • 在GoPro与Kohler数据集上取得了SOTA性能。

Method

​ 上图给出了作者提出的多尺度ECPeNet网络架构示意图。从中看出:它包含三个尺度,每个尺度包含编码模块、特征映射模块以及解码模块。

​ 先简单的说明网络内部的参数配置,所有卷积核大小均为3x3,步长为1,激活函数为PReLU,除了最后输出与ECPeL外其他所有卷积输出通道数均为64,ECPel的三个分支卷积输出分别是3,64,3。另外,该网络中的上采样与下采样均采用shuffle操作得到(可以参考文末提供的参考代码)。关于RIRBlock上图已经给出了架构示意图,按照上图不难写出相关代码。

ECPeL

​ 作者所提的ECPeeL用于集成模糊图像表达与极限先验信息对CNN的解空间进行正则化。它首先学习三个映射函数 [公式] 对传入特征进行提取三个心的特征,包含:用于传入下一层的特征 [公式] ,暗通道先验约束特征以及亮通道先验约束特征。然后采用拼接方式集成上述三个特征。ECPeL可以描述为:

[公式]

​ 为添加额外的先验信息,ECPeL采用了如下策略:

  • 提取亮与暗通道先验信息;
  • 在训练过程中添加$l_1$正则项以迫使其具有稀疏性。

​ 亮通道先验与暗通道先验分别定义如下(相关代码可以参考文末提供的参考代码):

[公式]

实际上,亮通道与暗通道就是传统图像去雾领域的先验信息,都是跨通道最大/小信息,外加局部最大/最小滤波。

损失函数

​ 已有的深度去模糊方法往往采用L1损失进行训练,作者在L1损失的基础上添加了极限通道先验信息正则项,此时损失函数定义如下:

[公式]

Experiments

​ 在训练过程中,作者采用了Caffe框架,训练数据集为GoPro与Kohler,图像块大小为256x256,BatchSize=10, [公式] ,网络参数初始化采用的是Xavier,优化器采用的Adam(0.9, 0.999),学习率为0.0001,总计训练600K迭代,花费140小时。另外,还对数据进行随机旋转与镜像、添加高斯噪声等进行增广。

​ 下图给出了所提方法与其他SOTA方法在GoPro数据的性能对比以及视觉效果对比,更多实验效果与分析详见原文,这里不再赘述。

Conclusion

​ 作者提出一种简单而有效的极限通道先验嵌入网络,它集成一种新颖的可训练的极限通道先验嵌入计算单元,旨在集成通道先验信息以提升深度网络的去模糊性能。通过在浅层特征上提取该通道先验信息并迫使其具有稀疏性,ECPeNet可以正则化解空间。另外,ECPeNet还采用了多尺度方式以集成跨尺度的信息。受益于所提出的通道先验信息,ECPeNet优于已有的其他SOTA去模糊方法。在极具挑战性的GoPro数据及上,所提方法至少优于其他方法0.84dB指标(PSNR)。

参考代码

​ 仔细看了一下这篇论文,发现这篇创新点主要是通道先验信息的引入。因此这里的关键也就是如何利用计算这两个先验信息了,另外论文还提到了使用shuffle操作进行下采样与上采样操作。Pytorch中已提供有上采样的计算单元,根据其思想再整理下下采样单元即可。这里给出了这篇论文的几个核心的计算单元,网络架构部分的代码就不再添加,看懂了架构写代码应该不是什么难事!感兴趣复现的朋友欢迎沟通交流。

# 暗通道先验计算单元
def minpool(feat, ksize, stride=1):
    pad = (ksize - 1)// 2
    N, C, H, W = feat.size()
    feat = F.pad(feat, (pad, pad, pad, pad),mode='reflect')
    feat = feat.unfold(2,ksize,stride).unfold(2,ksize,stride)
    feat = feat.permute(0,2,3,1,4,5).contiguous()
    feat = feat.view(N,H,W,-1)
    out  = feat.min(-1)[0]
    out  = out.unsqueeze(1)
    return out

# 量通道先验计算单元
def minpool(feat, ksize, stride=1):
pad = (ksize - 1)// 2
N, C, H, W = feat.size()
feat = F.pad(feat, (pad, pad, pad, pad),mode=‘reflect’)
feat = feat.unfold(2,ksize,stride).unfold(2,ksize,stride)
feat = feat.permute(0,2,3,1,4,5).contiguous()
feat = feat.view(N,H,W,-1)
out = feat.min(-1)[0]
out = out.unsqueeze(1)
return out

# shuffle下采样计算单元
def shuffle_down(inputs, scale):
N, C, iH, iW = inputs.size()
oH = iH // scale
oW = iW // scale

<span class="n">output</span> <span class="o">=</span> <span class="n">inputs</span><span class="o">.</span><span class="n">view</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="n">C</span><span class="p">,</span> <span class="n">oH</span><span class="p">,</span> <span class="n">scale</span><span class="p">,</span> <span class="n">oW</span><span class="p">,</span> <span class="n">scale</span><span class="p">)</span>
<span class="n">output</span> <span class="o">=</span> <span class="n">output</span><span class="o">.</span><span class="n">permute</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">4</span><span class="p">)</span><span class="o">.</span><span class="n">contiguous</span><span class="p">()</span>
<span class="k">return</span> <span class="n">output</span><span class="o">.</span><span class="n">view</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">oH</span><span class="p">,</span> <span class="n">oW</span><span class="p">)</span>

# 极限通道先验嵌入计算单元
class ECPeBlock(nn.Module):
def init(self):
super().init()
self.convB = nn.Conv2d(inc, 3, ksize, stride, pad)
self.relub = nn.PReLU()
self.convO = nn.Conv2d(inc, 64, ksize, stride, pad)
self.reluo = nn.PReLU()
self.convD = nn.Conv2d(inc, 3, ksize, stride, pad)
self.relud = nn.PReLU()
def forward(self, x):
bright = self.relub(self.convB(x))
output = self.reluo(self.convO(x))
darker = self.relud(self.convD(x))
return torch.cat([bright,output,darker],1),bright,darker

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值