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
"""The main file for the reconstruction.
This file should NOT be modified except the body of the 'run_reconstruction' function.
Students can call their functions (declared in others files of src/methods/your_name).
"""
from src.forward_model import CFA
import numpy as np
from scipy.signal import convolve2d
import cv2
def is_green(z,i, j):
return z[i, j, 1] != 0
def hamilton_adams_interpolation(y, op, z):
height, width = y.shape
green_channel = np.copy(z[:, :, 1])
for i in range(1, height-1):
for j in range(1, width-1):
if not is_green(z,i, j) :
delta_H = abs(z[i, j-1, 1] - z[i, j+1, 1]) + abs(z[i, j-1, 0] - z[i, j+1, 0] + z[i, j-1, 2] - z[i, j+1, 2]) / 2
# print(f"delta_H : {delta_H}")
delta_V = abs(z[i-1, j, 1] - z[i+1, j, 1]) + abs(z[i-1, j, 0] - z[i+1, j, 0] + z[i-1, j, 2] - z[i+1, j, 2]) / 2
if delta_H > delta_V:
green_channel[i, j] = (z[i-1, j, 1] + z[i+1, j, 1]) / 2 + (z[i, j-1, 0] - z[i, j+1, 0] + z[i, j-1, 2] - z[i, j+1, 2]) / 4
elif delta_H < delta_V:
green_channel[i, j] = (z[i, j-1, 1] + z[i, j+1, 1]) / 2 + (z[i-1, j, 0] - z[i+1, j, 0] + z[i-1, j, 2] - z[i+1, j, 2]) / 4
else:
green_channel[i, j] = (z[i-1, j, 1] + z[i+1, j, 1] + z[i, j-1, 1] + z[i, j+1, 1]) / 4 + \
(z[i, j-1, 0] - z[i, j+1, 0] + z[i, j-1, 2] - z[i, j+1, 2] + \
z[i-1, j, 0] - z[i+1, j, 0] + z[i-1, j, 2] - z[i+1, j, 2]) / 8
return green_channel
def interpolate_channel_difference(mosaicked_channel, green_channel_interpolated):
ker_bayer_red_blue = np.array([[1, 2, 1], [2, 4, 2], [1, 2, 1]]) / 4
print(mosaicked_channel.shape, green_channel_interpolated.shape)
difference = mosaicked_channel - green_channel_interpolated
difference_interpolated = convolve2d(difference, np.ones((3, 3)) / 9, mode='same', boundary='wrap')
channel_interpolated = green_channel_interpolated + difference_interpolated
channel_interpolated = convolve2d(channel_interpolated, ker_bayer_red_blue, mode='same')
return channel_interpolated
def Constant_difference_based_interpolation_reconstruction(op, y, z):
if op.cfa == 'bayer':
print("bayer")
red_channel = z[:, :, 0]
green_channel = z[:, :, 1]
blue_channel = z[:, :, 2]
green_channel_reconstruct = hamilton_adams_interpolation(y, op, z)
red_channel_interpolated = interpolate_channel_difference(red_channel, green_channel_reconstruct)
blue_channel_interpolated = interpolate_channel_difference(blue_channel, green_channel_reconstruct)
reconstructed_image = np.stack((red_channel_interpolated, green_channel_reconstruct, blue_channel_interpolated), axis=-1)
return reconstructed_image
elif op.cfa == "quad_bayer":
print(f"quad_bayer")
new_z = cv2.resize(z, (z.shape[1] // 2, z.shape[0] // 2), interpolation=cv2.INTER_AREA)
new_y=np.sum(new_z, axis=2)
op.mask = op.mask[::2, ::2]
green_channel_reconstruct_new = hamilton_adams_interpolation(new_y, op, new_z)
red_channel_new = new_z[:, :, 0]
blue_channel_new = new_z[:, :, 2]
red_channel_interpolated_new = interpolate_channel_difference(red_channel_new, green_channel_reconstruct_new)
blue_channel_interpolated_new = interpolate_channel_difference(blue_channel_new, green_channel_reconstruct_new)
reconstructed_image_new = np.stack((red_channel_interpolated_new, green_channel_reconstruct_new, blue_channel_interpolated_new), axis=-1)
reconstructed_image_upsampled = cv2.resize(reconstructed_image_new, (z.shape[1], z.shape[0]), interpolation=cv2.INTER_LINEAR)
return reconstructed_image_upsampled
else :
raise ValueError("CFA pattern not recognized")
def run_reconstruction(y: np.ndarray, cfa: str) -> np.ndarray:
"""Performs demosaicking on y.
Args:
y (np.ndarray): Mosaicked image to be reconstructed.
cfa (str): Name of the CFA. Can be bayer or quad_bayer.
Returns:
np.ndarray: Demosaicked image.
"""
input_shape = (y.shape[0], y.shape[1], 3)
op = CFA(cfa, input_shape)
z = op.adjoint(y)
reconstructed_image = Constant_difference_based_interpolation_reconstruction(op, y, z)
return reconstructed_image
####
####
####
#### #### #### #############
#### ###### #### ##################
#### ######## #### ####################
#### ########## #### #### ########
#### ############ #### #### ####
#### #### ######## #### #### ####
#### #### ######## #### #### ####
#### #### ######## #### #### ####
#### #### ## ###### #### #### ######
#### #### #### ## #### #### ############
#### #### ###### #### #### ##########
#### #### ########## #### #### ########
#### #### ######## #### ####
#### #### ############ ####
#### #### ########## ####
#### #### ######## ####
#### #### ###### ####
# 2023
# Authors: Mauro Dalla Mura and Matthieu Muller