-
Notifications
You must be signed in to change notification settings - Fork 3
/
Decomposition.m
104 lines (86 loc) · 2.6 KB
/
Decomposition.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
function [F, G, N] = Decomposition( I, alpha ,ii , beta, gamma)
% Layer Separation using Relative Smoothness (specific for intrinsic images)
% Image properties
I(I>1) = 1;
gray = rgb2gray(I);
[H,W,D] = size(I);
% Convolutional kernels
f1 = [1, -1];
f2 = [1; -1];
f4 = [0, -1, 0; -1, 4, -1; 0, -1, 0];
% Enhance gradient of I
[weight_x, weight_y] = Gradient_weight(I);
I_filt = imgaussfilt(gray,10);
delta_I = I - I_filt;
% main
otfFx = psf2otf(f1, [H,W]);
otfFy = psf2otf(f2, [H,W]);
otfL = psf2otf(f4, [H,W]);
fft_double_laplace = abs(otfL).^2 ;
fft_double_grad = abs(otfFx).^2 + abs(otfFy).^2;
if D > 1
fft_double_grad = repmat(fft_double_grad,[1,1,D]);
fft_double_laplace = repmat(fft_double_laplace,[1,1,D]);
weight_x = repmat(weight_x,[1,1,D]);
weight_y = repmat(weight_y,[1,1,D]);
end
F = 0;
N = 0;
Ix = - imfilter(I,f1); Iy = - imfilter(I,f2);
Normin_I = fft2([Ix(:,end,:) - Ix(:,1,:), -diff(Ix,1,2)] + ...
[Iy(end,:,:) - Iy(1,:,:); -diff(Iy,1,1)]);
Denormin_N = gamma + alpha * fft_double_laplace + beta;
Normin_gI = fft_double_laplace .* fft2(I);
i = 0;
while true
i = i+1;
prev_F = F;
lambda = min(2^(ii + i), 10^5);
Denormin_F = lambda * fft_double_grad + alpha * fft_double_laplace + beta;
% update q
qx = - imfilter(F,f1,'circular') - Ix ;
qy = - imfilter(F,f2,'circular') - Iy ;
qx = sign(qx) .* max(abs(qx) - weight_x/lambda, 0);
qy = sign(qy) .* max(abs(qy) - weight_y/lambda, 0);
% compute fog layer (F)
Normin_q = [qx(:,end,:) - qx(:,1,:), -diff(qx,1,2)] + ...
[qy(end,:,:) - qy(1,:,:); -diff(qy,1,1)];
Normin_gN = fft_double_laplace .* fft2(N);
FF = (lambda * (Normin_I + fft2(Normin_q)) + ...
alpha * (Normin_gI - Normin_gN) + beta * fft2(delta_I - N)) ...
./ Denormin_F;
F = real(ifft2(FF));
% compute Noise
Normin_F = fft_double_laplace .* fft2(F);
B = fft2(delta_I - F);
NN = (alpha * (Normin_gI - Normin_F) + beta * B)./Denormin_N;
N = real(ifft2(NN));
if sum(sum(sum(abs(prev_F - F))))/(H*W) < 10^(-1)
break
end
end
% normalize F
for c = 1:D
Ft = F(:,:,c);
q = numel(Ft);
for k = 1:500
m = sum(Ft(Ft<0));
n = sum(Ft(Ft>1)-1);
dt = (m + n)/q;
if abs(dt) < 1/q
break;
end
Ft = Ft - dt;
end
F(:,:,c) = Ft;
end
F = abs(F);
F(F>1) = 1;
N(N>1) = 1;
N(N<0) = 0;
N = mean(N,3);
G = abs(I - F - N);
G = min(G, [], 3);
G = imgaussfilt(G,3);
F = abs(I - G - N);
F(F == 0) = 0.001;