【传知代码】从零开始搭建图像去雾神经网络-论文复现

news2024/11/20 4:36:30

文章目录

  • 概述
  • 原理介绍
    • 网络结构
  • 核心逻辑
    • 迁移学习子网
    • 数据拟合子网
  • 环境配置
    • 训练本次复现代码所用数据集
    • 测试本次复现代码所用的评价指标
  • 结果展示
    • 在O-Haze数据集上的结果
    • 在I-Haze数据集上的结果
  • 小结

本文涉及的源码可从从零开始搭建图像去雾神经网络该文章下方附件获取

本文复现了一种简单而有效的基于集成学习的双分支非均匀去雾神经网络。该方法使用一个双分支神经网络分别处理上述问题,然后通过一个可学习的融合尾映射它们的不同特征。
论文地址:https://arxiv.org/pdf/2104.08902.pdf

概述

图像去雾神经网络的应用范围相当广泛:

  1. 交通和安全领域:在交通监控和自动驾驶系统中,清晰的图像对于准确识别和判断道路和交通状况至关重要。然而,由于雾霾的存在,图像质量下降,给交通监控和自动驾驶系统带来了困难。图像去雾技术可以应用于这些领域,提高交通监控和自动驾驶系统的可靠性和安全性。
  2. 航海领域:在雾霾天气下,船舶航行的安全性会受到严重影响。图像去雾技术可以提高船舶雾霾天气下入港效率,保障航行安全。
  3. 目标跟踪领域:在目标跟踪系统中,往往要求有较为清晰的输入。图像去雾技术可以在雾霾天气条件下为这些系统提供依旧清晰的输入,保证这类系统的正常识别跟踪。

原理介绍

网络结构

基于集成学习的双分支非均质去雾网络由两个子网络组成,即迁移学习子网和数据拟合子网。每个子网有着特定的目的:迁移学习子网利用预先训练的权重从输入图像中提取鲁棒全局表示;数据拟合子网对当前数据进行处理。融合层采用这两个子网络的级联特征图,并输出无雾图像。

在这里插入图片描述

核心逻辑

迁移学习子网

迁移学习子网是一个编码器-解码器结构的网络。该子网络使用Res2Net作为编码器,因为它在分类任务上有很好的性能。具体来说,在编码器中,该网络只使用了Res2Net的前端部分,没有使用全连接层。Res2Net由ResNet改进,传统的ResNet是一个瓶颈结构,由1×1、3×3、1×1的三层不同大小的卷积层组成。Res2Net为了能够在残差模块中实现多尺度多通道,将中间的3×3模块由Bottle2neck实现。
Bottle2neck的实现代码如下,首先通过torch.split拆分特征向量,除了第一个分支经过卷积之外,拆出来的每个分支通过3x3的卷积之后与下一个分支进行拼接之后分两步,一步保存继续,一步再与下一个分支做拼接。将一个3×3卷积层替换为对每个拆分的通道的3×3卷积使得该模块在不增加额外参数量的同时,泛化性能增强。

