【CVPR2017】AOD-Net:端到端的除雾网络(原理&实操)

简介: 【CVPR2017】AOD-Net:端到端的除雾网络(原理&实操)

前言

  由于AOD-Net网络是2017年的顶刊论文,在网上也有相当多的讲解,因此本文中将不会过多赘述论文中的内容,仅摘取精华进行讲解。

导读

  AOD-Net 是一种用于图像去雾的深度神经网络模型,旨在通过对图像进行学习和分析,从中提取出场景中的深度信息,从而去除图像中的雾霾。AOD-Net 的全称为 "All-in-One Dehazing Network",是由学者们在研究图像去雾的过程中提出的一种全新的深度神经网络模型。该模型采用了基于 CNN 的网络结构,在学习和分析图像的同时,还能够提取出场景中的深度信息,从而能够更加准确地去除图像中的雾霾。

  相较于传统的图像去雾算法,AOD-Net 具有更高的去雾效果和更快的速度,并且能够适应各种不同的场景和光照条件。因此,AOD-Net 在图像去雾领域具有广泛的应用前景,并且已经被广泛地应用于实际的图像处理任务中。

原理

  AOD-Net其原理基于自适应的最优估计理论和深度学习技术。AOD-Net的设计思想是通过将自适应最优估计理论引入深度学习框架中,实现图像去噪的自适应性和最优性。


image.png

结构组成

  具体来说,AOD-Net由两个子网络组成,即噪声估计网络和噪声去除网络。噪声估计网络用于估计图像中的噪声水平,而噪声去除网络则根据噪声估计网络输出的噪声水平信息,以及图像本身的特征,对图像进行去噪处理。

  AOD-Net的噪声估计网络使用一个类似于U-Net的架构,从原始图像中提取特征并预测噪声的分布。在噪声去除网络中,使用残差网络的结构进行去噪处理,同时使用一个可学习的标准化层来适应预测的噪声水平。

AOD-Net的优点在于它能够自适应地估计噪声水平,从而在不同的噪声水平下进行图像去噪,同时具有较高的去噪效果和计算效率。

代码

  下面是使用torch框架实现的AOD-Net网络结构

ini

复制代码

import torch
import torch.nn as nn
class AODNet(nn.Module):
   def __init__(self):
      super(AODNet, self).__init__()
      self.relu = nn.ReLU(inplace=True)
   
      self.conv1 = nn.Conv2d(3, 3, 1, 1, 0, bias=True)
      self.conv2 = nn.Conv2d(3, 3, 3, 1, 1, bias=True)
      self.conv3 = nn.Conv2d(6, 3, 5, 1, 2, bias=True)
      self.conv4 = nn.Conv2d(6, 3, 7, 1, 3, bias=True)
      self.conv5 = nn.Conv2d(12, 3, 3, 1, 1, bias=True)
      
   def forward(self, x):
      x1 = self.relu(self.conv1(x))
      x2 = self.relu(self.conv2(x1))
      concat1 = torch.cat((x1, x2), 1)
      x3 = self.relu(self.conv3(concat1))
      concat2 = torch.cat((x2, x3), 1)
      x4 = self.relu(self.conv4(concat2))
      concat3 = torch.cat((x1, x2, x3, x4), 1)
      x5 = self.relu(self.conv5(concat3))
      clean_image = self.relu((x5 * x) - x5 + 1) 
      
      return clean_image

结构示例图

image.png

精髓部分

  AOD-Net主要精髓是AOD-Net通过自适应去模糊和多尺度处理的结合,能够在不同场景下有效地提高图像去模糊的效果,具有较高的实用性和普适性。

  具体来说,AOD-Net采用了一个深度卷积神经网络,通过输入模糊图像和一个预先设定的点扩散函数(PSF),输出一张更加清晰的图像。网络架构包含两个主要组成部分:自适应去模糊模块和多尺度处理模块。

  AOD-Net自适应去模糊模块是AOD-Net的核心,它可以根据输入的模糊图像和PSF自适应地学习一个去模糊滤波器,用于恢复更清晰的图像。这个模块中采用了自适应残差学习机制,能够使网络在学习过程中自动选择最优的滤波器。此外,为了保证网络的泛化能力和稳定性,自适应去模糊模块还采用了一些特殊的技巧,例如局部标准化和正则化。

  AOD-Net多尺度处理模块则可以在不同的尺度上处理输入图像,从而有效地提高去模糊效果。具体来说,AOD-Net使用了一个金字塔结构,将输入图像按照不同的尺度进行下采样,并分别输入自适应去模糊模块进行处理。之后,网络将不同尺度的输出图像进行上采样和融合,得到最终的去模糊结果。

实操

  在实操中我将分模块的讲解如何运用网络训练一个自己的除雾网络以及进行ORT推理,在GITHUB上也有相当多的关于AOD-NET的代码,我这里也有一份代码放置在github上,欢迎大家自取。这里主要讲解数据集的准备以及使用ort推理。

数据集的准备

  由于我们需要使用该网络,因此数据集是必不可少的,所以我们可以将本地的一些图像进行生成雾图加雾处理,然后将原图和含有雾的图像分成两个文件夹放置起来即可。

