暗通道先驗——Single Image Haze Removal Using Dark Channel Prior

大氣散射模型

在這裏插入圖片描述

暗通道先驗

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

大氣光值A的估計

在這裏插入圖片描述

圖像復原

在這裏插入圖片描述

from PIL import Image
import cv2;
import math;
import numpy as np;
import os
def DarkChannel(im,sz):
    b,g,r = cv2.split(im)#通道拆分
    dc = cv2.min(cv2.min(r,g),b);#取三通道的最小值
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(sz,sz))#返回szxsz大小的矩陣
    dark = cv2.erode(dc,kernel)
    return dark

def AtmLight(im,dark):#計算大氣光A
    [h,w] = im.shape[:2]
    imsz = h*w
    numpx = int(max(math.floor(imsz/1000),1))#前0.1%個像素點的個數
    darkvec = dark.reshape(imsz,1)#將暗通道序列化
    imvec = im.reshape(imsz,3);#將圖像序列化
    indices = np.argsort(darkvec,0)#將暗通道按灰度值排序
    indices = indices[imsz-numpx::]#取灰度值最大的的前0.1%
    b,g,r=cv2.split(im)
    gray_im=r*0.299 + g*0.587 + b*0.114#計算彩色圖像對應的灰度值
    gray_im=gray_im.reshape(imsz,1)
    loc=np.where(gray_im==max(gray_im[indices]))#找出暗通道中的前0.1%對應原始彩色圖像中灰度值最大的點
    x=loc[0][0]
    A=np.array(imvec[x])
    A=A.reshape(1,3)
    return A#返回該點灰度值,作爲大氣光

def TransmissionEstimate(im,A,sz):
    omega = 0.95;
    im3 = np.empty(im.shape,im.dtype);

    for ind in range(0,3):
        im3[:,:,ind] = im[:,:,ind]/A[0,ind]

    transmission = 1 - omega*DarkChannel(im3,sz);
    return transmission

def Guidedfilter(im,p,r,eps):
    mean_I = cv2.boxFilter(im,cv2.CV_64F,(r,r));
    mean_p = cv2.boxFilter(p, cv2.CV_64F,(r,r));
    mean_Ip = cv2.boxFilter(im*p,cv2.CV_64F,(r,r));
    cov_Ip = mean_Ip - mean_I*mean_p;

    mean_II = cv2.boxFilter(im*im,cv2.CV_64F,(r,r));
    var_I   = mean_II - mean_I*mean_I;

    a = cov_Ip/(var_I + eps);
    b = mean_p - a*mean_I;

    mean_a = cv2.boxFilter(a,cv2.CV_64F,(r,r));
    mean_b = cv2.boxFilter(b,cv2.CV_64F,(r,r));

    q = mean_a*im + mean_b;
    return q;

def TransmissionRefine(im,et):
    gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY);
    gray = np.float64(gray)/255;
    r = 60;
    eps = 0.0001;
    t = Guidedfilter(gray,et,r,eps);

    return t;

def Recover(im,t,A,tx = 0.1):
    res = np.empty(im.shape,im.dtype);
    t = cv2.max(t,tx);

    for ind in range(0,3):
        res[:,:,ind] = (im[:,:,ind]-A[0,ind])/t + A[0,ind]

    return res
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章