├── image ├── 15.png └── J.png ├── README.md ├── LICENSE └── dehaze.py /image/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/He-Zhang/image_dehaze/HEAD/image/15.png -------------------------------------------------------------------------------- /image/J.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/He-Zhang/image_dehaze/HEAD/image/J.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # single image dehaze 2 | ## Introduction 3 | This program implement single image dehazing using dark channel prior. 4 | 5 | ## Compile Dependencies 6 | - OpenCV 7 | - Numpy 8 | 9 | ## Examples 10 |
11 | 图片名称 12 | 图片名称 13 |
14 | 15 | 16 | ## Algorithms 17 | - Single Image Haze Removal Using Dark Channel Prior, Kaiming He, Jian Sun, and Xiaoou Tang", in CVPR 2009 18 | - Guided Image Filtering, Kaiming He, Jian Sun, and Xiaoou Tang", in ECCV 2010. 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 WinCoder 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /dehaze.py: -------------------------------------------------------------------------------- 1 | import cv2; 2 | import math; 3 | import numpy as np; 4 | 5 | def DarkChannel(im,sz): 6 | b,g,r = cv2.split(im) 7 | dc = cv2.min(cv2.min(r,g),b); 8 | kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(sz,sz)) 9 | dark = cv2.erode(dc,kernel) 10 | return dark 11 | 12 | def AtmLight(im,dark): 13 | [h,w] = im.shape[:2] 14 | imsz = h*w 15 | numpx = int(max(math.floor(imsz/1000),1)) 16 | darkvec = dark.reshape(imsz); 17 | imvec = im.reshape(imsz,3); 18 | 19 | indices = darkvec.argsort(); 20 | indices = indices[imsz-numpx::] 21 | 22 | atmsum = np.zeros([1,3]) 23 | for ind in range(1,numpx): 24 | atmsum = atmsum + imvec[indices[ind]] 25 | 26 | A = atmsum / numpx; 27 | return A 28 | 29 | def TransmissionEstimate(im,A,sz): 30 | omega = 0.95; 31 | im3 = np.empty(im.shape,im.dtype); 32 | 33 | for ind in range(0,3): 34 | im3[:,:,ind] = im[:,:,ind]/A[0,ind] 35 | 36 | transmission = 1 - omega*DarkChannel(im3,sz); 37 | return transmission 38 | 39 | def Guidedfilter(im,p,r,eps): 40 | mean_I = cv2.boxFilter(im,cv2.CV_64F,(r,r)); 41 | mean_p = cv2.boxFilter(p, cv2.CV_64F,(r,r)); 42 | mean_Ip = cv2.boxFilter(im*p,cv2.CV_64F,(r,r)); 43 | cov_Ip = mean_Ip - mean_I*mean_p; 44 | 45 | mean_II = cv2.boxFilter(im*im,cv2.CV_64F,(r,r)); 46 | var_I = mean_II - mean_I*mean_I; 47 | 48 | a = cov_Ip/(var_I + eps); 49 | b = mean_p - a*mean_I; 50 | 51 | mean_a = cv2.boxFilter(a,cv2.CV_64F,(r,r)); 52 | mean_b = cv2.boxFilter(b,cv2.CV_64F,(r,r)); 53 | 54 | q = mean_a*im + mean_b; 55 | return q; 56 | 57 | def TransmissionRefine(im,et): 58 | gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY); 59 | gray = np.float64(gray)/255; 60 | r = 60; 61 | eps = 0.0001; 62 | t = Guidedfilter(gray,et,r,eps); 63 | 64 | return t; 65 | 66 | def Recover(im,t,A,tx = 0.1): 67 | res = np.empty(im.shape,im.dtype); 68 | t = cv2.max(t,tx); 69 | 70 | for ind in range(0,3): 71 | res[:,:,ind] = (im[:,:,ind]-A[0,ind])/t + A[0,ind] 72 | 73 | return res 74 | 75 | if __name__ == '__main__': 76 | import sys 77 | try: 78 | fn = sys.argv[1] 79 | except: 80 | fn = './image/15.png' 81 | 82 | def nothing(*argv): 83 | pass 84 | 85 | src = cv2.imread(fn); 86 | 87 | I = src.astype('float64')/255; 88 | 89 | dark = DarkChannel(I,15); 90 | A = AtmLight(I,dark); 91 | te = TransmissionEstimate(I,A,15); 92 | t = TransmissionRefine(src,te); 93 | J = Recover(I,t,A,0.1); 94 | 95 | cv2.imshow("dark",dark); 96 | cv2.imshow("t",t); 97 | cv2.imshow('I',src); 98 | cv2.imshow('J',J); 99 | cv2.imwrite("./image/J.png",J*255); 100 | cv2.waitKey(); 101 | 102 | --------------------------------------------------------------------------------