Newer
Older
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
import numpy as np
# interpolation kernels
w1 = np.array([[0,0,-1,0,0], [0,0,2,0,0], [-1,2,4,2,-1], [0,0,2,0,0], [0,0,-1,0,0]])/8 # G at R location
w2 = w1 #G at B location
w3 = np.array([[0,0,0.5,0,0], [0,-1,0,-1,0], [-1,4,5,4,-1], [0,-1,0,-1,0], [0,0,0.5,0,0]])/8 # R at G location (Brow, Rcol)
w4 = np.array([[0,0,-1,0,0], [0,-1,4,-1,0], [0.5,0,5,0,0.5], [0,-1,4,-1,0], [0,0,-1,0,0]])/8 # R at G location (Rrow, Bcol)
w5 = np.array([[0,0,-3/2,0,0], [0,2,0,2,0], [-3/2,0,6,0,-1], [0,2,0,2,0], [0,0,-3/2,0,0]])/8 # R at B location (Brow, Bcol)
w6 = w3 #R at G location (Brow, Rcol)
w7 = w4 #B at G location (Rrow, Bcol)
w8 = w5 #B at R location (Rrow, Rcol)
w_s = [w1, w2, w3, w4, w5, w6, w7, w8]
def conv(A,B):
return np.sum(A*B)
def bayer_gradient_interpolation(y, op, w=w_s):
"""
Second interpolation method: convolution with a 2D kernels (5x5) using multi-channel interpolations
y: input image
w: interpolation kernels
"""
y_padded = np.pad(y, ((2,2),(2,2)), 'constant', constant_values=0)
size_padded = y_padded.shape
#separate channels
y_0 = y*op.mask[:, :, 0]
y_1 = y*op.mask[:, :, 1]
y_2 = y*op.mask[:, :, 2]
for i in range(2,size_padded[0]-2):
for j in range(2,size_padded[1]-2):
# determine the location of the pixel
if op.mask[i-2,j-2,1] == 1: # at G
if op.mask[i-2,j-3,0] == 1: #R row
y_0[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w3)
y_2[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w7)
else: #B row
y_0[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w4)
y_2[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w6)
elif op.mask[i-2,j-2,0] == 1: # at R
y_1[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w1)
y_2[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w8)
else: # at B
y_1[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w2)
y_0[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w5)
y_res = np.zeros((y.shape[0], y.shape[1], 3))
y_res[:, :, 0] = y_0
y_res[:, :, 1] = y_1
y_res[:, :, 2] = y_2
return y_res
import numpy as np
def conv(A,B):
return np.sum(A*B)
def quad_gradient_interpolation(y, op):
"""
Second interpolation method: convolution with a 2D kernels (5x5) using multi-channel interpolations
y: input image
w: interpolation kernels
"""
y_padded = np.pad(y, ((2,2),(2,2)), 'constant', constant_values=0)
size_padded = y_padded.shape
mask_padded = np.pad(op.mask, ((2,2),(2,2),(0,0)), 'constant', constant_values=-1)
#separate channels
y_0 = y*op.mask[:, :, 0]
y_1 = y*op.mask[:, :, 1]
y_2 = y*op.mask[:, :, 2]
#interpolation kernels
# green quad kernels
wg11 = np.zeros((5,5))
wg11[0,2] = -3
wg11[1,2] = 13
wg11[2,4] = 2
wg11 += wg11.T
wg11 = wg11/24
# rotate the kernel
wg12 = np.rot90(wg11,3)
wg22 = np.rot90(wg11,2)
wg21 = np.rot90(wg11,1)
#red/blue quad kernels
# center part
w_c11 = np.zeros((5,5))
w_c11[0:2,0:2] = np.array([[-1,-1],[-1,9]])/6
w_c21 = np.rot90(w_c11,1)
w_c22 = np.rot90(w_c11,2)
w_c12 = np.rot90(w_c11,3)
# left part
w_l11 = np.zeros((5,5))
w_l11[0:2, 2] = np.array([-3,13])
w_l11[4,2] = 2
w_l11 = w_l11/12
w_l22 = np.rot90(w_l11,2)
# top part
w_t11 = np.rot90(w_l11,1)
w_t22 = np.rot90(w_t11,2)
for i in range(2,size_padded[0]-2):
for j in range(2,size_padded[1]-2):
# determine the location of the pixel
if mask_padded[i,j,1] == 1: # at G
if mask_padded[i-1,j,0] + mask_padded[i+1,j,0] == 1: # at R column
if mask_padded[i,j-1,2] == 1:
y_2[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w_t11)
elif mask_padded[i,j+1,2] == 1:
y_2[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w_t22)
if mask_padded[i-1,j,0] == 1:
y_0[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w_l11)
elif mask_padded[i+1,j,0] == 1:
y_0[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w_l22)
else:
if mask_padded[i,j-1,0] == 1:
y_0[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w_t11)
elif mask_padded[i,j+1,0] == 1:
y_0[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w_t22)
if mask_padded[i-1,j,2] == 1:
y_2[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w_l11)
elif mask_padded[i+1,j,2] == 1:
y_2[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w_l22)
elif mask_padded[i,j,1] == 0: # at R or B
if mask_padded[i-1,j,1] ==1:
if mask_padded[i,j-1,1] ==1:
y_1[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],wg11)
else:
y_1[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],wg12)
else:
if mask_padded[i,j-1,1] ==1:
y_1[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],wg21)
else:
y_1[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],wg22)
if mask_padded[i,j,0] == 1: #at R
if mask_padded[i-1,j-1,2] ==1: #center (1,1)
y_2[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w_c11)
elif mask_padded[i-1,j+1,2] ==1: #center (1,2)
y_2[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w_c12)
elif mask_padded[i+1,j-1,2] ==1: #center (2,1)
y_2[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w_c21)
elif mask_padded[i+1,j+1,2] ==1: #center (2,2)
y_2[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w_c22)
elif mask_padded[i,j,2] == 1: #at B
if mask_padded[i-1,j-1,0] ==1: #center (1,1)
y_0[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w_c11)
elif mask_padded[i-1,j+1,0] ==1: #center (1,2)
y_0[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w_c12)
elif mask_padded[i+1,j-1,0] ==1: #center (2,1)
y_0[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w_c21)
elif mask_padded[i+1,j+1,0] ==1: #center (2,2)
y_0[i-2,j-2] = conv(y_padded[i-2:i+3, j-2:j+3],w_c22)
y_res = np.zeros((y.shape[0], y.shape[1], 3))
y_res[:, :, 0] = y_0
y_res[:, :, 1] = y_1
y_res[:, :, 2] = y_2
return y_res
from scipy import signal
def interpolate(y, op, mode = 'bayer'):
"""
First interpolation method: convolution with a 2D kernel
y: input image
op: object of class CFA
"""
#separate channels
y_0 = y*op.mask[:, :, 0]
y_1 = y*op.mask[:, :, 1]
y_2 = y*op.mask[:, :, 2]
#convolution 2D
if mode == 'bayer':
a = np.array([1,2,1])
elif mode == 'quad_bayer':
a = np.array([1,2,3,2,1])
else:
raise Exception('Mode not supported')
# create the 2D kernel
w = a[:, None] * a[None, :]
w = w / np.sum(w)
#interpolate green
y_1_interpolated = signal.convolve2d(y_1, w, mode='same', boundary='fill', fillvalue=0)
#interpolate red
y_0_interpolated = signal.convolve2d(y_0, w, mode='same', boundary='fill', fillvalue=0)
# interpolate blue
y_2_interpolated = signal.convolve2d(y_2, w, mode='same', boundary='fill', fillvalue=0)
y_res = np.zeros((y.shape[0], y.shape[1], 3))
y_res[:,:,0] = y_0_interpolated*4
y_res[:,:,1] = y_1_interpolated*2
y_res[:,:,2] = y_2_interpolated*4
return y_res