论文阅读——《Retinexformer: One-stage Retinex-based Transformer for Low-light Image Enhancement》

这篇具有很好参考价值的文章主要介绍了论文阅读——《Retinexformer: One-stage Retinex-based Transformer for Low-light Image Enhancement》。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


retinexformer: one-stage retinex-based transformer for low-light image enhan,1024程序员节,python,算法,图像处理,transformer,深度学习,论文阅读

前言

本文试图从原理和代码简单介绍低照度增强领域中比较新的一篇论文——Retinexformer,其效果不错,刷新了十三大暗光增强效果榜单。

论文名称:Retinexformer: One-stage Retinex-based Transformer for Low-light Image Enhancement

👀论文信息:由清华大学联合维尔兹堡大学和苏黎世联邦理工学院2023年8月发表在ICCV2023的一篇论文。
🎆论文地址:https://arxiv.org/abs/2303.06705
📌代码地址:https://github.com/caiyuanhao1998/Retinexformer
部分参考来源:https://zhuanlan.zhihu.com/p/657927878

论文主要贡献总结如下:
1.提出了首个与Retinex理论相结合的 Transformer 算法,命名为 Retinexformer。
2.推导了一个单阶段Retinex理论框架,名为 ORF(One-stage Retinex-based Framework),只需要一个阶段端到端的训练即可,流程简单。
3.设计了一种由光照引导的新型多头自注意机制,名为 IG-MSA(Illumination-Guided Multi-head Self-Attention,IG-MSA),将光照信息作为关键线索来引导长程依赖关系的捕获。

一、基本原理

  • 首先看这个网络的名字——Retinexformer,我们基本就能知道主要是结合两个方面来设计的:

1.1 Retinex理论。

  • 低照度增强领域中非常经典的理论,原理很简单,但是其应用范围非常广,很多的增强算法都是从该理论出发,包括之前介绍的SCI-Net也是从基于该理论。下面简单介绍一下该理论:
  • Retinex理论中将一幅图像 S S S看做是光照分量 I I I 和反射分量 R R R的乘积,即
    S = I ⊙ R S=I \odot R S=IR 反射分量 R 反射分量R 反射分量R 物体的本身性质决定的恒定的部分 物体的本身性质决定的恒定的部分 物体的本身性质决定的恒定的部分
    光照分量 I :受外界光照影响的部分 光照分量I:受外界光照影响的部分 光照分量I:受外界光照影响的部分
    ⊙ :表示逐元素相乘 \odot :表示逐元素相乘 :表示逐元素相乘

1.2 Transformer 算法。

  • 深度学习领域中必须提及的一个模型,其核心思想是将输入序列划分为多个子序列,并通过层级的编码-解码结构来处理这些子序列。它由编码器(Encoder)和解码器(Decoder)组成,每个部分都由多个相同的模块堆叠而成。
  • Transformer的原理部分可以参考:
    • 大佬写的Transformer很详细
    • 个人对部分代码的一些梳理

二、论文内容

  • 尽管有很多的传统算法或者深度学习算法都是基于Retinex理论的,但是都没有考虑到噪声伪影等一些退化因素,只是直接应用上面的图像分解的式子,而本文的一个亮点就是将这些退化因素考虑在内。

1.网络结构

  • 整个Retinexformer网络结构大体上分为两个部分:
    • illumination estimator(光照估计模块)
    • corruption restorer(退化修复器)
  • 其中, corruption restorer主要由多个Illumination-Guided Attention Block(光照引导的注意力块 ,IGAB)组成;IGAB又由两个归一化层(LN)、一个前馈网络(FFN)和一个光照引导的多头自注意力模块(Illumination-Guided Multi-head Self-Attention,IG-MSA)组成。
  • 注意:图中的 I I I 相当于上面公式中的 S S S , L L L 才是光照量 I I I
    retinexformer: one-stage retinex-based transformer for low-light image enhan,1024程序员节,python,算法,图像处理,transformer,深度学习,论文阅读

