圖像去雨去霧綜述

1.Single Image Haze Removal Using Dark Channel Prior

這是何凱明在博士期間發(fā)表的一篇經(jīng)典的圖像去霧算法的文章。這篇文章中他通過觀察提出了一種暗通道算法(Dark Channel Prior),簡單來說就在一張正常圖像中,除了天空區(qū)域,在圖像的每個小塊(patch)中一定有一些像素點至少有一個通道的值是非常小的,基于這個先驗條件,何凱明團隊使用了一種簡單有效的辦法來進行圖像去霧。
下面的公式為經(jīng)典的去霧模型,其中I(x)指獲取得到的圖片亮度,J(x)是去霧后恢復的圖像,t(x)指透射率,A是指大氣的光成分(即霧成分)。這個公式還是很容易直觀的理解,因為透射率可以在一定程度上代表損失率。\beta為大氣散射系數(shù),d(x)為景深。
I(x)=J(x)t(x)+A(1-t(x))
t(x)=e^{-\beta d(x)}
由于在統(tǒng)計意義上,一個patch中總有幾個像素的至少一個通道是很暗的,此時的J(x)t(x)趨近于0,于是在一個patch中有如下公式成立:
\tilde{t}=1-min_c(min_{y\in \Omega (x)}(\frac{i^c(y)}{A^c}))
這樣我們就可以算出t的近似值了。同時,當patch為天空時,大氣光A和真實圖像光I(y)十分相近,于是t的近似值趨向于0。
獲得了反射率t以后,下一步便是對圖像進行soft matting獲得輪廓特征,這樣可以將透射率t精細化。
這樣我們就獲得了精細化后的透射率t值。對于有霧區(qū)域,我們可以根據(jù)下面的公式進行去霧,其中我們對t設(shè)定了一個最低的閾值。

對于A的獲取,我們可以借助于暗通道圖來從有霧圖像中獲取該值。從暗通道圖中按照亮度的大小取前0.1%的像素。
在這些位置中,在原始有霧圖像I中尋找對應的具有最高亮度的點的值,作為A值。
以下圖為例說明一下這么做的理由:如果使用傳統(tǒng)的方法,直接選取圖像中的亮度值最高的點作為全局大氣光值,這樣原始有霧圖像中的白色物體會對此有影響,使得其值偏高。暗通道的運算可以抹去原始圖像中小塊的白色物體,所以這樣估計的全局大氣光值會更準確。

最終的公式如下:
J(x)=\frac{I(x)-A}{max(t(x),t_0)}+A

2.DehazeNet: An End-to-End System for Single Image Haze Removal

在這篇文章中,作者提出了用神經(jīng)網(wǎng)絡方法對反射率t進行訓練并預測,網(wǎng)絡結(jié)構(gòu)如下:
首先用CNN接maxout抽取圖像特征,再接幾個平行的multi-scale mapping,然后進行池化,經(jīng)過BReLU激活函數(shù)得到最終的反射率t



BReLU如圖b所示,因為rgb具有上界和下界,如果不進行截斷可能會越界。



網(wǎng)絡結(jié)構(gòu)如圖:

Pytorch復現(xiàn):
import torch 
import torch.nn as nn
import numpy as np
import cv2
import random
from torchsummary import summary
import os
from torch.autograd import Variable
from tqdm import tqdm
import torch.utils.data as Data

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

class MaxoutConv(torch.nn.Module):
    def __init__(self, in_channels,
                 out_channels, kernel_size,stride):
        super(MaxoutConv, self).__init__()

        self.conv = torch.nn.Conv2d(in_channels, out_channels, kernel_size,stride=stride)

        self.BN = torch.nn.BatchNorm2d(out_channels)

    def forward(self, _input, is_norm=False):
        z = self.conv(_input)
        if is_norm:
            z = self.BN(z)
        # (batch size, channels, height, width)
        h = torch.max(z, 1).values     # take max operation from first dimension(channel)
        # Insert 1 as channel dimension to h
        hshape = h.shape
        h = h.reshape(*([hshape[0]] + [1] + list(hshape[1:])))
        return h

class BRelu(nn.Module):
    def __init__(self):
        super(BRelu,self).__init__()
        self.relu=nn.ReLU()
    def forward(self,x):
        return torch.min(self.relu(x),torch.tensor([1.0],device=device))
        
class DehazeNet(nn.Module):
    def __init__(self):
        super(DehazeNet, self).__init__()
        
        #conv2d_maxout
        self.conv_1=MaxoutConv(in_channels=3,out_channels=4,kernel_size=(5,5),stride=(1,1))
        self.conv_2=MaxoutConv(in_channels=3,out_channels=4,kernel_size=(5,5),stride=(1,1))
        self.conv_3=MaxoutConv(in_channels=3,out_channels=4,kernel_size=(5,5),stride=(1,1))
        self.conv_4=MaxoutConv(in_channels=3,out_channels=4,kernel_size=(5,5),stride=(1,1))
        
        
        #multi-scale conv
        self.multi_layer_1=nn.Conv2d(in_channels=4,out_channels=16, kernel_size=(3, 3),stride=(1,1),padding=1)
        self.multi_layer_2=nn.Conv2d(in_channels=4,out_channels=16, kernel_size=(5, 5),stride=(1,1),padding=2)
        self.multi_layer_3=nn.Conv2d(in_channels=4,out_channels=16, kernel_size=(7, 7),stride=(1,1),padding=3)
        
        #max pool
        self.max_pool_1=nn.MaxPool2d(kernel_size=(7,7),stride=(1,1))
        
        self.conv_5=nn.Conv2d(in_channels=48,out_channels=1,kernel_size=(6, 6), stride=(1, 1))
        
        self.brelu=BRelu()
    def forward(self,x):
        x=torch.cat([self.conv_1(x),self.conv_2(x),self.conv_3(x),self.conv_4(x)],axis=1)
        x=self.max_pool_1(torch.cat([self.multi_layer_1(x),self.multi_layer_2(x),self.multi_layer_3(x)],axis=1))
        x=self.conv_5(x)
        return self.brelu(x)

model=DehazeNet().to(device)
summary(model,(3,16,16))
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容