1 import cv2
2 import numpy as np
3
4
-
E741
Ambiguous variable name 'I'
5 def guideFilter(I, p, winsize, eps, s):
6 h, w = I.shape[:2]
7
8 size = (int(round(w * 1.0 / s)), int(round(h * 1.0 / s)))
9 small_I = cv2.resize(I, size, interpolation=cv2.INTER_NEAREST)
10 small_p = cv2.resize(p, size, interpolation=cv2.INTER_NEAREST)
11 X = winsize[0]
12 r = round((2 * X + 1) * 1.0 / s + 1)
13 small_winsize = (int(r), int(r))
14 mean_small_I = cv2.blur(small_I, small_winsize)
15 mean_small_p = cv2.blur(small_p, small_winsize)
16
17 mean_small_II = cv2.blur(small_I * small_I, small_winsize)
18 mean_small_Ip = cv2.blur(small_I * small_p, small_winsize)
19 var_small_I = mean_small_II - mean_small_I * mean_small_I
20 cov_small_Ip = mean_small_Ip - mean_small_I * mean_small_p
21
22 small_a = cov_small_Ip / (var_small_I + eps)
23 small_b = mean_small_p - small_a * mean_small_I
24
25 mean_small_a = cv2.blur(small_a, small_winsize)
26 mean_small_b = cv2.blur(small_b, small_winsize)
27
28 size1 = (w, h)
29 mean_a = cv2.resize(mean_small_a, size1, interpolation=cv2.INTER_LINEAR)
30 mean_b = cv2.resize(mean_small_b, size1, interpolation=cv2.INTER_LINEAR)
31 q = mean_a * I + mean_b
32 return q
33
34
35 def normValue(im):
36 maxV = np.max(im)
37 minV = np.min(im)
38 im = (im - minV) / (maxV - minV + 1e-6)
39 return im
40
41
42 def imgrad(im):
43 gv = cv2.Sobel(im, cv2.CV_64F, 1, 0)
44 gh = cv2.Sobel(im, cv2.CV_64F, 0, 1)
45 g = 0.5 * abs(gv) + 0.5 * abs(gh)
46 return g
47
48
49 def psf2otf(psf, outSize):
50 '''
51 code is from https://blog.csdn.net/
52 weixin_43890288/article/details/
53 105676416
54 '''
55 psfSize = np.array(psf.shape)
56 outSize = np.array(outSize)
57 padSize = outSize - psfSize
58 psf = np.pad(psf, ((0, padSize[0]), (0, padSize[1])), 'constant')
59 for i in range(len(psfSize)):
60 psf = np.roll(psf, -int(psfSize[i] / 2), i)
61 otf = np.fft.fftn(psf)
62 nElem = np.prod(psfSize)
63 nOps = 0
64 for k in range(len(psfSize)):
65 nffts = nElem / psfSize[k]
66 nOps = nOps + psfSize[k] * np.log2(psfSize[k]) * nffts
67 if np.max(np.abs(np.imag(otf))) / np.max(np.abs(otf)) \
68 <= nOps * np.finfo(np.float32).eps:
69 otf = np.real(otf)
70 return otf
71
72
73 def sign(x):
74 xs = x.copy()
75 xs[x > 0] = 1
76 xs[x < 0] = -1
77 return xs
78
79
80 def shrink(x, lam):
81 sig = sign(x)
82 abs_x = abs(x)
83 f = sig * np.maximum(abs_x - lam, 0)
84 return f
85
86
87 def updateI(I0, K, L, w, dx, dy):
88 tmp = w * K - L
89 fn0 = np.fft.fft2(2 * I0)
90 fn1 = np.conjugate(dx * tmp) + np.conjugate(dy * tmp)
91 fn = fn0 + fn1
92 fd = 2 + w * (np.abs(dx) ** 2 + np.abs(dy) ** 2)
-
E741
Ambiguous variable name 'I'
93 I = np.fft.ifft2(fn / fd)
-
E741
Ambiguous variable name 'I'
94 I = abs(I).astype(np.float64)
95 return I
96
97
-
E741
Ambiguous variable name 'I'
98 def getG(I):
99 G = -np.log(imgrad(I) + 1e-6)
100 return G
101
102
-
E741
Ambiguous variable name 'I'
103 def updateK(I, L, Jm, w, G, a, b):
104 Fi = b * G / (2 * a + w)
105 x = 2 * a * Jm + w * imgrad(I) + L
106 K = shrink(x, Fi)
107 return K
108
109
-
E741
Ambiguous variable name 'I'
110 def updateLw(L, I, K, w, sigma):
111 tmp = imgrad(I) - K
112 L += w * tmp
113 w = w * sigma
114 return L, w
115
116
117 def initJm(im):
118 gim = np.zeros(im.shape)
119 for i in range(3):
120 gim[..., i] = imgrad(im[..., i])
121 return np.max(gim, 2)
122
123
124 def optimizAlgo(I0, Jm, alpha=0.5, beta=0.1, ite=1):
125 K = 0.
126 L = 0.
127 w = 1.
128 sigma = 1.5
129 G = getG(I0)
130
131 H, W = I0.shape
132 ky = np.array([[1, -1]])
133 kx = np.array([[1], [-1]])
134 dx = psf2otf(kx, (H + 1, W))
135 dy = psf2otf(ky, (H, W + 1))
136 dy = dy[:, 1:]
137 dx = dx[1:, :]
138
139 for i in range(ite):
-
E741
Ambiguous variable name 'I'
140 I = updateI(I0, K, L, w, dx, dy)
141 K = updateK(I, L, Jm, w, G, alpha, beta)
142 L, w = updateLw(L, I, K, w, sigma)
143 return I
144
145
146 def initIlluminunce(im):
147 epsi = 0.025
148 gs = 2
149 H, W, C = im.shape
150 bmin = 3
151 bmax = int(np.round(np.minimum(H, W) / 2.))
152 bmean = int(np.round((bmin + bmax) / 2.))
153 ws = [bmin, bmean, bmax]
154 ttI = np.zeros(im.shape)
155 for i in range(3):
-
E741
Ambiguous variable name 'I'
156 I = np.zeros(im.shape)
157 r = im[:, :, 0]
158 g = im[:, :, 1]
159 b = im[:, :, 2]
160 I[:, :, 0] = guideFilter(r, r, [ws[i], ws[i]], epsi, gs)
161 I[:, :, 1] = guideFilter(g, g, [ws[i], ws[i]], epsi, gs)
162 I[:, :, 2] = guideFilter(b, b, [ws[i], ws[i]], epsi, gs)
163 ttI[:, :, i] = np.max(I, 2)
164 return np.max(ttI, 2)
165
166
167 def NPLIE(src):
168 # im = src.copy().astype(np.float32)
169 # im /= 255.
170 im = src.copy()
171 I0 = initIlluminunce(im)
172 Jm = initJm(im)
-
E741
Ambiguous variable name 'I'
173 I = optimizAlgo(I0, Jm, 0.5, 0.1, 8)
174 Ie = np.power(I, 0.45)
175 for i in range(3):
176 R = im[:, :, i] / I
177 im[:, :, i] = R * Ie
178 im = np.minimum(1, np.maximum(0, im))
179 # im *= 255
180 return im