1.1 单阶段Retinex理论框架(One-stage Retinex-based Framework)

  • 根据上面的Retinex理论,若将噪声伪影等退化因素考虑在内,即在反射量和光照量中都加上扰动项。
    S = ( R + R ^ ) ⊙ ( I + I ^ ) = R ⊙ I + R ⊙ I ^ + R ^ ⊙ ( I + I ^ ) S = (R+\hat{R})\odot(I+\hat{I})=R\odot I+R\odot \hat{I}+\hat{R} \odot(I+\hat{I}) S=(R+R^)(I+I^)=RI+RI^+R^(I+I^)
  • 为了提高暗光图像 S S S 的亮度,两边同时乘上一个光照量 I ˉ \bar{I} Iˉ ,并且使得 I ˉ ⊙ I = 1 \bar{I}\odot{I} = 1 IˉI=1,从而有:
    S ⊙ I ˉ = R + R ⊙ ( I ^ ⊙ I ˉ ) + ( R ^ ⊙ ( I + I ^ ) ) ⊙ I ˉ S\odot{\bar{I}}=R+R\odot(\hat{I}\odot \bar{I})+(\hat{R}\odot{(I+\hat{I})})\odot{\bar{I}} SIˉ=R+R(I^Iˉ)+(R^(I+I^))Iˉ
  • 作者认为右边第二项 R ⊙ ( I ^ ⊙ I ˉ ) R\odot(\hat{I}\odot \bar{I}) R(I^Iˉ) 表示亮度增强过程中造成的曝光不足/过度曝光和色彩失真;而第三项中的 ( R ^ ⊙ ( I + I ^ ) ) (\hat{R}\odot{(I+\hat{I})}) (R^(I+I^))表示隐藏在黑暗中的噪声和伪影,在亮度增强过程中(乘上 I ˉ \bar{I} Iˉ)会被进一步放大。
    retinexformer: one-stage retinex-based transformer for low-light image enhan,1024程序员节,python,算法,图像处理,transformer,深度学习,论文阅读
  • C C C 表示所有的退化项, S l u S_{lu} Slu表示增强后的图像,有:
    S l u = R + C S_{lu}=R+C Slu=R+C
  • ORF的过程可以表示为:
    ( S l u , F l u ) = ε ( S , I p ) S e n = R ( S l u , F l u ) (S_{lu},F_{lu})=\varepsilon(S,I_{p})\\S_{en}=\mathcal{R}(S_{lu},F_{lu}) (SluFlu)=ε(S,Ip)Sen=R(Slu,Flu) ε :表示 l i g h t − u p (增强)过程 \varepsilon:表示light-up(增强)过程 ε:表示lightup(增强)过程
    S : 原始低照度图像 S:原始低照度图像 S:原始低照度图像
    I p :沿着通道维度计算每个像素的均值 I_{p}:沿着通道维度计算每个像素的均值 Ip:沿着通道维度计算每个像素的均值
    F l u :亮度的特征图 F_{lu}:亮度的特征图 Flu:亮度的特征图
    R :损失修复器。重建过程,修复退化项 \mathcal{R}:损失修复器。重建过程,修复退化项 R:损失修复器。重建过程,修复退化项

1.2 illumination estimator

  • 直接看代码部分:
    retinexformer: one-stage retinex-based transformer for low-light image enhan,1024程序员节,python,算法,图像处理,transformer,深度学习,论文阅读
class Illumination_Estimator(nn.Module):
    def __init__(
            self, n_fea_middle, n_fea_in=4, n_fea_out=3):  #__init__部分是内部属性,而forward的输入才是外部输入
        super(Illumination_Estimator, self).__init__()

        self.conv1 = nn.Conv2d(n_fea_in, n_fea_middle, kernel_size=1, bias=True)

        self.depth_conv = nn.Conv2d(
            n_fea_middle, n_fea_middle, kernel_size=5, padding=2, bias=True, groups=n_fea_in)

        self.conv2 = nn.Conv2d(n_fea_middle, n_fea_out, kernel_size=1, bias=True)

    def forward(self, img):
        # img:        b,c=3,h,w
        # mean_c:     b,c=1,h,w
        
        # illu_fea:   b,c,h,w
        # illu_map:   b,c=3,h,w
        
        mean_c = img.mean(dim=1).unsqueeze(1)
        # stx()
        input = torch.cat([img,mean_c], dim=1)

        x_1 = self.conv1(input)
        illu_fea = self.depth_conv(x_1)
        illu_map = self.conv2(illu_fea)
        return illu_fea, illu_map

