@@ -136,42 +136,172 @@ def estimate_normalized_alpha(J, W_m, num_images=30):
136
136
return alpha
137
137
138
138
# estimate the blend factor C
139
+ # def estimate_blend_factor(J, W_m, alph, threshold=0.01*255):
140
+ # alpha_n = alph
141
+ # S = J.copy()
142
+ # num_images = S.shape[0]
143
+ # # for i in xrange(num_images):
144
+ # # S[i] = PlotImage(S[i])
145
+ # # R = (S<=threshold).astype(np.float64)
146
+ # R = (S>-1).astype(np.float64)
147
+
148
+ # est_Ik = S.copy()
149
+ # # est_Ik[S>threshold] = nan
150
+ # est_Ik = np.nanmedian(est_Ik, axis=0)
151
+ # est_Ik[isnan(est_Ik)] = 0
152
+
153
+ # alpha_k = R.copy()
154
+ # beta_k = R*J
155
+ # for i in xrange(num_images):
156
+ # alpha_k[i] *= alpha_n*est_Ik
157
+ # beta_k[i] -= R[i]*W_m
158
+ # beta_k = np.abs(beta_k)
159
+ # # we have alpha and beta, solve for c's now
160
+ # c = []
161
+ # for i in range(3):
162
+ # c_i = np.sum(beta_k[:,:,:,i]*alpha_k[:,:,:,i])/np.sum(np.square(alpha_k[:,:,:,i]))
163
+ # c.append(c_i)
164
+ # return c
165
+
139
166
def estimate_blend_factor (J , W_m , alph , threshold = 0.01 * 255 ):
140
- alpha_n = alph
141
- S = J .copy ()
142
- num_images = S .shape [0 ]
143
- # for i in xrange(num_images):
144
- # S[i] = PlotImage(S[i])
145
- # R = (S<=threshold).astype(np.float64)
146
- R = (S > - 1 ).astype (np .float64 )
147
-
148
- est_Ik = S .copy ()
149
- # est_Ik[S>threshold] = nan
150
- est_Ik = np .nanmedian (est_Ik , axis = 0 )
151
- est_Ik [isnan (est_Ik )] = 0
152
-
153
- alpha_k = R .copy ()
154
- beta_k = R * J
155
- for i in xrange (num_images ):
156
- alpha_k [i ] *= alpha_n * est_Ik
157
- beta_k [i ] -= R [i ]* W_m
158
- beta_k = np .abs (beta_k )
159
- # we have alpha and beta, solve for c's now
160
- c = []
161
- for i in range (3 ):
162
- c_i = np .sum (beta_k [:,:,:,i ]* alpha_k [:,:,:,i ])/ np .sum (np .square (alpha_k [:,:,:,i ]))
163
- c .append (c_i )
164
- return c
165
-
166
- # TODO: Remove the blend factor formulation with something more suitable
167
- # Like taking the edge details instead of sum of squares of intensity
168
- # c=0.1
169
- # ...: while c<1:
170
- # ...: img = (S[61]-c*alph*est_Ik)
171
- # ...: sx = cv2.Sobel(img, cv2.CV_64F, 1, 0, 3)
172
- # ...: sy = cv2.Sobel(img, cv2.CV_64F, 0, 1, 3)
173
- # ...: edge = np.sqrt(sx**2 + sy**2)
174
- # ...: edge = img
175
- # ...: plt.subplot(3,3,int(c*10)); plt.imshow(PlotImage(edge));
176
- # ...: c+=0.1
177
- # ...: print(np.mean(np.square(edge)))
167
+ K , m , n , p = J .shape
168
+ Jm = (J - W_m )
169
+ gx_jm = np .zeros (J .shape )
170
+ gy_jm = np .zeros (J .shape )
171
+
172
+ for i in xrange (K ):
173
+ gx_jm [i ] = cv2 .Sobel (Jm [i ], cv2 .CV_64F , 1 , 0 , 3 )
174
+ gy_jm [i ] = cv2 .Sobel (Jm [i ], cv2 .CV_64F , 0 , 1 , 3 )
175
+
176
+ Jm_grad = np .sqrt (gx_jm ** 2 + gy_jm ** 2 )
177
+
178
+ est_Ik = alph * np .median (J , axis = 0 )
179
+ gx_estIk = cv2 .Sobel (est_Ik , cv2 .CV_64F , 1 , 0 , 3 )
180
+ gy_estIk = cv2 .Sobel (est_Ik , cv2 .CV_64F , 0 , 1 , 3 )
181
+ estIk_grad = np .sqrt (gx_estIk ** 2 + gy_estIk ** 2 )
182
+
183
+ C = []
184
+ for i in xrange (3 ):
185
+ c_i = np .sum (Jm_grad [:,:,:,i ]* estIk_grad [:,:,i ])/ np .sum (np .square (estIk_grad [:,:,i ]))/ K
186
+ print (c_i )
187
+ C .append (c_i )
188
+
189
+ return C , est_Ik
190
+
191
+
192
+ def Func_Phi (X , epsilon = 1e-3 ):
193
+ return np .sqrt (X + epsilon ** 2 )
194
+
195
+ def Func_Phi_deriv (X , epsilon = 1e-3 ):
196
+ return 0.5 / Func_Phi (X , epsilon )
197
+
198
+ def solve_images (J , W_m , alpha , W_init , gamma = 1 , beta = 0.01 , lambda_w = 0.01 , lambda_i = 0.01 , lambda_a = 0.01 , iters = 2 ):
199
+ '''
200
+ Master solver, follows the algorithm given in the supplementary.
201
+ W_init: Initial value of W
202
+ Step 1: Image Watermark decomposition
203
+ '''
204
+ # prepare variables
205
+ K , m , n , p = J .shape
206
+ size = m * n * p
207
+
208
+ sobelx = get_xSobel_matrix (m , n , p )
209
+ sobely = get_ySobel_matrix (m , n , p )
210
+ Ik = np .zeros (J .shape )
211
+ Wk = np .zeros (J .shape )
212
+ for i in xrange (K ):
213
+ Ik [i ] = J [i ] - W_m
214
+ Wk [i ] = W_init .copy ()
215
+
216
+ # This is for median images
217
+ W = W_init .copy ()
218
+
219
+ # Iterations
220
+ for _ in xrange (iters ):
221
+
222
+ # Step 1
223
+ print ("Step 1" )
224
+ alpha_gx = cv2 .Sobel (alpha , cv2 .CV_64F , 1 , 0 , 3 )
225
+ alpha_gy = cv2 .Sobel (alpha , cv2 .CV_64F , 0 , 1 , 3 )
226
+
227
+ Wm_gx = cv2 .Sobel (W_m , cv2 .CV_64F , 1 , 0 , 3 )
228
+ Wm_gy = cv2 .Sobel (W_m , cv2 .CV_64F , 0 , 1 , 3 )
229
+
230
+ cx = diags (np .abs (alpha_gx ).reshape (- 1 ))
231
+ cy = diags (np .abs (alpha_gy ).reshape (- 1 ))
232
+
233
+ alpha_diag = diags (alpha .reshape (- 1 ))
234
+ alpha_bar_diag = diags ((1 - alpha ).reshape (- 1 ))
235
+
236
+ for i in xrange (K ):
237
+ # prep vars
238
+ Wkx = cv2 .Sobel (Wk [i ], cv2 .CV_64F , 1 , 0 , 3 )
239
+ Wky = cv2 .Sobel (Wk [i ], cv2 .CV_64F , 0 , 1 , 3 )
240
+
241
+ Ikx = cv2 .Sobel (Ik [i ], cv2 .CV_64F , 1 , 0 , 3 )
242
+ Iky = cv2 .Sobel (Ik [i ], cv2 .CV_64F , 0 , 1 , 3 )
243
+
244
+ alphaWk = alpha * Wk [i ]
245
+ alphaWk_gx = cv2 .Sobel (alphaWk , cv2 .CV_64F , 1 , 0 , 3 )
246
+ alphaWk_gy = cv2 .Sobel (alphaWk , cv2 .CV_64F , 0 , 1 , 3 )
247
+
248
+ phi_data = diags ( Func_Phi_deriv (np .square (alpha * Wk [i ] + (1 - alpha )* Ik [i ] - J [i ]).reshape (- 1 )) )
249
+ phi_W = diags ( Func_Phi_deriv (np .square ( np .abs (alpha_gx )* Wkx + np .abs (alpha_gy )* Wky ).reshape (- 1 )) )
250
+ phi_I = diags ( Func_Phi_deriv (np .square ( np .abs (alpha_gx )* Ikx + np .abs (alpha_gy )* Iky ).reshape (- 1 )) )
251
+ phi_f = diags ( Func_Phi_deriv ( ((Wm_gx - alphaWk_gx )** 2 + (Wm_gy - alphaWk_gy )** 2 ).reshape (- 1 )) )
252
+ phi_aux = diags ( Func_Phi_deriv (np .square (Wk [i ] - W ).reshape (- 1 )) )
253
+ phi_rI = diags ( Func_Phi_deriv ( np .abs (alpha_gx )* (Ikx ** 2 ) + np .abs (alpha_gy )* (Iky ** 2 ) ).reshape (- 1 ) )
254
+ phi_rW = diags ( Func_Phi_deriv ( np .abs (alpha_gx )* (Wkx ** 2 ) + np .abs (alpha_gy )* (Wky ** 2 ) ).reshape (- 1 ) )
255
+
256
+ L_i = sobelx .T .dot (cx * phi_rI ).dot (sobelx ) + sobely .T .dot (cy * phi_rI ).dot (sobely )
257
+ L_w = sobelx .T .dot (cx * phi_rW ).dot (sobelx ) + sobely .T .dot (cy * phi_rW ).dot (sobely )
258
+ L_f = sobelx .T .dot (phi_f ).dot (sobelx ) + sobely .T .dot (phi_f ).dot (sobely )
259
+ A_f = alpha_diag .T .dot (L_f ).dot (alpha_diag ) + gamma * phi_aux
260
+
261
+ bW = alpha_diag .dot (phi_data ).dot (J [i ].reshape (- 1 )) + beta * L_f .dot (W_m .reshape (- 1 )) + gamma * phi_aux .dot (W .reshape (- 1 ))
262
+ bI = alpha_bar_diag .dot (phi_data ).dot (J [i ].reshape (- 1 ))
263
+
264
+ A = vstack ([hstack ([(alpha_diag ** 2 )* phi_data + lambda_w * L_w + beta * A_f , alpha_diag * alpha_bar_diag * phi_data ]), \
265
+ hstack ([alpha_diag * alpha_bar_diag * phi_data , (alpha_bar_diag ** 2 )* phi_data + lambda_i * L_i ])]).tocsr ()
266
+
267
+ b = np .hstack ([bW , bI ])
268
+ x = linalg .spsolve (A , b )
269
+
270
+ Wk [i ] = x [:size ].reshape (m , n , p )
271
+ Ik [i ] = x [size :].reshape (m , n , p )
272
+ plt .subplot (2 ,1 ,1 ); plt .imshow (PlotImage (Wk [i ]))
273
+ plt .subplot (2 ,1 ,2 ); plt .imshow (PlotImage (Ik [i ])); plt .show ()
274
+ print (i )
275
+
276
+ # Step 2
277
+ print ("Step 2" )
278
+ W = np .median (Wk , axis = 0 )
279
+
280
+ # Step 3
281
+ print ("Step 3" )
282
+ W_diag = diags (W .reshape (- 1 ))
283
+
284
+ for i in range (K ):
285
+ alphaWk = alpha * Wk [i ]
286
+ alphaWk_gx = cv2 .Sobel (alphaWk , cv2 .CV_64F , 1 , 0 , 3 )
287
+ alphaWk_gy = cv2 .Sobel (alphaWk , cv2 .CV_64F , 0 , 1 , 3 )
288
+ phi_f = diags ( Func_Phi_deriv ( ((Wm_gx - alphaWk_gx )** 2 + (Wm_gy - alphaWk_gy )** 2 ).reshape (- 1 )) )
289
+
290
+ phi_k = diags (Func_Phi_deriv (((alpha * Wk [i ] + (1 - alpha )* Ik [i ] - J [i ])** 2 )* (W - Ik [i ])).reshape (- 1 ))
291
+ phi_alpha = diags (Func_Phi_deriv (alpha_gx ** 2 + alpha_gy ** 2 ).reshape (- 1 ))
292
+ L_alpha = sobelx .T .dot (phi_alpha .dot (sobelx )) + sobely .T .dot (phi_alpha .dot (sobely ))
293
+
294
+ L_f = sobelx .T .dot (phi_f ).dot (sobelx ) + sobely .dot (phi_f ).dot (sobely )
295
+ A_tilde_f = W_diag .dot (L_f ).dot (W_diag )
296
+
297
+ # Ax = b, setting up A
298
+ if i == 0 :
299
+ A1 = phi_k + lambda_a * L_alpha + beta * A_tilde_f
300
+ b1 = phi_k .dot ((J [i ]- Ik [i ]).reshape (- 1 )) + beta * W_diag .dot (L_f ).dot (W_m .reshape (- 1 ))
301
+ else :
302
+ A1 += (phi_k + lambda_a * L_alpha + beta * A_tilde_f )
303
+ b1 += (phi_k .dot ((J [i ]- Ik [i ]).reshape (- 1 )) + beta * W_diag .dot (L_f ).dot (W_m .reshape (- 1 )))
304
+
305
+ alpha = linalg .spsolve (A1 , b1 ).reshape (m ,n ,p )
306
+
307
+ return (Wk , Ik , W , alpha )
0 commit comments