​```class Bottle2neck(nn.Module):
    expansion = 4

    def __init__(self, inplanes, planes, stride=1, downsample=None, baseWidth=26, scale=4, stype='normal'):

        super(Bottle2neck, self).__init__()

        width = int(math.floor(planes * (baseWidth / 64.0)))
        self.conv1 = nn.Conv2d(inplanes, width * scale, kernel_size=1, bias=False)
        self.bn1 = nn.BatchNorm2d(width * scale)

        if scale == 1:
            self.nums = 1
        else:
            self.nums = scale - 1
        if stype == 'stage':
            self.pool = nn.AvgPool2d(kernel_size=3, stride=stride, padding=1)
        convs = []
        bns = []
        for i in range(self.nums):
            convs.append(nn.Conv2d(width, width, kernel_size=3, stride=stride, padding=1, bias=False))
            bns.append(nn.BatchNorm2d(width))
        self.convs = nn.ModuleList(convs)
        self.bns = nn.ModuleList(bns)

        self.conv3 = nn.Conv2d(width * scale, planes * self.expansion, kernel_size=1, bias=False)
        self.bn3 = nn.BatchNorm2d(planes * self.expansion)

        self.relu = nn.ReLU(inplace=True)
        self.downsample = downsample
        self.stype = stype
        self.scale = scale
        self.width = width

    def forward(self, x):
        residual = x

        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        spx = torch.split(out, self.width, 1)
        for i in range(self.nums):
            if i == 0 or self.stype == 'stage':
                sp = spx[i]
            else:
                sp = sp + spx[i]
            sp = self.convs[i](sp)
            sp = self.relu(self.bns[i](sp))
            if i == 0:
                out = sp
            else:
                out = torch.cat((out, sp), 1)
        if self.scale != 1 and self.stype == 'normal':
            out = torch.cat((out, spx[self.nums]), 1)
        elif self.scale != 1 and self.stype == 'stage':
            out = torch.cat((out, self.pool(spx[self.nums])), 1)

        out = self.conv3(out)
        out = self.bn3(out)

        if self.downsample is not None:
            residual = self.downsample(x)

        out += residual
        out = self.relu(out)

        return out

此外,该网络采用了由通道注意力模块(CA)和像素注意力模块(PA)组成的特征注意作为注意力模块,插入在网络的高维部分以提取图像的结构特征和细节特征。
通道注意力CA的代码如下:
解码器部分,该网络使用用于图像超分辨率恢复的Pixel Shuffle作为该子网中的上采样模块。该模块可以将低分辨的特征图,通过卷积和多通道间的重组得到高分辨率的特征图,在实现时可以直接使用torch库中的nn.PixelShuffle函数,代码如下。
该网络受enhanced pix2pix dehazing network (EPDN)的启发,使用。在训练阶段,在特征进入融合层之前引入了一个增强模块。该模块使用了DCPDN中的金字塔池化模块,以两个3×3的卷积层作为开端,输出结果经平均池化层下采样为4×、8×、16×和32×四个不同尺寸的特征图。不同尺度的特征图提供不同的感受野,帮助图像在不同尺度上重建图像。之后,不同尺度的特征图由1×1卷积层进行降维并恢复到与原始图像尺寸相同的大小,最后与开端卷积层的输出进行拼接,作为最后3×3卷积层的输入。该模块将不同尺度的特征细节融入到最终的结果,起到对恢复的图像特征进行保持增强的作用。该模块的代码如下。

​```class Enhancer(nn.Module):
	def __init__(self, in_channels, out_channels):
		super(Enhancer, self).__init__()

		self.relu = nn.LeakyReLU(0.2, inplace=True)

		self.tanh = nn.Tanh()

		self.refine1 = nn.Conv2d(in_channels, 20, kernel_size=3, stride=1, padding=1)
		self.refine2 = nn.Conv2d(20, 20, kernel_size=3, stride=1, padding=1)

		self.conv1010 = nn.Conv2d(20, 1, kernel_size=1, stride=1, padding=0)
		self.conv1020 = nn.Conv2d(20, 1, kernel_size=1, stride=1, padding=0)
		self.conv1030 = nn.Conv2d(20, 1, kernel_size=1, stride=1, padding=0)
		self.conv1040 = nn.Conv2d(20, 1, kernel_size=1, stride=1, padding=0)

		self.refine3 = nn.Conv2d(20 + 4, out_channels, kernel_size=3, stride=1, padding=1)
		#self.upsample = F.upsample_nearest
		self.upsample=F.interpolate

		self.batch1 = nn.InstanceNorm2d(100, affine=True)

	def forward(self, x):
		dehaze = self.relu((self.refine1(x)))
		dehaze = self.relu((self.refine2(dehaze)))
		shape_out = dehaze.data.size()

		shape_out = shape_out[2:4]

		x101 = F.avg_pool2d(dehaze, 32)

		x102 = F.avg_pool2d(dehaze, 16)

		x103 = F.avg_pool2d(dehaze, 8)

		x104 = F.avg_pool2d(dehaze, 4)

		x1010 = self.upsample(self.relu(self.conv1010(x101)), size=shape_out)
		x1020 = self.upsample(self.relu(self.conv1020(x102)), size=shape_out)
		x1030 = self.upsample(self.relu(self.conv1030(x103)), size=shape_out)
		x1040 = self.upsample(self.relu(self.conv1040(x104)), size=shape_out)

		dehaze = torch.cat((x1010, x1020, x1030, x1040, dehaze), 1)
		dehaze = self.tanh(self.refine3(dehaze))

		return dehaze