1.3 光照引导的Transformer(Illumination-Guided Transformer,IGT)

retinexformer: one-stage retinex-based transformer for low-light image enhan,1024程序员节,python,算法,图像处理,transformer,深度学习,论文阅读

  • 设计IGT的作用是用来表示上式中的 R \mathcal{R} R,用来修复退化项。
  • 采用three-scale的U型架构(encoder-bottleneck-decoder)。
  • 下采样过程中, S l u S_{lu} Slu 经历一个 3 × 3 c o n v 3×3conv 3×3conv、一个 I G A B IGAB IGAB、一个 4 × 4 c o n v ( s t r i d e = 2 ) 4×4conv(stride=2) 4×4conv(stride=2)、两个 I G A B IGAB IGAB、一个 4 × 4 c o n v ( s t r i d e = 2 ) 4×4conv(stride=2) 4×4conv(stride=2),得到分层特征 F 0 、 F 1 、 F 2 F_{0}、F_{1}、F_{2} F0F1F2,然后 F 2 F_{2} F2又通过两个IGAB。
  • 设计对称结构作为上采样过程。经过上采样输出的是残差 S r e S_{re} Sre。最终输出的增强图像 S e n = S l u + S r e S_{en}=S_{lu}+S_{re} Sen=Slu+Sre
  • 代码实现部分:(个人感觉这部分代码在self.encoder部分和文中的结构貌似不太一致?不知道是不是自己理解错了😆)
