【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月前
|
网络协议 安全 5G
网络与通信原理
【10月更文挑战第14天】网络与通信原理涉及众多方面的知识,从信号处理到网络协议,从有线通信到无线通信,从差错控制到通信安全等。深入理解这些原理对于设计、构建和维护各种通信系统至关重要。随着技术的不断发展,网络与通信原理也在不断演进和完善,为我们的生活和工作带来了更多的便利和创新。
72 3
|
3月前
|
并行计算 安全 网络协议
探索未来网络:量子互联网的原理与应用
本文深入探讨了量子互联网的基本概念、技术原理及其潜在应用。通过对量子纠缠、量子叠加和量子隐形传态等核心概念的解释,文章展示了量子互联网如何利用量子力学特性来实现超高速、超高安全性的通信。此外,还讨论了量子互联网在金融、医疗、国防等领域的应用前景,以及当前面临的技术挑战和未来的发展方向。
94 2
|
1月前
|
运维 物联网 网络虚拟化
网络功能虚拟化(NFV):定义、原理及应用前景
网络功能虚拟化(NFV):定义、原理及应用前景
68 3
|
1月前
|
网络协议 安全 算法
网络空间安全之一个WH的超前沿全栈技术深入学习之路(9):WireShark 简介和抓包原理及实战过程一条龙全线分析——就怕你学成黑客啦!
实战:WireShark 抓包及快速定位数据包技巧、使用 WireShark 对常用协议抓包并分析原理 、WireShark 抓包解决服务器被黑上不了网等具体操作详解步骤;精典图示举例说明、注意点及常见报错问题所对应的解决方法IKUN和I原们你这要是学不会我直接退出江湖;好吧!!!
网络空间安全之一个WH的超前沿全栈技术深入学习之路(9):WireShark 简介和抓包原理及实战过程一条龙全线分析——就怕你学成黑客啦!
|
1月前
|
XML 开发框架 .NET
.NET 9 中 LINQ 新增功能实操
.NET 9 中 LINQ 新增功能实操
|
1月前
|
网络协议 Unix Linux
精选2款C#/.NET开源且功能强大的网络通信框架
精选2款C#/.NET开源且功能强大的网络通信框架
|
1月前
|
网络协议 网络安全 Apache
一个整合性、功能丰富的.NET网络通信框架
一个整合性、功能丰富的.NET网络通信框架
|
2月前
|
机器学习/深度学习 人工智能 监控
深入理解深度学习中的卷积神经网络(CNN):从原理到实践
【10月更文挑战第14天】深入理解深度学习中的卷积神经网络(CNN):从原理到实践
227 1
|
2月前
|
网络协议 Linux 应用服务中间件
Socket通信之网络协议基本原理
【10月更文挑战第10天】网络协议定义了机器间通信的标准格式,确保信息准确无损地传输。主要分为两种模型:OSI七层模型与TCP/IP模型。
|
2月前
|
存储 安全 算法
网络安全与信息安全:构建数字世界的防线在数字化浪潮席卷全球的今天,网络安全与信息安全已成为维系现代社会正常运转的关键支柱。本文旨在深入探讨网络安全漏洞的成因与影响,剖析加密技术的原理与应用,并强调提升公众安全意识的重要性。通过这些综合性的知识分享,我们期望为读者提供一个全面而深刻的网络安全视角,助力个人与企业在数字时代中稳健前行。
本文聚焦网络安全与信息安全领域,详细阐述了网络安全漏洞的潜在威胁、加密技术的强大防护作用以及安全意识培养的紧迫性。通过对真实案例的分析,文章揭示了网络攻击的多样性和复杂性,强调了构建全方位、多层次防御体系的必要性。同时,结合当前技术发展趋势,展望了未来网络安全领域的新挑战与新机遇,呼吁社会各界共同努力,共筑数字世界的安全防线。
下一篇
DataWorks