ini

复制代码

import math
import os
import random
import cv2
import numpy as np
from numba import jit
@jit(nopython=True)
def fog(j, center0, l, center1, size, beta):
    d = -0.04 * math.sqrt((j - center0) ** 2 + (l - center1) ** 2) + size
    td = math.exp(-beta * d)
    return d, td
def put_fog(raw_img_path, fog_img_path):
    img = cv2.imread(raw_img_path)
    img_f = img / 255.0
    (row, col, chs) = img.shape
    A = random.uniform(0.45, 0.65)  # 亮度
    beta = random.uniform(0.03, 0.075)  # 亮度
    max_rc = max(row, col)
    size = math.sqrt(max_rc)  # 雾化尺寸
    center = (row // 2, col // 2)  # 雾化中心
    for j in range(row):
        for l in range(col):
            center0 = center[0]
            center1 = center[1]
            d, td = fog(j, center0, l, center1, size, beta)
            img_f[j][l][:] = img_f[j][l][:] * td + A * (1 - td)
    out_img = (img_f * 255).astype(np.uint8)
    cv2.imwrite(fog_img_path, out_img)
    print("---------------------------------")
def ChangeImgName(ImgName, NewName):
    old_img = cv2.imread(ImgName)
    cv2.imwrite(NewName, old_img)
if __name__ == '__main__':
    # demo()
    path = "C:/Users/kiven/Desktop/AOD//data/hazy/"
    fog_path = "C:/Users/kiven/Desktop/AOD//data/1/"
    name_list = os.listdir(path)
    we = "_1_1_2"
    for name in name_list:
        imgname = name[0:-4] + we + ".jpg"
        ChangeImgName(path + name, fog_path+ imgname)
        # put_fog(path+name, fog_path+name)

pth2onnx

  我们新建一个.py文件对训练得到的pth权重进行转化,为了后期能够摆脱torch的安装以及可在边缘设备上运行,这里我们需要明确的是网络的输入大小以及输入输出的名字。

ini

复制代码

import torch
import torch.onnx
def pth_to_onnx(input, checkpoint, onnx_path, input_names,output_names):
    if not onnx_path.endswith('.onnx'):
        print('Warning!')
        return 0
    model = torch.load('saved_models/dehaze_net_epoch_17.pth', map_location=torch.device('cpu'))
    # #指定模型的输入,以及onnx的输出路径
    torch.onnx.export(model, input, onnx_path, verbose=True, input_names=input_names,
                      output_names=output_names)  # 指定模型的输入,以及onnx的输出路径
if __name__ == '__main__':
    checkpoint = './saved_models/dehaze_net_epoch_17.pth'
    onnx_path = './dehaze_net.onnx'
    input = torch.randn(1, 3, 450, 600)
    input_names = ['input']
    output_names = ['output']
    pth_to_onnx(input, checkpoint, onnx_path, input_names, output_names)

ORT推理

  在ORT中我们主要工作是将torch中的一些操作替换为numpy的操作:

  1. 采用pillow读取图像;
  2. 转换为numpy然后归一化0~1之间;
  3. 数据转换为float32格式;
  4. 在位置0维度上添加一个维度;
  5. 使用ort读取网络并推理(推理结果是一个list)
  6. 获取推理结果后取出结果numpy(shape= 1,3,450,600)
  7. 去除shape[0]的地方
  8. 显示结果图

ini

复制代码

import numpy as np
from PIL import Image
import onnxruntime as ort
import matplotlib.pyplot as plt
def dehaze_image(image_name):
    data_hazy = Image.open(image_name)
    data_hazy = np.array(data_hazy) / 255.0
    original_img = data_hazy.copy()
    data_hazy = np.array(data_hazy, dtype=np.float32)
    data_hazy = np.transpose(data_hazy, (2, 0, 1))
    data_hazy = np.expand_dims(data_hazy, 0)
    bolb = data_hazy
    input_name = 'input'
    output_name = 'output'
    dehaze_net = ort.InferenceSession("./dehaze_net.onnx", providers=ort.get_available_providers())
    netOutputImg = dehaze_net.run([output_name], {input_name: bolb})
    pdata = netOutputImg[0]
    clean_image = pdata.squeeze()
    clean_image = np.swapaxes(clean_image, 0, 1)
    clean_image = np.swapaxes(clean_image, 1, 2)
    plt.subplot(1, 2, 1)
    plt.imshow(original_img)
    plt.axis('off')
    plt.title('Original Image')
    plt.subplot(1, 2, 2)
    plt.imshow(clean_image)
    plt.axis('off')
    plt.title('Dehaze Image')
    plt.show()
if __name__ == '__main__':
    img_name = './test_images/test0.png'
    dehaze_image(img_name)

结语

  虽然AOD-Net已经取得了很好的去雾效果,但是还有很多挑战需要克服,例如在复杂场景下的去雾效果提升,以及对运动模糊等噪声的抵抗能力。未来的研究将不断推动图像去雾技术的发展,希望这篇文章能为读者们对图像去雾技术的理解和应用提供一些帮助。


相关文章
|
2月前
|
机器学习/深度学习 存储 算法
NoProp:无需反向传播,基于去噪原理的非全局梯度传播神经网络训练,可大幅降低内存消耗
反向传播算法虽是深度学习基石,但面临内存消耗大和并行扩展受限的问题。近期,牛津大学等机构提出NoProp方法,通过扩散模型概念,将训练重塑为分层去噪任务,无需全局前向或反向传播。NoProp包含三种变体(DT、CT、FM),具备低内存占用与高效训练优势,在CIFAR-10等数据集上达到与传统方法相当的性能。其层间解耦特性支持分布式并行训练,为无梯度深度学习提供了新方向。
119 1
NoProp:无需反向传播,基于去噪原理的非全局梯度传播神经网络训练,可大幅降低内存消耗
|
1月前
|
监控 应用服务中间件 Linux
掌握并发模型:深度揭露网络IO复用并发模型的原理。
总结,网络 I/O 复用并发模型通过实现非阻塞 I/O、引入 I/O 复用技术如 select、poll 和 epoll,以及采用 Reactor 模式等技巧,为多任务并发提供了有效的解决方案。这样的模型有效提高了系统资源利用率,以及保证了并发任务的高效执行。在现实中,这种模型在许多网络应用程序和分布式系统中都取得了很好的应用成果。
83 35
|
25天前
|
机器学习/深度学习 算法 测试技术
图神经网络在信息检索重排序中的应用:原理、架构与Python代码解析
本文探讨了基于图的重排序方法在信息检索领域的应用与前景。传统两阶段检索架构中,初始检索速度快但结果可能含噪声,重排序阶段通过强大语言模型提升精度,但仍面临复杂需求挑战
64 0
图神经网络在信息检索重排序中的应用:原理、架构与Python代码解析
|
8月前
|
网络协议 安全 5G
网络与通信原理
【10月更文挑战第14天】网络与通信原理涉及众多方面的知识,从信号处理到网络协议,从有线通信到无线通信,从差错控制到通信安全等。深入理解这些原理对于设计、构建和维护各种通信系统至关重要。随着技术的不断发展,网络与通信原理也在不断演进和完善,为我们的生活和工作带来了更多的便利和创新。
284 58
|
3月前
|
机器学习/深度学习 数据可视化 PyTorch
深入解析图神经网络注意力机制:数学原理与可视化实现
本文深入解析了图神经网络(GNNs)中自注意力机制的内部运作原理,通过可视化和数学推导揭示其工作机制。文章采用“位置-转移图”概念框架,并使用NumPy实现代码示例,逐步拆解自注意力层的计算过程。文中详细展示了从节点特征矩阵、邻接矩阵到生成注意力权重的具体步骤,并通过四个类(GAL1至GAL4)模拟了整个计算流程。最终,结合实际PyTorch Geometric库中的代码,对比分析了核心逻辑,为理解GNN自注意力机制提供了清晰的学习路径。
354 7
深入解析图神经网络注意力机制:数学原理与可视化实现
|
4月前
|
网络协议 安全 网络安全
应用程序中的网络协议:原理、应用与挑战
网络协议是应用程序实现流畅运行和安全通信的基石。了解不同协议的特点和应用场景,以及它们面临的挑战和应对策略,对于开发者和用户都具有重要意义。在未来,随着技术的不断发展,网络协议也将不断优化和创新,为数字世界的发展提供更强大的支持。
139 1
|
5月前
|
机器学习/深度学习 算法 PyTorch
深度强化学习中SAC算法:数学原理、网络架构及其PyTorch实现
软演员-评论家算法(Soft Actor-Critic, SAC)是深度强化学习领域的重要进展,基于最大熵框架优化策略,在探索与利用之间实现动态平衡。SAC通过双Q网络设计和自适应温度参数,提升了训练稳定性和样本效率。本文详细解析了SAC的数学原理、网络架构及PyTorch实现,涵盖演员网络的动作采样与对数概率计算、评论家网络的Q值估计及其损失函数,并介绍了完整的SAC智能体实现流程。SAC在连续动作空间中表现出色,具有高样本效率和稳定的训练过程,适合实际应用场景。
1278 7
深度强化学习中SAC算法:数学原理、网络架构及其PyTorch实现
|
6月前
|
前端开发 网络协议 安全
【网络原理】——HTTP协议、fiddler抓包
HTTP超文本传输,HTML,fiddler抓包,URL,urlencode,HTTP首行方法,GET方法,POST方法
|
6月前
|
域名解析 网络协议 关系型数据库
【网络原理】——带你认识IP~(长文~实在不知道取啥标题了)
IP协议详解,IP协议管理地址(NAT机制),IP地址分类、组成、特殊IP地址,MAC地址,数据帧格式,DNS域名解析系统
|
6月前
|
存储 JSON 缓存
【网络原理】——HTTP请求头中的属性
HTTP请求头,HOST、Content-Agent、Content-Type、User-Agent、Referer、Cookie。

热门文章

最新文章