class Denoiser(nn.Module):
    def __init__(self, in_dim=3, out_dim=3, dim=31, level=2, num_blocks=[2, 4, 4]):
        super(Denoiser, self).__init__()
        self.dim = dim
        self.level = level

        # Input projection
        self.embedding = nn.Conv2d(in_dim, self.dim, 3, 1, 1, bias=False)

        # Encoder
        self.encoder_layers = nn.ModuleList([])
        dim_level = dim
        for i in range(level):
            self.encoder_layers.append(nn.ModuleList([
                IGAB(
                    dim=dim_level, num_blocks=num_blocks[i], dim_head=dim, heads=dim_level // dim),
                nn.Conv2d(dim_level, dim_level * 2, 4, 2, 1, bias=False),
                nn.Conv2d(dim_level, dim_level * 2, 4, 2, 1, bias=False)
            ]))
            dim_level *= 2

        # Bottleneck
        self.bottleneck = IGAB(
            dim=dim_level, dim_head=dim, heads=dim_level // dim, num_blocks=num_blocks[-1])

        # Decoder
        self.decoder_layers = nn.ModuleList([])
        for i in range(level):
            self.decoder_layers.append(nn.ModuleList([
                nn.ConvTranspose2d(dim_level, dim_level // 2, stride=2,
                                   kernel_size=2, padding=0, output_padding=0),
                nn.Conv2d(dim_level, dim_level // 2, 1, 1, bias=False),
                IGAB(
                    dim=dim_level // 2, num_blocks=num_blocks[level - 1 - i], dim_head=dim,
                    heads=(dim_level // 2) // dim),
            ]))
            dim_level //= 2

        # Output projection
        self.mapping = nn.Conv2d(self.dim, out_dim, 3, 1, 1, bias=False)

        # activation function
        self.lrelu = nn.LeakyReLU(negative_slope=0.1, inplace=True)
        self.apply(self._init_weights)

    def _init_weights(self, m):
        if isinstance(m, nn.Linear):
            trunc_normal_(m.weight, std=.02)
            if isinstance(m, nn.Linear) and m.bias is not None:
                nn.init.constant_(m.bias, 0)
        elif isinstance(m, nn.LayerNorm):
            nn.init.constant_(m.bias, 0)
            nn.init.constant_(m.weight, 1.0)

    def forward(self, x, illu_fea):
        """
        x:          [b,c,h,w]         x是feature, 不是image
        illu_fea:   [b,c,h,w]
        return out: [b,c,h,w]
        """

        # Embedding
        fea = self.embedding(x)

        # Encoder
        fea_encoder = []
        illu_fea_list = []
        for (IGAB, FeaDownSample, IlluFeaDownsample) in self.encoder_layers:
            fea = IGAB(fea,illu_fea)  # bchw
            illu_fea_list.append(illu_fea)
            fea_encoder.append(fea)
            fea = FeaDownSample(fea)
            illu_fea = IlluFeaDownsample(illu_fea)

        # Bottleneck
        fea = self.bottleneck(fea,illu_fea)

        # Decoder
        for i, (FeaUpSample, Fution, LeWinBlcok) in enumerate(self.decoder_layers):
            fea = FeaUpSample(fea)
            fea = Fution(
                torch.cat([fea, fea_encoder[self.level - 1 - i]], dim=1))
            illu_fea = illu_fea_list[self.level-1-i]
            fea = LeWinBlcok(fea,illu_fea)

        # Mapping
        out = self.mapping(fea) + x

        return out
  • IG-MSA是这一部分的核心。
    illumination estimator输出的亮度特征图 F l u F_{lu} Flu作为每一个IG-MSA的输入。首先 F l u F_{lu} Flu变形为token,然后被分成K个heads:
    X = [ X 1 , X 2 , . . . , X k , ] X=[X_{1},X_{2},...,X_{k},] X=[X1,X2,...,Xk,]对每个heads将其投影为 Q , K , V Q,K,V QKV
    Q i = X i W Q i T , K i = X i W K i T , V i = X i W V i T Q_{i}=X_{i}W^{T}_{Q_{i}},K_{i}=X_{i}W^{T}_{K_{i}},V_{i}=X_{i}W^{T}_{V_{i}} Qi=XiWQiTKi=XiWKiTVi=XiWViT
    F l u F_{lu} Flu又变形成 Y Y Y Y = [ Y 1 , Y 2 , . . . , Y k , ] Y=[Y_{1},Y_{2},...,Y_{k},] Y=[Y1,Y2,...,Yk,]

计算每个 head的自注意力时用光照信息作为引导:
retinexformer: one-stage retinex-based transformer for low-light image enhan,1024程序员节,python,算法,图像处理,transformer,深度学习,论文阅读

  • 代码:
class IG_MSA(nn.Module):
    def __init__(
            self,
            dim,
            dim_head=64,
            heads=8,
    ):
        super().__init__()
        self.num_heads = heads
        self.dim_head = dim_head
        self.to_q = nn.Linear(dim, dim_head * heads, bias=False)
        self.to_k = nn.Linear(dim, dim_head * heads, bias=False)
        self.to_v = nn.Linear(dim, dim_head * heads, bias=False)
        self.rescale = nn.Parameter(torch.ones(heads, 1, 1))
        self.proj = nn.Linear(dim_head * heads, dim, bias=True)
        self.pos_emb = nn.Sequential(
            nn.Conv2d(dim, dim, 3, 1, 1, bias=False, groups=dim),
            GELU(),
            nn.Conv2d(dim, dim, 3, 1, 1, bias=False, groups=dim),
        )
        self.dim = dim

    def forward(self, x_in, illu_fea_trans):
        """
        x_in: [b,h,w,c]         # input_feature
        illu_fea: [b,h,w,c]         # mask shift? 为什么是 b, h, w, c?
        return out: [b,h,w,c]
        """
        b, h, w, c = x_in.shape
        x = x_in.reshape(b, h * w, c)
        q_inp = self.to_q(x)
        k_inp = self.to_k(x)
        v_inp = self.to_v(x)
        illu_attn = illu_fea_trans # illu_fea: b,c,h,w -> b,h,w,c
        q, k, v, illu_attn = map(lambda t: rearrange(t, 'b n (h d) -> b h n d', h=self.num_heads),
                                 (q_inp, k_inp, v_inp, illu_attn.flatten(1, 2)))
        v = v * illu_attn
        # q: b,heads,hw,c
        q = q.transpose(-2, -1)
        k = k.transpose(-2, -1)
        v = v.transpose(-2, -1)
        q = F.normalize(q, dim=-1, p=2)
        k = F.normalize(k, dim=-1, p=2)
        attn = (k @ q.transpose(-2, -1))   # A = K^T*Q
        attn = attn * self.rescale
        attn = attn.softmax(dim=-1)
        x = attn @ v   # b,heads,d,hw
        x = x.permute(0, 3, 1, 2)    # Transpose
        x = x.reshape(b, h * w, self.num_heads * self.dim_head)
        out_c = self.proj(x).view(b, h, w, c)
        out_p = self.pos_emb(v_inp.reshape(b, h, w, c).permute(
            0, 3, 1, 2)).permute(0, 2, 3, 1)
        out = out_c + out_p

        return out

实验结果

retinexformer: one-stage retinex-based transformer for low-light image enhan,1024程序员节,python,算法,图像处理,transformer,深度学习,论文阅读

个人看法

  • 只给了PSNR和SSIM两个评价指标,缺少一些无参考图像质量评价。

  • 实际测试的效果发现图片中较亮的区域很容易出现过曝和色彩失真的问题:

  • 测试图片增强前后

    • example 1
      retinexformer: one-stage retinex-based transformer for low-light image enhan,1024程序员节,python,算法,图像处理,transformer,深度学习,论文阅读
      retinexformer: one-stage retinex-based transformer for low-light image enhan,1024程序员节,python,算法,图像处理,transformer,深度学习,论文阅读

    • example 2
      retinexformer: one-stage retinex-based transformer for low-light image enhan,1024程序员节,python,算法,图像处理,transformer,深度学习,论文阅读
      retinexformer: one-stage retinex-based transformer for low-light image enhan,1024程序员节,python,算法,图像处理,transformer,深度学习,论文阅读文章来源地址https://www.toymoban.com/news/detail-801143.html

总结

  • Retinexformer通过分析低曝光场景中隐藏的噪声伪影以及点亮过程带来的影响,将扰动项引入到原始的Retinex模型中,构建了一个新的基于Retinex的框架ORF。然后设计了一个利用ORF捕获的光照信息来指导不同光照条件下区域的长程依赖和相互作用的IGT。最后通过将IGT插入到ORF中得到了完整的Retinexformer模型。

到了这里,关于论文阅读——《Retinexformer: One-stage Retinex-based Transformer for Low-light Image Enhancement》的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【AI面试】目标检测中one-stage、two-stage算法的内容和优缺点对比汇总

    在深度学习领域中,图像分类,目标检测和目标分割是三个相对来说较为基础的任务了。再加上图像生成(GAN,VAE,扩散模型),keypoints关键点检测等等,基本上涵盖了图像领域大部分场景了。 尤其是在目标检测,一直是各大比赛 (Pascal VOC, COCO, ImageNet) 的主要任务。与此

    2024年02月12日
    浏览(27)
  • 图像 检测 - FCOS: Fully Convolutional One-Stage Object Detection (ICCV 2019)

    声明:此翻译仅为个人学习记录 文章信息 标题: FCOS: Fully Convolutional One-Stage Object Detection (ICCV 2019) 作者: Zhi Tian, Chunhua Shen*, Hao Chen, Tong He (*Corresponding author) 文章链接:https://openaccess.thecvf.com/content_ICCV_2019/papers/Tian_FCOS_Fully_Convolutional_One-Stage_Object_Detection_ICCV_2019_paper.pdf 文章代

    2024年02月15日
    浏览(32)
  • FCOS3D: Fully Convolutional One-Stage Monocular 3D Object Detection

    Paper name FCOS3D: Fully Convolutional One-Stage Monocular 3D Object Detection Paper Reading Note URL: https://arxiv.org/pdf/2104.10956.pdf 基于 Fcos 改进的 3d 检测方案,在 NeurIPS 2020 的 nuScenes 3d 检测比赛上取得了第一名成绩 Fcos3d 方案 将 7-DoF 3D 目标解耦为 2D 和 3D 的属性 考虑对象的二维比例,将对象分布到

    2023年04月08日
    浏览(52)
  • 【半监督学习】5、Efficient Teacher | 专为 one-stage anchor-based 方法设计的半监督目标检测方法

    论文:Efficient Teacher: Semi-Supervised Object Detection for YOLOv5 出处:阿里 时间:2023.03 目标检测近年来的进展离不开大量的标注数据,但数据标识昂贵且耗时。 故此,半监督方法被提出,通过自动生成伪标签来利用大量的未标注数据。 目前的半监督学习有如下三个最重要的挑战:

    2024年02月05日
    浏览(46)
  • Retinexformer 论文阅读笔记

    清华大学、维尔兹堡大学和苏黎世联邦理工学院在ICCV2023的一篇transformer做暗图增强的工作,开源。 文章认为,Retinex的 I = R ⊙ L I=Rodot L I = R ⊙ L 假设干净的R和L,但实际上由于噪声,并不干净,所以分别为L和R添加干扰项,把公式改成如下: 本文采用先预测 L ‾ overline L

    2024年01月21日
    浏览(28)
  • Low-Light Image Enhancement via Self-Reinforced Retinex Projection Model 论文阅读笔记

    这是马龙博士2022年在TMM期刊发表的基于改进的retinex方法去做暗图增强(非深度学习)的一篇论文 文章用一张图展示了其动机,第一行是估计的亮度层,第二列是通常的retinex方法会对估计的亮度层进行RTV约束优化,从而产生平滑的亮度层,然后原图除以亮度层产生照度层作为

    2024年02月16日
    浏览(34)
  • 【论文阅读】One For All: Toward Training One Graph Model for All Classification Tasks

    会议: 2024-ICLR-UNDER_REVIEW 评分:6,6,6,10 作者:Anonymous authors 文章链接:ONE FOR ALL: TOWARDS TRAINING ONE GRAPHMODEL FOR ALL CLASSIFICATION TASKS 代码链接:ONE FOR ALL: TOWARDS TRAINING ONE GRAPHMODEL FOR ALL CLASSIFICATION TASKS  设计一个能够解决多个任务的模型是人工智能长期发展的一个目标。最近,

    2024年01月18日
    浏览(31)
  • RIS 系列 Beyond One-to-One: Rethinking the Referring Image Segmentation 论文阅读笔记

    写在前面   又是一周,没思路调代码囧么办?当然是继续淦论文了,(┬_┬) 论文地址:Beyond One-to-One: Rethinking the Referring Image Segmentation 代码地址:https://github.com/toggle1995/RIS-DMMI 收录于:ICCV2023 Ps:2023 年每周一篇博文阅读笔记,主页 更多干货,欢迎关注呀,期待 6 千粉丝

    2024年02月20日
    浏览(29)
  • Low-Light Image Enhancement via Stage-Transformer-Guided Network 论文阅读笔记

    这是TCSVT 2023年的一篇暗图增强的论文 文章的核心思想是,暗图有多种降质因素,单一stage的model难以实现多降质因素的去除,因此需要一个multi-stage的model,文章中设置了4个stage。同时提出了用预设query向量来代表不同的降质因素,对原图提取的key 和value进行注意力的方法。

    2024年02月16日
    浏览(29)
  • One-4-All: Neural Potential Fields for Embodied Navigation 论文阅读

    题目 :One-4-All: Neural Potential Fields for Embodied Navigation 作者 :Sacha Morin, Miguel Saavedra-Ruiz 来源 :arXiv 时间 :2023 现实世界的导航可能需要使用高维 RGB 图像进行长视野规划,这对基于端到端学习的方法提出了巨大的挑战。 目前的半参数方法通过将学习的模块与环境的拓扑记忆相

    2024年02月14日
    浏览(23)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包