diff --git a/src/methods/maxime_torre/rapport_image_analysis_maxime_torre.pdf b/src/methods/maxime_torre/rapport_image_analysis_maxime_torre.pdf new file mode 100644 index 0000000000000000000000000000000000000000..526f0f1c1a4f451c81a780ae7a1610605e50ce64 Binary files /dev/null and b/src/methods/maxime_torre/rapport_image_analysis_maxime_torre.pdf differ diff --git a/src/methods/maxime_torre/reconstruct.py b/src/methods/maxime_torre/reconstruct.py new file mode 100644 index 0000000000000000000000000000000000000000..98eeaefe21ad4a9eb7f6593baf8fc0710a62c38e --- /dev/null +++ b/src/methods/maxime_torre/reconstruct.py @@ -0,0 +1,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