大气散射模型
暗通道先验
大气光值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