总览整个迁移子网络,编码器模块加载比随机初始化参数的模型更具鲁棒性的ImageNet[作为预训练参数,但由于其仅使用了Res2net的前端部分,容易使网络丢失恢复图像细节的重要信息。为了改善该问题,本方法建立了第二个子网——数据拟合子网。

数据拟合子网

数据拟合子网由多个残差注意力模块组成,每个残差注意力模块由卷积层和通道注意力组成。对于残差注意力模块的实现如下所示,通道注意力模块有两条分支,一条负责提取不同的通道特征,另一条负责生成特征权重,最后将两个结果进行融合得到通道特征权重。通道注意力的使用突出了显著特征,增强了模型对数据的拟合能力。

​```class Residual_CA(nn.Module):
    def __init__(self, channels):
        super(Residual_CA, self).__init__()
        self.PointWise = nn.Conv2d(channels, channels, 1)
        self.RELU = nn.ReLU()
        self.GlobalPlooling = nn.AvgPool2d(1)
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        out1 = self.PointWise(x)
        out1 = self.RELU(out1)
        out1 = self.PointWise(out1)

        out2 = self.GlobalPlooling(out1)
        out2 = self.PointWise(out2)
        out2 = self.RELU(out2)
        out2 = self.PointWise(out2)
        out2 = self.sigmoid(out2)

        out = out1 * out2
        out = x + out
        return out

该网络为了防止梯度下降,还在不同的模块之间使用了跳跃连接。为了保留细致的特征,该子网没有使用下采样和上采样操作。这些获得的细节特征可以看作是对迁移学习子网特性的补充。由于数据拟合子网络是从零开始训练的,并且是基于全分辨率目的构建的,因此它将适合数据并提取更多指定的特征且有着优秀的拟合能力。但同时,更容易遇到过拟合问题。因此,为了改善该数据拟合子网的过拟合问题,建立迁移学习分支的作用是不可忽视的。
##融合尾
该网络的融合尾使用集成的方法产生最终的输出。具体来说,融合尾从两个分支获取特征的拼接,然后学习映射这些特征来恢复图像。融合尾由一个卷积层和一个双曲切线激活函数(Tanh)组成。该模块之所以只采用单一的卷积运算,是因为这两个分支已经为恢复清晰的图像提供了充分而鲜明的特征。相比之下,过多的融合尾会影响方法的整体泛化能力,导致性能下降。整个双分支网络的整体代码如下。

环境配置

使用Pytorch1.12和一台24GB RTX 3090 GPU来实现所有的实验。在所有的实验中,采用平滑L1损失和MS-SSIM损失作为模型的损失函数。选择ADAM优化器作为优化算法,并设置学习率为0.0001,批次大小为1。在训练过程中,降低学习率,每100个epochs降低25%。在训练过程中为了测试模型的普适性,对不同的数据集选取不同的图像大小。

训练本次复现代码所用数据集

O-Haze和I-Haze数据集是由专业雾霾机生成的真实雾霾分别在户外和室内拍摄的图像,。NH-Haze数据集是CVPR-NTRIRE2020竞赛中去雾赛道使用的数据集,具体的组成将在表1详细介绍。为了验证我们网络的鲁棒性,我们选取O-Haze的前40对有雾/无雾图像对、I-Haze的前30对有雾/无雾图像对、NH-Haze的前50对有雾/无雾图像对分别作为训练数据集。剩余有雾/无雾图像对分别作为测试数据集以验证结果。

数据集图片数量真实\合成室内\室外
O-Haze45真实室外
I-Haze35真实室内
NH-Haze55真实室外

测试本次复现代码所用的评价指标

为了评价所提出的模型及方法,本文使用常用的峰值信噪比(PSNR)和结构相似度指数(SSIM)来评价模型的性能。其中,PSNR或SSIM值越高,代表恢复的效果越好。均使用均值的形式处理测试集实验结果。

结果展示

在O-Haze数据集上的结果

在这里插入图片描述

由图中的PSNR和SSIM值所示,本文方法在O-Haze数据集上表现稳定,在训练200次的时候便接近收敛,收敛速度较快;在训练300次时取得最好的模型,PSNR达到19.38,SSIM达到0.67。在剩余的1700次训练中,PSNR基本稳定在19.25左右,SSIM基本稳定在0.66左右。

在这里插入图片描述

本文方法在300次训练出的模型在O-Haze[测试集上的测试结果如图3所示,第一列是原始有雾图像,第二列是本文方法的去雾结果,第三列是真实无雾图像。可以发现,本文方法得到的恢复图像对比原始有雾图像几乎没有雾霾残留,去雾效果明显。但对比真实无雾图像,可以发现,本文方法得到的恢复图像存在细节模糊,色调昏暗的缺点,饱和度较低。
综上,本文方法在O-Haze数据集上虽然能够快速收敛并表现稳定,但由于边缘模糊,色彩饱和度较低使得恢复的图像缺失愉悦的视觉感受。

在I-Haze数据集上的结果

同样,在I-Haze数据集中,选择了前30对图像用以2000次的网络训练,每100次生成一个模型。生成的20个模型在I-Haze的剩余5对图像上的测试结果如图所示。由图可以发现,在I-Haze数据集上,其收敛速度快于O-Haze数据集,仅训练了100次便趋向拟合,仅训练200次便得到最优模型,PSNR达18.71,SSIM达0.71。在之后的1800次训练中,其PSNR稳定在18.60左右,SSIM稳定在0.71左右。

在这里插入图片描述

下图展示了本文方法训练得到的最优模型在I-Haze测试集上的结果,其中,第一列是原始有雾图像,第二列是本文方法的去雾结果,第三列是真实无雾图像。将本文方法的去雾结果对比原始有雾图像可以发现,本文方法能够有效的去除室内的均匀雾霾,但对白色区域的恢复效果不理想。对比真实无雾图像可以发现,本文方法恢复的图像与原图还有较大差距,有着与在O-Haze数据集上的模型相同的缺点。对于均匀雾霾室内场景下物体边缘及整体色彩的恢复表现较差。

在这里插入图片描述

小结

图像去雾神经网络在图像处理领域具有重要意义,主要体现在以下几个方面:

  1. 提升图像质量:雾天拍摄的图像通常存在对比度低、细节模糊、颜色失真等问题,这严重影响了图像中目标物体的可见性和可识别性。图像去雾神经网络能够有效地改善这些问题,通过去除或减轻图像中的雾气,提高图像的整体对比度和亮度,使原本被遮蔽的物体细节得以显现,从而提升图像质量。
  2. 提高目标检测准确性:在自动驾驶、视频监控、遥感探测等领域,目标检测的准确性直接影响着系统的可靠性和安全性。经过去雾处理的图像,能够让目标检测模型在不利天气条件下保持甚至提高原有的检测精度,避免因图像质量下降而导致的误检或漏检。
  3. 增强特征提取:目标检测算法通常依赖于从图像中提取有效的特征,例如边缘、纹理、颜色和形状等。去雾后的图像,其特征更为鲜明,有利于卷积神经网络(CNN)等深度学习模型更准确地捕获和学习目标物体的关键特征,从而提升检测的准确性。
  4. 提高鲁棒性:通过集成图像去雾模块,可以在前端图像预处理阶段就改善输入到目标检测模型的数据质量,增强了整个视觉系统的鲁棒性,使其能够在各种复杂的气象环境中稳定、高效地工作。
  5. 扩大应用场景:图像去雾技术不仅限于提高目标检测准确性,还可以应用于其他领域,如医学影像分析、遥感图像处理、安防监控等。在这些领域,图像去雾技术同样能够提升图像质量,帮助人们更准确地获取和分析图像中的信息。

图像去雾神经网络对于提升图像质量、提高目标检测准确性、增强特征提取、提高鲁棒性以及扩大应用场景等方面都具有重要意义。随着深度学习技术的不断发展,图像去雾神经网络将在更多领域发挥重要作用。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1683153.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

React中显示数据

SX 会让你把标签放到 JavaScript 中。而大括号会让你 “回到” JavaScript 中&#xff0c;这样你就可以从你的代码中嵌入一些变量并展示给用户。例如&#xff0c;这将显示 user.name&#xff1a; return (<h1>{user.name}</h1> ); 你还可以将 JSX 属性 “转义到 …

内网安全之搭建ADCS证书服务

在域控上安装ADCS服务时&#xff0c;默认会自动配置完LDAPS&#xff0c;如果不是在域控上安装ADCS服务&#xff0c;需要手动配置LDAPS 安装证书服务ADCS 打开服务器管理器——>添加角色和功能 选择“基于角色或基于功能的安装”选项&#xff0c;然后点击下一步 选择“从…

我的前端封装之路

最近有粉丝提问了我一个面试中遇到的问题&#xff0c;他说面试的时候&#xff0c;面试官问我&#xff1a;你在以前的项目中封装过组件吗&#xff1f;或者做过npm公共库吗&#xff1f;遇到过什么问题吗&#xff1f;当时自己突然觉得好像没什么可回答的啊&#xff0c;但面试结束想…

实现顺序表各种基本运算的算法

实验一&#xff1a;实现顺序表各种基本运算的算法 一、实验目的与要求 目的: 领会顺序表存储结构和掌握顺序表中各种基本运算算法设计。 内容: 编写一个程序sqlist.cpp,实现顺序表的各种基本运算和整体建表算法(假设顺序表的元素类型ElemType为char),并在此基础上设计一个…

【免费】支持向量机回归预测(SVR)的MATLAB实现(含源代码)

支持向量机&#xff08;Support Vector Machine, SVM&#xff09;是一种常用于分类和回归分析的机器学习算法。虽然SVM最为人熟知的是其分类应用&#xff0c;但它同样适用于回归任务&#xff0c;被称为支持向量回归&#xff08;Support Vector Regression, SVR&#xff09;。以…

温故而知新-JUC篇【面试复习】

温故而知新-JUC篇【面试复习】 前言版权推荐温故而知新-JUC篇多线程Java语言中的线程安全线程安全的实现方法线程的创建线程的状态wait和sleep的区别ThreadLocalsynchronize的优化synchronize和Reentrant的对比AQS线程池ThreadPoolExecutorThreadPoolExecutor源码ConcurrentHas…

javaSwing电影票购票管理系统(视频+源码)

摘要 运行环境&#xff1a;jdk1.8 mysql5.7 eclipse 系统实现 联系 q:3996962787 完整代码、sql、报告、程序资源

【Shell脚本】文本三剑客之sed编辑器

目录 一.sed编辑器的相关介绍及执行过程 1.sed介绍 2.sed编辑器的执行过程 二.sed命令格式 1.基本格式 2.在一个脚本文件里定义操作命令 3.常用操作 三.打印功能 1.默认打印方式 2.防止出现重复打印 2.1. 2.2. 2.3. 2.4. 3.使用地址打印 3.1.以数字形式打印行区…

物联网实战--平台篇之(八)分组后台管理

目录 一、分组数据库 二、请求分组列表 三、添加分组 四、重命名分组 五、删除分组 六、分组排序 本项目的交流QQ群:701889554 物联网实战--入门篇https://blog.csdn.net/ypp240124016/category_12609773.html 物联网实战--驱动篇https://blog.csdn.net/ypp240124016/ca…

给你一把接口响应断言神器,你要不要?

JSON Schema是用来标记和校验JSON数据&#xff0c;类似于XMLSchema,可用在自动化测试验证JSON数据。 官网&#xff1a;http://json-schema.org/ 最常用版本&#xff1a;draft 04。&#xff08;目前各类编程语言对draft 04支持最广泛&#xff09; 举个例子 假如你有一个接口…

【LeetCode】【3】无重复字符的最长子串(1113字)

文章目录 [toc]题目描述样例输入输出与解释样例1样例2样例3 提示Python实现滑动窗口 个人主页&#xff1a;丷从心 系列专栏&#xff1a;LeetCode 刷题指南&#xff1a;LeetCode刷题指南 题目描述 给定一个字符串s&#xff0c;请你找出其中不含有重复字符的最长子串的长度 样…

element DatePicker 日期选择器设置禁用未来日期,时间范围为60天

需要用到 DatePicker 里面的 picker-options 方法 disabledDate onPick方法 <el-date-pickerv-model"form.xxxx"type"daterange"value-format"yyyy-MM-dd":clearable"false":picker-options"pickerOptions"start-placeho…

「React」2024最新版本入门 React 19 你需要掌握什么

前言 React 是前端很火且被广泛使用的一个框架&#xff0c;在当下这个时间想入门上手React开发&#xff0c;我们需要了解它的哪些最为关键的特性&#xff0c;本文将一一列出。 介绍 类组件在官方文档中也已经被废弃&#xff0c;下面均为 React Hooks useStateuseEffectuse…

C - Sigma Problem(AtCoder Beginner Contest 353)

题目的链接: C - Sigma Problem (atcoder.jp) 题目&#xff1a; 样例&#xff1a; 题目大致含意: 给你n个数&#xff0c;让你对这n个数进行操作&#xff0c;比如当前是第i个&#xff0c;那么让a[i] 和 后面的每个数进行相加, 例如a[i] a[i 1] 注意的是a[i] a[i 1]的结果…

ASTGCN 论文学习上

这里写自定义目录标题 Attention Based Spatial-Temporal Graph Convolutional Networks for Traffic Flow Forecasting1. 摘要1.1 背景1.2 现有方法的不足1.3 提出的方法1.3.1 方法细节 1.4 实验结果 2 引言2.1 研究背景2.2 问题描述2.3 数据基础2.4 现有方法及其局限性2.5 提…

Easy Notes 彩色记事本,备忘录,笔记本,尊享版 v1.2.42.0517

软件介绍 「Easy Notes」是一款为用户量身打造的简易记事本管理应用APP&#xff0c;其功能覆盖了笔记撰写、备忘录设置、彩色便签制作及加密文档存储等。该应用程序以简洁的界面和便捷的操作性为核心&#xff0c;为用户提供了一个多元化的记录体验。借助其彩色背景与分类清单的…

AI预测体彩排3采取878=23策略+杀断组+杀和尾+杀和值012缩水测试5月23日预测第8弹

最近几天单位事情比较多&#xff0c;回来会比较晚&#xff0c;等忙过这段时间后每天我会恢复到中午左右将预测结果发出来&#xff0c;望各位见谅~今天继续验证测试87823策略&#xff0c;继续完成一个周期&#xff08;十期&#xff09;的测试。下面直接发预测结果~ 首先…

网络模型-Qinq配置与应用

Qinq配置与应用 通过配置Qinq来实现利用公网提供的VLAN100使企业1互通&#xff0c;利用公网提供的VLAN200使企业2互通不同企业之间互相隔离。并通过在连接其它厂商设备的接口上配置修改0in0外层VLAN Tag的TPID值&#xff0c;来实现与其它厂商设备的互通。 一、创建VLAN #在Swi…

基于springboot+vue的学生考勤管理系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

【Linux】Centos7安装RabbitMQ

【Linux】Centos7安装RabbitMQ 下载 从 rabbitmq 的 GitHub 仓库下载 https://github.com/rabbitmq/rabbitmq-server/releases rabbitmq 是 erlang 语言编写的&#xff0c;需要先安装 erlang https://github.com/rabbitmq/erlang-rpm/releases 安装 使用rz命令上传 erlang 和 …