eari-package 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- eari_package-0.1.0/PKG-INFO +9 -0
- eari_package-0.1.0/README.md +0 -0
- eari_package-0.1.0/eari_package/__init__.py +2 -0
- eari_package-0.1.0/eari_package/eari.py +141 -0
- eari_package-0.1.0/eari_package/ri.py +231 -0
- eari_package-0.1.0/eari_package.egg-info/PKG-INFO +9 -0
- eari_package-0.1.0/eari_package.egg-info/SOURCES.txt +10 -0
- eari_package-0.1.0/eari_package.egg-info/dependency_links.txt +1 -0
- eari_package-0.1.0/eari_package.egg-info/requires.txt +3 -0
- eari_package-0.1.0/eari_package.egg-info/top_level.txt +1 -0
- eari_package-0.1.0/pyproject.toml +15 -0
- eari_package-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: eari_package
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: EARI image demosaicking implementation
|
|
5
|
+
Requires-Python: >=3.8
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: numpy>=2.4.4
|
|
8
|
+
Requires-Dist: opencv-python>=4.13.0.92
|
|
9
|
+
Requires-Dist: scipy>=1.17.1
|
|
File without changes
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import cv2
|
|
3
|
+
from fast_ri import guidedfilter, bilinear_RB, ri,standardize_input
|
|
4
|
+
def MEARI(MPFA):
|
|
5
|
+
eps=1e-32
|
|
6
|
+
Fn=np.array([[1,2,1],[1,2,1],[0,0,0]], dtype=np.float32)/8
|
|
7
|
+
Fs=np.array([[0,0,0],[1,2,1],[1,2,1]], dtype=np.float32)/8
|
|
8
|
+
Fw=Fn.T
|
|
9
|
+
Fe=Fs.T
|
|
10
|
+
|
|
11
|
+
Hn=np.array([[-1,2,-1],[1,-2,1],[0,0,0]], dtype=np.float32)/2
|
|
12
|
+
Hs=np.array([[0,0,0],[1,-2,1],[-1,2,-1]], dtype=np.float32)/2
|
|
13
|
+
Hw=Hn.T
|
|
14
|
+
He=Hs.T
|
|
15
|
+
|
|
16
|
+
Mn=np.ones((5,5), dtype=np.float32)/15
|
|
17
|
+
Mn[3:,:]=0
|
|
18
|
+
Ms=Mn[::-1,:]
|
|
19
|
+
Mw=Mn.T
|
|
20
|
+
Me=Ms.T
|
|
21
|
+
|
|
22
|
+
MPFA32 = standardize_input(MPFA)
|
|
23
|
+
|
|
24
|
+
Xn = cv2.filter2D(MPFA32, -1, Fn, borderType=cv2.BORDER_REFLECT_101)
|
|
25
|
+
Xs = cv2.filter2D(MPFA32, -1, Fs, borderType=cv2.BORDER_REFLECT_101)
|
|
26
|
+
Xe = cv2.filter2D(MPFA32, -1, Fe, borderType=cv2.BORDER_REFLECT_101)
|
|
27
|
+
Xw = cv2.filter2D(MPFA32, -1, Fw, borderType=cv2.BORDER_REFLECT_101)
|
|
28
|
+
|
|
29
|
+
Dn = cv2.filter2D(MPFA32, -1, Hn, borderType=cv2.BORDER_REFLECT_101)
|
|
30
|
+
Ds = cv2.filter2D(MPFA32, -1, Hs, borderType=cv2.BORDER_REFLECT_101)
|
|
31
|
+
De = cv2.filter2D(MPFA32, -1, He, borderType=cv2.BORDER_REFLECT_101)
|
|
32
|
+
Dw = cv2.filter2D(MPFA32, -1, Hw, borderType=cv2.BORDER_REFLECT_101)
|
|
33
|
+
|
|
34
|
+
sDn = cv2.filter2D(np.abs(Dn), -1, Mn, borderType=cv2.BORDER_REFLECT_101)
|
|
35
|
+
sDs = cv2.filter2D(np.abs(Ds), -1, Ms, borderType=cv2.BORDER_REFLECT_101)
|
|
36
|
+
sDe = cv2.filter2D(np.abs(De), -1, Me, borderType=cv2.BORDER_REFLECT_101)
|
|
37
|
+
sDw = cv2.filter2D(np.abs(Dw), -1, Mw, borderType=cv2.BORDER_REFLECT_101)
|
|
38
|
+
|
|
39
|
+
Wn = 1 / (sDn + eps)
|
|
40
|
+
Ws = 1 / (sDs + eps)
|
|
41
|
+
We = 1 / (sDe + eps)
|
|
42
|
+
Ww = 1 / (sDw + eps)
|
|
43
|
+
|
|
44
|
+
W = Wn + Ws + We + Ww
|
|
45
|
+
|
|
46
|
+
G = (Wn*Xn + Ws*Xs + We*Xe + Ww*Xw) / W
|
|
47
|
+
|
|
48
|
+
M = np.zeros_like(MPFA)
|
|
49
|
+
M90 = np.copy(M)
|
|
50
|
+
M00 = np.copy(M)
|
|
51
|
+
M45 = np.copy(M)
|
|
52
|
+
M135 = np.copy(M)
|
|
53
|
+
|
|
54
|
+
M90[0::2,0::2] = 1
|
|
55
|
+
M00[1::2,1::2] = 1
|
|
56
|
+
M45[0::2,1::2] = 1
|
|
57
|
+
M135[1::2,0::2] = 1
|
|
58
|
+
|
|
59
|
+
I90_sparse = np.copy(M)
|
|
60
|
+
I00_sparse = np.copy(M)
|
|
61
|
+
I45_sparse = np.copy(M)
|
|
62
|
+
I135_sparse = np.copy(M)
|
|
63
|
+
|
|
64
|
+
I90_sparse[0::2,0::2] = MPFA[0::2,0::2]
|
|
65
|
+
I00_sparse[1::2,1::2] = MPFA[1::2,1::2]
|
|
66
|
+
I45_sparse[0::2,1::2] = MPFA[0::2,1::2]
|
|
67
|
+
I135_sparse[1::2,0::2] = MPFA[1::2,0::2]
|
|
68
|
+
|
|
69
|
+
I90_t = guidedfilter(G, I90_sparse, M90, 5, 5)
|
|
70
|
+
I00_t = guidedfilter(G, I00_sparse, M00, 5, 5)
|
|
71
|
+
I45_t = guidedfilter(G, I45_sparse, M45, 5, 5)
|
|
72
|
+
I135_t = guidedfilter(G, I135_sparse, M135, 5, 5)
|
|
73
|
+
|
|
74
|
+
I90_res = M90 * (MPFA - I90_t)
|
|
75
|
+
I00_res = M00 * (MPFA - I00_t)
|
|
76
|
+
I45_res = M45 * (MPFA - I45_t)
|
|
77
|
+
I135_res = M135 * (MPFA - I135_t)
|
|
78
|
+
|
|
79
|
+
I90 = bilinear_RB(I90_res) + I90_t
|
|
80
|
+
I00 = bilinear_RB(I00_res) + I00_t
|
|
81
|
+
I45 = bilinear_RB(I45_res) + I45_t
|
|
82
|
+
I135 = bilinear_RB(I135_res) + I135_t
|
|
83
|
+
|
|
84
|
+
return I90, I00, I45, I135
|
|
85
|
+
|
|
86
|
+
def make_mpfa(rgb90,rgb00,rgb45,rgb135):
|
|
87
|
+
R90,G90,B90=rgb90[:,:,0],rgb90[:,:,1],rgb90[:,:,2]
|
|
88
|
+
R00,G00,B00=rgb00[:,:,0],rgb00[:,:,1],rgb00[:,:,2]
|
|
89
|
+
R45,G45,B45=rgb45[:,:,0],rgb45[:,:,1],rgb45[:,:,2]
|
|
90
|
+
R135,G135,B135=rgb135[:,:,0],rgb135[:,:,1],rgb135[:,:,2]
|
|
91
|
+
x,y=rgb90.shape[:2]
|
|
92
|
+
|
|
93
|
+
RMPFA=np.empty((2*x,2*y), dtype=np.float32)
|
|
94
|
+
GMPFA=np.empty((2*x,2*y), dtype=np.float32)
|
|
95
|
+
BMPFA=np.empty((2*x,2*y), dtype=np.float32)
|
|
96
|
+
|
|
97
|
+
RMPFA[::2,::2]=R90
|
|
98
|
+
RMPFA[1::2,1::2]=R00
|
|
99
|
+
RMPFA[0::2,1::2]=R45
|
|
100
|
+
RMPFA[1::2,0::2]=R135
|
|
101
|
+
|
|
102
|
+
GMPFA[::2,::2]=G90
|
|
103
|
+
GMPFA[1::2,1::2]=G00
|
|
104
|
+
GMPFA[0::2,1::2]=G45
|
|
105
|
+
GMPFA[1::2,0::2]=G135
|
|
106
|
+
|
|
107
|
+
BMPFA[::2,::2]=B90
|
|
108
|
+
BMPFA[1::2,1::2]=B00
|
|
109
|
+
BMPFA[0::2,1::2]=B45
|
|
110
|
+
BMPFA[1::2,0::2]=B135
|
|
111
|
+
|
|
112
|
+
return RMPFA,GMPFA,BMPFA
|
|
113
|
+
|
|
114
|
+
def CEARI(CPFA,pattern):
|
|
115
|
+
CPFA_standard = standardize_input(CPFA)
|
|
116
|
+
cfa90=CPFA_standard[0::2,0::2]
|
|
117
|
+
cfa00=CPFA_standard[1::2,1::2]
|
|
118
|
+
cfa45=CPFA_standard[0::2,1::2]
|
|
119
|
+
cfa135=CPFA_standard[1::2,0::2]
|
|
120
|
+
#if speed is importnat you can use a faster color demosaicking algo
|
|
121
|
+
rgb90=ri(cfa90,pattern)
|
|
122
|
+
rgb00=ri(cfa00,pattern)
|
|
123
|
+
rgb45=ri(cfa45,pattern)
|
|
124
|
+
rgb135=ri(cfa135,pattern)
|
|
125
|
+
|
|
126
|
+
RMPFA,GMPFA,BMPFA=make_mpfa(rgb90,rgb00,rgb45,rgb135)
|
|
127
|
+
|
|
128
|
+
R90,R00,R45,R135=MEARI(RMPFA)
|
|
129
|
+
G90,G00,G45,G135=MEARI(GMPFA)
|
|
130
|
+
B90,B00,B45,B135=MEARI(BMPFA)
|
|
131
|
+
|
|
132
|
+
RGB90=np.stack((R90,G90,B90),axis=-1)
|
|
133
|
+
RGB00=np.stack((R00,G00,B00),axis=-1)
|
|
134
|
+
RGB45=np.stack((R45,G45,B45),axis=-1)
|
|
135
|
+
RGB135=np.stack((R135,G135,B135),axis=-1)
|
|
136
|
+
|
|
137
|
+
RGB90=np.clip(RGB90,0,1)
|
|
138
|
+
RGB00=np.clip(RGB00,0,1)
|
|
139
|
+
RGB45=np.clip(RGB45,0,1)
|
|
140
|
+
RGB135=np.clip(RGB135,0,1)
|
|
141
|
+
return RGB90,RGB00,RGB45,RGB135
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from scipy import ndimage as nd
|
|
3
|
+
import cv2
|
|
4
|
+
|
|
5
|
+
offsets = {
|
|
6
|
+
'RGGB': {'R': (0,0), 'Gr': (0,1), 'Gb': (1,0), 'B': (1,1)},
|
|
7
|
+
'BGGR': {'R': (1,1), 'Gr': (1,0), 'Gb': (0,1), 'B': (0,0)},
|
|
8
|
+
'GRBG': {'R': (0,1), 'Gr': (0,0), 'Gb': (1,1), 'B': (1,0)},
|
|
9
|
+
'GBRG': {'R': (1,0), 'Gr': (1,1), 'Gb': (0,0), 'B': (0,1)},
|
|
10
|
+
}
|
|
11
|
+
def standardize_input(img):
|
|
12
|
+
if img.dtype == np.uint8:
|
|
13
|
+
return img.astype(np.float32) / 255.0
|
|
14
|
+
elif img.dtype == np.float32:
|
|
15
|
+
return img
|
|
16
|
+
else:
|
|
17
|
+
return img.astype(np.float32)
|
|
18
|
+
|
|
19
|
+
def getRGB_known(cfa,pattern):
|
|
20
|
+
R=np.zeros(cfa.shape, dtype=np.float32)
|
|
21
|
+
G=np.copy(R)
|
|
22
|
+
B=np.copy(R)
|
|
23
|
+
channels={'R':R,'G':G,'B':B}
|
|
24
|
+
for ch, (r0, c0) in offsets[pattern].items():
|
|
25
|
+
channels[ch[0]][r0::2,c0::2]=cfa[r0::2,c0::2]
|
|
26
|
+
return R,G,B
|
|
27
|
+
|
|
28
|
+
def make_cfa(img_path, pattern):
|
|
29
|
+
channel={'B':0,'Gr':1,'Gb':1,'R':2}
|
|
30
|
+
bgr_img=cv2.imread(img_path).astype(np.float32)/255.0
|
|
31
|
+
cfa=np.zeros(bgr_img.shape[:2], dtype=np.float32)
|
|
32
|
+
for ch, (r0, c0) in offsets[pattern].items():
|
|
33
|
+
cfa[r0::2,c0::2]=bgr_img[r0::2,c0::2,channel[ch]]
|
|
34
|
+
return cfa
|
|
35
|
+
|
|
36
|
+
def bilinear_1D(C_known_h,C_known_v,channel,pattern):
|
|
37
|
+
C_h=np.zeros_like(C_known_h)
|
|
38
|
+
C_v=np.zeros_like(C_known_v)
|
|
39
|
+
r,c=offsets[pattern][channel]
|
|
40
|
+
|
|
41
|
+
kernel_h = np.array([[0.5,1.0,0.5]], dtype=np.float32)
|
|
42
|
+
kernel_v=kernel_h.T
|
|
43
|
+
|
|
44
|
+
C_h[r::2,:]=cv2.filter2D(C_known_h[r::2,:].astype(np.float32), -1, kernel_h, borderType=cv2.BORDER_REFLECT_101)
|
|
45
|
+
C_v[:,c::2]=cv2.filter2D(C_known_v[:,c::2].astype(np.float32), -1, kernel_v, borderType=cv2.BORDER_REFLECT_101)
|
|
46
|
+
|
|
47
|
+
return C_h,C_v
|
|
48
|
+
|
|
49
|
+
def get_residuals(C_known,C_tent,channel,pattern):
|
|
50
|
+
r,c=offsets[pattern][channel]
|
|
51
|
+
C_res=np.zeros(C_known.shape, dtype=np.float32)
|
|
52
|
+
C_res[r::2,c::2]=C_known[r::2,c::2]-C_tent[r::2,c::2]
|
|
53
|
+
return C_res
|
|
54
|
+
|
|
55
|
+
def overlap(C,channel,pattern):
|
|
56
|
+
r,c=offsets[pattern][channel]
|
|
57
|
+
C_overlap=np.zeros(C.shape, dtype=np.float32)
|
|
58
|
+
C_overlap[r::2,c::2]=C[r::2,c::2]
|
|
59
|
+
return C_overlap
|
|
60
|
+
|
|
61
|
+
def half_gaussian_kernel(size, sigma):
|
|
62
|
+
x = np.arange(size)
|
|
63
|
+
kernel = np.exp(-x**2 / (2 * sigma**2))
|
|
64
|
+
return kernel / kernel.sum()
|
|
65
|
+
|
|
66
|
+
def get_delta(delta_h,delta_v,channel,pattern,N=5,sigma=1e+8):
|
|
67
|
+
delta_h_pad=np.pad(delta_h,((0,0),(1,1)),mode='symmetric')
|
|
68
|
+
delta_v_pad=np.pad(delta_v,((1,1),(0,0)),mode='symmetric')
|
|
69
|
+
|
|
70
|
+
Dh=np.abs(delta_h_pad[:,:-2]-delta_h_pad[:,2:])
|
|
71
|
+
Dv=np.abs(delta_v_pad[:-2,:]-delta_v_pad[2:,:])
|
|
72
|
+
eps=1e-5
|
|
73
|
+
|
|
74
|
+
wn = 1/(nd.uniform_filter(Dv, size=N, mode='mirror', origin=(2, 0))+eps)**2
|
|
75
|
+
ws = 1/(nd.uniform_filter(Dv, size=N, mode='mirror', origin=(-2, 0))+eps)**2
|
|
76
|
+
ww = 1/(nd.uniform_filter(Dh, size=N, mode='mirror', origin=(0, 2))+eps)**2
|
|
77
|
+
we = 1/(nd.uniform_filter(Dh, size=N, mode='mirror', origin=(0, -2))+eps)**2
|
|
78
|
+
|
|
79
|
+
wt=wn+ws+we+ww
|
|
80
|
+
f=half_gaussian_kernel(N, sigma)
|
|
81
|
+
|
|
82
|
+
delta_s=ws*nd.correlate1d(delta_v,f,origin=-2,axis=0,mode='mirror')
|
|
83
|
+
delta_e=we*nd.correlate1d(delta_h,f,origin=-2,axis=1,mode='mirror')
|
|
84
|
+
delta_w=ww*nd.correlate1d(delta_h,f[::-1],origin=2,axis=1,mode='mirror')
|
|
85
|
+
delta_n=wn*nd.correlate1d(delta_v,f[::-1],origin=2,axis=0,mode='mirror')
|
|
86
|
+
|
|
87
|
+
delta=np.zeros(delta_h.shape, dtype=np.float32)
|
|
88
|
+
r,c=offsets[pattern][channel]
|
|
89
|
+
delta[r::2,c::2]=((delta_n+delta_s+delta_e+delta_w)/wt)[r::2,c::2]
|
|
90
|
+
|
|
91
|
+
return delta
|
|
92
|
+
|
|
93
|
+
def guidedfilter(I,p,M,h,v,eps=0):
|
|
94
|
+
size_v=2*v+1 if v!=0 else 1
|
|
95
|
+
size_h=2*h+1 if h!=0 else 1
|
|
96
|
+
|
|
97
|
+
I32 = I.astype(np.float32, copy=False)
|
|
98
|
+
p32 = p.astype(np.float32, copy=False)
|
|
99
|
+
M32 = M.astype(np.float32, copy=False)
|
|
100
|
+
|
|
101
|
+
def boxfilter(img):
|
|
102
|
+
return cv2.boxFilter(img, cv2.CV_32F, (size_h, size_v), normalize=False, borderType=cv2.BORDER_REFLECT_101)
|
|
103
|
+
|
|
104
|
+
N = boxfilter(M32)
|
|
105
|
+
N[N==0]=1
|
|
106
|
+
N2 = boxfilter(np.ones_like(I32))
|
|
107
|
+
|
|
108
|
+
mean_I = boxfilter(I32*M32)/N
|
|
109
|
+
mean_p = boxfilter(p32)/N
|
|
110
|
+
mean_Ip = boxfilter(I32*p32)/N
|
|
111
|
+
|
|
112
|
+
cov_Ip = mean_Ip - mean_I*mean_p
|
|
113
|
+
|
|
114
|
+
mean_II = boxfilter(I32*I32*M32)/N
|
|
115
|
+
var_I = mean_II - mean_I*mean_I
|
|
116
|
+
|
|
117
|
+
th=1e-5
|
|
118
|
+
var_I = np.maximum(var_I, th)
|
|
119
|
+
|
|
120
|
+
a = cov_Ip/(var_I+eps)
|
|
121
|
+
b = mean_p - a*mean_I
|
|
122
|
+
|
|
123
|
+
mean_a = boxfilter(a)/N2
|
|
124
|
+
mean_b = boxfilter(b)/N2
|
|
125
|
+
|
|
126
|
+
q = mean_a*I32 + mean_b
|
|
127
|
+
return q
|
|
128
|
+
|
|
129
|
+
def guided_1D(G_d,C_known,d,channel,pattern,ep=0):
|
|
130
|
+
r,c=offsets[pattern][channel]
|
|
131
|
+
M=np.zeros_like(C_known)
|
|
132
|
+
M[r::2,c::2]=1.0
|
|
133
|
+
p=C_known*M
|
|
134
|
+
|
|
135
|
+
h=5 if d==1 else 0
|
|
136
|
+
v=5 if d==0 else 0
|
|
137
|
+
|
|
138
|
+
C_tent=guidedfilter(G_d,p,M,h,v,ep)
|
|
139
|
+
|
|
140
|
+
C_d=np.zeros_like(G_d)
|
|
141
|
+
if d==0:
|
|
142
|
+
C_d[:,c::2]=C_tent[:,c::2]
|
|
143
|
+
elif d==1:
|
|
144
|
+
C_d[r::2,:]=C_tent[r::2,:]
|
|
145
|
+
|
|
146
|
+
return C_d
|
|
147
|
+
|
|
148
|
+
def guided_upsampling(C,G,channel,pattern,ep=0):
|
|
149
|
+
r,c=offsets[pattern][channel]
|
|
150
|
+
M=np.zeros_like(C)
|
|
151
|
+
M[r::2,c::2]=1.0
|
|
152
|
+
p=C*M
|
|
153
|
+
return guidedfilter(G,p,M,5,5,ep)
|
|
154
|
+
|
|
155
|
+
def bilinear_RB(C):
|
|
156
|
+
kernel=np.array([[.25,.5,.25],
|
|
157
|
+
[.5,1,.5],
|
|
158
|
+
[.25,.5,.25]], dtype=np.float32)
|
|
159
|
+
return cv2.filter2D(C.astype(np.float32), -1, kernel, borderType=cv2.BORDER_REFLECT_101)
|
|
160
|
+
|
|
161
|
+
def ri(cfa,pattern):
|
|
162
|
+
cfa_standard = standardize_input(cfa)
|
|
163
|
+
R,G,B=getRGB_known(cfa_standard, pattern)
|
|
164
|
+
|
|
165
|
+
Grh_lin,Grv_lin=bilinear_1D(G,G,'R',pattern)
|
|
166
|
+
Rgh_lin,Rgv_lin=bilinear_1D(R,R,'R',pattern)
|
|
167
|
+
Gbh_lin,Gbv_lin=bilinear_1D(G,G,'B',pattern)
|
|
168
|
+
Bgh_lin,Bgv_lin=bilinear_1D(B,B,'B',pattern)
|
|
169
|
+
|
|
170
|
+
Rh_tent=guided_1D(Grh_lin,R,1,'R',pattern)
|
|
171
|
+
Rv_tent=guided_1D(Grv_lin,R,0,'R',pattern)
|
|
172
|
+
Grh_tent=guided_1D(Rgh_lin,G,1,'Gr',pattern)
|
|
173
|
+
Grv_tent=guided_1D(Rgv_lin,G,0,'Gb',pattern)
|
|
174
|
+
Bh_tent=guided_1D(Gbh_lin,B,1,'B',pattern)
|
|
175
|
+
Bv_tent=guided_1D(Gbv_lin,B,0,'B',pattern)
|
|
176
|
+
Gbh_tent=guided_1D(Bgh_lin,G,1,'Gb',pattern)
|
|
177
|
+
Gbv_tent=guided_1D(Bgv_lin,G,0,'Gr',pattern)
|
|
178
|
+
|
|
179
|
+
Rh_res=get_residuals(R,Rh_tent,'R',pattern)
|
|
180
|
+
Rv_res=get_residuals(R,Rv_tent,'R',pattern)
|
|
181
|
+
Grh_res=get_residuals(G,Grh_tent,'Gr',pattern)
|
|
182
|
+
Grv_res=get_residuals(G,Grv_tent,'Gb',pattern)
|
|
183
|
+
Bh_res=get_residuals(B,Bh_tent,'B',pattern)
|
|
184
|
+
Bv_res=get_residuals(B,Bv_tent,'B',pattern)
|
|
185
|
+
Gbh_res=get_residuals(G,Gbh_tent,'Gb',pattern)
|
|
186
|
+
Gbv_res=get_residuals(G,Gbv_tent,'Gr',pattern)
|
|
187
|
+
|
|
188
|
+
Rh_resin,Rv_resin=bilinear_1D(Rh_res,Rv_res,'R',pattern)
|
|
189
|
+
Grh_resin,Grv_resin=bilinear_1D(Grh_res,Grv_res,'R',pattern)
|
|
190
|
+
Bh_resin,Bv_resin=bilinear_1D(Bh_res,Bv_res,'B',pattern)
|
|
191
|
+
Gbh_resin,Gbv_resin=bilinear_1D(Gbh_res,Gbv_res,'B',pattern)
|
|
192
|
+
|
|
193
|
+
Rh=Rh_resin+Rh_tent
|
|
194
|
+
Rv=Rv_resin+Rv_tent
|
|
195
|
+
Grh=Grh_resin+Grh_tent
|
|
196
|
+
Grv=Grv_resin+Grv_tent
|
|
197
|
+
Bh=Bh_resin+Bh_tent
|
|
198
|
+
Bv=Bv_resin+Bv_tent
|
|
199
|
+
Gbh=Gbh_resin+Gbh_tent
|
|
200
|
+
Gbv=Gbv_resin+Gbv_tent
|
|
201
|
+
|
|
202
|
+
delta_gr_h=overlap(Grh,'R',pattern)-R+overlap(G,'Gr',pattern)-overlap(Rh,'Gr',pattern)
|
|
203
|
+
delta_gr_v=overlap(Grv,'R',pattern)-R+overlap(G,'Gb',pattern)-overlap(Rv,'Gb',pattern)
|
|
204
|
+
delta_gb_h=overlap(Gbh,'B',pattern)-B+overlap(G,'Gb',pattern)-overlap(Bh,'Gb',pattern)
|
|
205
|
+
delta_gb_v=overlap(Gbv,'B',pattern)-B+overlap(G,'Gr',pattern)-overlap(Bv,'Gr',pattern)
|
|
206
|
+
|
|
207
|
+
delta_gr=get_delta(delta_gr_h,delta_gr_v,'R',pattern)
|
|
208
|
+
delta_gb=get_delta(delta_gb_h,delta_gb_v,'B',pattern)
|
|
209
|
+
|
|
210
|
+
G_demosaicked=(R+delta_gr)+(B+delta_gb)+G
|
|
211
|
+
G_demosaicked = np.clip(G_demosaicked, 0, 1)
|
|
212
|
+
|
|
213
|
+
R_tent=guided_upsampling(R,G_demosaicked,'R',pattern)
|
|
214
|
+
B_tent=guided_upsampling(B,G_demosaicked,'B',pattern)
|
|
215
|
+
|
|
216
|
+
R_res=R-overlap(R_tent,'R',pattern)
|
|
217
|
+
B_res=B-overlap(B_tent,'B',pattern)
|
|
218
|
+
|
|
219
|
+
R_resin=bilinear_RB(R_res)
|
|
220
|
+
B_resin=bilinear_RB(B_res)
|
|
221
|
+
|
|
222
|
+
R_demosaicked=R_resin+R_tent
|
|
223
|
+
R_demosaicked=np.clip(R_demosaicked,0,1)
|
|
224
|
+
|
|
225
|
+
B_demosaicked=B_resin+B_tent
|
|
226
|
+
B_demosaicked=np.clip(B_demosaicked,0,1)
|
|
227
|
+
|
|
228
|
+
color_image=np.stack((R_demosaicked,G_demosaicked,B_demosaicked),axis=-1)
|
|
229
|
+
|
|
230
|
+
return color_image
|
|
231
|
+
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: eari_package
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: EARI image demosaicking implementation
|
|
5
|
+
Requires-Python: >=3.8
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: numpy>=2.4.4
|
|
8
|
+
Requires-Dist: opencv-python>=4.13.0.92
|
|
9
|
+
Requires-Dist: scipy>=1.17.1
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
eari_package/__init__.py
|
|
4
|
+
eari_package/eari.py
|
|
5
|
+
eari_package/ri.py
|
|
6
|
+
eari_package.egg-info/PKG-INFO
|
|
7
|
+
eari_package.egg-info/SOURCES.txt
|
|
8
|
+
eari_package.egg-info/dependency_links.txt
|
|
9
|
+
eari_package.egg-info/requires.txt
|
|
10
|
+
eari_package.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
eari_package
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "eari_package"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "EARI image demosaicking implementation"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"numpy>=2.4.4",
|
|
13
|
+
"opencv-python>=4.13.0.92",
|
|
14
|
+
"scipy>=1.17.1"
|
|
15
|
+
]
|