diff --git a/.vscode/PythonImportHelper-v2-Completion.json b/.vscode/PythonImportHelper-v2-Completion.json new file mode 100644 index 0000000000000000000000000000000000000000..18adc695ef866459961a004c40b4130e1973502e --- /dev/null +++ b/.vscode/PythonImportHelper-v2-Completion.json @@ -0,0 +1,569 @@ +[ + { + "label": "numpy", + "kind": 6, + "isExtraImport": true, + "importPath": "numpy", + "description": "numpy", + "detail": "numpy", + "documentation": {} + }, + { + "label": "convolve2d", + "importPath": "scipy.signal", + "description": "scipy.signal", + "isExtraImport": true, + "detail": "scipy.signal", + "documentation": {} + }, + { + "label": "CFA", + "importPath": "src.forward_model", + "description": "src.forward_model", + "isExtraImport": true, + "detail": "src.forward_model", + "documentation": {} + }, + { + "label": "CFA", + "importPath": "src.forward_model", + "description": "src.forward_model", + "isExtraImport": true, + "detail": "src.forward_model", + "documentation": {} + }, + { + "label": "CFA", + "importPath": "src.forward_model", + "description": "src.forward_model", + "isExtraImport": true, + "detail": "src.forward_model", + "documentation": {} + }, + { + "label": "naive_interpolation", + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "isExtraImport": true, + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "*", + "importPath": "src.methods.ELAMRANI_Mouna.functions", + "description": "src.methods.ELAMRANI_Mouna.functions", + "isExtraImport": true, + "detail": "src.methods.ELAMRANI_Mouna.functions", + "documentation": {} + }, + { + "label": "exists", + "importPath": "os.path", + "description": "os.path", + "isExtraImport": true, + "detail": "os.path", + "documentation": {} + }, + { + "label": "check_cfa", + "importPath": "src.checks", + "description": "src.checks", + "isExtraImport": true, + "detail": "src.checks", + "documentation": {} + }, + { + "label": "check_rgb", + "importPath": "src.checks", + "description": "src.checks", + "isExtraImport": true, + "detail": "src.checks", + "documentation": {} + }, + { + "label": "check_data_range", + "importPath": "src.checks", + "description": "src.checks", + "isExtraImport": true, + "detail": "src.checks", + "documentation": {} + }, + { + "label": "check_rgb", + "importPath": "src.checks", + "description": "src.checks", + "isExtraImport": true, + "detail": "src.checks", + "documentation": {} + }, + { + "label": "check_shape", + "importPath": "src.checks", + "description": "src.checks", + "isExtraImport": true, + "detail": "src.checks", + "documentation": {} + }, + { + "label": "check_path", + "importPath": "src.checks", + "description": "src.checks", + "isExtraImport": true, + "detail": "src.checks", + "documentation": {} + }, + { + "label": "check_png", + "importPath": "src.checks", + "description": "src.checks", + "isExtraImport": true, + "detail": "src.checks", + "documentation": {} + }, + { + "label": "peak_signal_noise_ratio", + "importPath": "skimage.metrics", + "description": "skimage.metrics", + "isExtraImport": true, + "detail": "skimage.metrics", + "documentation": {} + }, + { + "label": "structural_similarity", + "importPath": "skimage.metrics", + "description": "skimage.metrics", + "isExtraImport": true, + "detail": "skimage.metrics", + "documentation": {} + }, + { + "label": "imread", + "importPath": "skimage.io", + "description": "skimage.io", + "isExtraImport": true, + "detail": "skimage.io", + "documentation": {} + }, + { + "label": "imsave", + "importPath": "skimage.io", + "description": "skimage.io", + "isExtraImport": true, + "detail": "skimage.io", + "documentation": {} + }, + { + "label": "naive_interpolation", + "kind": 2, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "def naive_interpolation(op: CFA, y: np.ndarray) -> np.ndarray:\n \"\"\"Performs a simple interpolation of the lost pixels.\n Args:\n op (CFA): CFA operator.\n y (np.ndarray): Mosaicked image.\n Returns:\n np.ndarray: Demosaicked image.\n \"\"\"\n z = op.adjoint(y)\n if op.cfa == 'bayer':", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "extract_padded", + "kind": 2, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "def extract_padded(M, size, i, j):\n N_i, N_j = M.shape\n res = np.zeros((size, size))\n middle_size = int((size - 1) / 2)\n for ii in range(- middle_size, middle_size + 1):\n for jj in range(- middle_size, middle_size + 1):\n if i + ii >= 0 and i + ii < N_i and j + jj >= 0 and j + jj < N_j:\n res[middle_size + ii, middle_size + jj] = M[i + ii, j + jj]\n return res\ndef varying_kernel_convolution(M, K_list):", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "varying_kernel_convolution", + "kind": 2, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "def varying_kernel_convolution(M, K_list):\n N_i, N_j = M.shape\n res = np.zeros_like(M)\n for i in range(N_i):\n for j in range(N_j):\n res[i, j] = np.sum(extract_padded(M, K_list[4 * (i % 4) + j % 4].shape[0], i, j) * K_list[4 * (i % 4) + j % 4])\n np.clip(res, 0, 1, res)\n return res\nK_identity = np.zeros((5, 5))\nK_identity[2, 2] = 1", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "K_identity", + "kind": 5, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "K_identity = np.zeros((5, 5))\nK_identity[2, 2] = 1\nK_red_0 = np.zeros((5, 5))\nK_red_0[2, :] = np.array([-3, 13, 0, 0, 2]) / 12\nK_red_1 = np.zeros((5, 5))\nK_red_1[2, :] = np.array([2, 0, 0, 13, -3]) / 12\nK_red_8 = np.zeros((5, 5))\nK_red_8[:2, :2] = np.array([[-1, -1], [-1, 9]]) / 6\nK_red_9 = np.zeros((5, 5))\nK_red_9[:2, 3:] = np.array([[-1, -1], [9, -1]]) / 6", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "K_red_0", + "kind": 5, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "K_red_0 = np.zeros((5, 5))\nK_red_0[2, :] = np.array([-3, 13, 0, 0, 2]) / 12\nK_red_1 = np.zeros((5, 5))\nK_red_1[2, :] = np.array([2, 0, 0, 13, -3]) / 12\nK_red_8 = np.zeros((5, 5))\nK_red_8[:2, :2] = np.array([[-1, -1], [-1, 9]]) / 6\nK_red_9 = np.zeros((5, 5))\nK_red_9[:2, 3:] = np.array([[-1, -1], [9, -1]]) / 6\nK_red_10 = np.zeros((5, 5))\nK_red_10[:, 2] = np.array([-3, 13, 0, 0, 2]) / 12", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "K_red_1", + "kind": 5, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "K_red_1 = np.zeros((5, 5))\nK_red_1[2, :] = np.array([2, 0, 0, 13, -3]) / 12\nK_red_8 = np.zeros((5, 5))\nK_red_8[:2, :2] = np.array([[-1, -1], [-1, 9]]) / 6\nK_red_9 = np.zeros((5, 5))\nK_red_9[:2, 3:] = np.array([[-1, -1], [9, -1]]) / 6\nK_red_10 = np.zeros((5, 5))\nK_red_10[:, 2] = np.array([-3, 13, 0, 0, 2]) / 12\nK_red_12 = np.zeros((5, 5))\nK_red_12[3:, :2] = np.array([[-1, 9], [-1, -1]]) / 6", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "K_red_8", + "kind": 5, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "K_red_8 = np.zeros((5, 5))\nK_red_8[:2, :2] = np.array([[-1, -1], [-1, 9]]) / 6\nK_red_9 = np.zeros((5, 5))\nK_red_9[:2, 3:] = np.array([[-1, -1], [9, -1]]) / 6\nK_red_10 = np.zeros((5, 5))\nK_red_10[:, 2] = np.array([-3, 13, 0, 0, 2]) / 12\nK_red_12 = np.zeros((5, 5))\nK_red_12[3:, :2] = np.array([[-1, 9], [-1, -1]]) / 6\nK_red_13 = np.zeros((5, 5))\nK_red_13[3:, 3:] = np.array([[9, -1], [-1, -1]]) / 6", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "K_red_9", + "kind": 5, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "K_red_9 = np.zeros((5, 5))\nK_red_9[:2, 3:] = np.array([[-1, -1], [9, -1]]) / 6\nK_red_10 = np.zeros((5, 5))\nK_red_10[:, 2] = np.array([-3, 13, 0, 0, 2]) / 12\nK_red_12 = np.zeros((5, 5))\nK_red_12[3:, :2] = np.array([[-1, 9], [-1, -1]]) / 6\nK_red_13 = np.zeros((5, 5))\nK_red_13[3:, 3:] = np.array([[9, -1], [-1, -1]]) / 6\nK_red_14 = np.zeros((5, 5))\nK_red_14[:, 2] = np.array([2, 0, 0, 13, -3]) / 12", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "K_red_10", + "kind": 5, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "K_red_10 = np.zeros((5, 5))\nK_red_10[:, 2] = np.array([-3, 13, 0, 0, 2]) / 12\nK_red_12 = np.zeros((5, 5))\nK_red_12[3:, :2] = np.array([[-1, 9], [-1, -1]]) / 6\nK_red_13 = np.zeros((5, 5))\nK_red_13[3:, 3:] = np.array([[9, -1], [-1, -1]]) / 6\nK_red_14 = np.zeros((5, 5))\nK_red_14[:, 2] = np.array([2, 0, 0, 13, -3]) / 12\nK_list_red = [K_red_0, K_red_1, K_identity, K_identity, K_red_0, K_red_1, K_identity, K_identity, K_red_8, K_red_9, K_red_10, K_red_10, K_red_12, K_red_13, K_red_14, K_red_14]\nK_green_2 = np.zeros((5, 5))", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "K_red_12", + "kind": 5, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "K_red_12 = np.zeros((5, 5))\nK_red_12[3:, :2] = np.array([[-1, 9], [-1, -1]]) / 6\nK_red_13 = np.zeros((5, 5))\nK_red_13[3:, 3:] = np.array([[9, -1], [-1, -1]]) / 6\nK_red_14 = np.zeros((5, 5))\nK_red_14[:, 2] = np.array([2, 0, 0, 13, -3]) / 12\nK_list_red = [K_red_0, K_red_1, K_identity, K_identity, K_red_0, K_red_1, K_identity, K_identity, K_red_8, K_red_9, K_red_10, K_red_10, K_red_12, K_red_13, K_red_14, K_red_14]\nK_green_2 = np.zeros((5, 5))\nK_green_2[2, :] = [-3, 13, 0, 0, 2]\nK_green_2[:, 2] = [-3, 13, 0, 0, 2]", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "K_red_13", + "kind": 5, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "K_red_13 = np.zeros((5, 5))\nK_red_13[3:, 3:] = np.array([[9, -1], [-1, -1]]) / 6\nK_red_14 = np.zeros((5, 5))\nK_red_14[:, 2] = np.array([2, 0, 0, 13, -3]) / 12\nK_list_red = [K_red_0, K_red_1, K_identity, K_identity, K_red_0, K_red_1, K_identity, K_identity, K_red_8, K_red_9, K_red_10, K_red_10, K_red_12, K_red_13, K_red_14, K_red_14]\nK_green_2 = np.zeros((5, 5))\nK_green_2[2, :] = [-3, 13, 0, 0, 2]\nK_green_2[:, 2] = [-3, 13, 0, 0, 2]\nK_green_2 = K_green_2 / 24\nK_green_3 = np.zeros((5, 5))", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "K_red_14", + "kind": 5, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "K_red_14 = np.zeros((5, 5))\nK_red_14[:, 2] = np.array([2, 0, 0, 13, -3]) / 12\nK_list_red = [K_red_0, K_red_1, K_identity, K_identity, K_red_0, K_red_1, K_identity, K_identity, K_red_8, K_red_9, K_red_10, K_red_10, K_red_12, K_red_13, K_red_14, K_red_14]\nK_green_2 = np.zeros((5, 5))\nK_green_2[2, :] = [-3, 13, 0, 0, 2]\nK_green_2[:, 2] = [-3, 13, 0, 0, 2]\nK_green_2 = K_green_2 / 24\nK_green_3 = np.zeros((5, 5))\nK_green_3[2, :] = [2, 0, 0, 13, -3]\nK_green_3[:, 2] = [-3, 13, 0, 0, 2]", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "K_list_red", + "kind": 5, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "K_list_red = [K_red_0, K_red_1, K_identity, K_identity, K_red_0, K_red_1, K_identity, K_identity, K_red_8, K_red_9, K_red_10, K_red_10, K_red_12, K_red_13, K_red_14, K_red_14]\nK_green_2 = np.zeros((5, 5))\nK_green_2[2, :] = [-3, 13, 0, 0, 2]\nK_green_2[:, 2] = [-3, 13, 0, 0, 2]\nK_green_2 = K_green_2 / 24\nK_green_3 = np.zeros((5, 5))\nK_green_3[2, :] = [2, 0, 0, 13, -3]\nK_green_3[:, 2] = [-3, 13, 0, 0, 2]\nK_green_3 = K_green_3 / 24\nK_green_6 = np.zeros((5, 5))", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "K_green_2", + "kind": 5, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "K_green_2 = np.zeros((5, 5))\nK_green_2[2, :] = [-3, 13, 0, 0, 2]\nK_green_2[:, 2] = [-3, 13, 0, 0, 2]\nK_green_2 = K_green_2 / 24\nK_green_3 = np.zeros((5, 5))\nK_green_3[2, :] = [2, 0, 0, 13, -3]\nK_green_3[:, 2] = [-3, 13, 0, 0, 2]\nK_green_3 = K_green_3 / 24\nK_green_6 = np.zeros((5, 5))\nK_green_6[2, :] = [-3, 13, 0, 0, 2]", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "K_green_2", + "kind": 5, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "K_green_2 = K_green_2 / 24\nK_green_3 = np.zeros((5, 5))\nK_green_3[2, :] = [2, 0, 0, 13, -3]\nK_green_3[:, 2] = [-3, 13, 0, 0, 2]\nK_green_3 = K_green_3 / 24\nK_green_6 = np.zeros((5, 5))\nK_green_6[2, :] = [-3, 13, 0, 0, 2]\nK_green_6[:, 2] = [2, 0, 0, 13, -3]\nK_green_6 = K_green_6 / 24\nK_green_7 = np.zeros((5, 5))", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "K_green_3", + "kind": 5, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "K_green_3 = np.zeros((5, 5))\nK_green_3[2, :] = [2, 0, 0, 13, -3]\nK_green_3[:, 2] = [-3, 13, 0, 0, 2]\nK_green_3 = K_green_3 / 24\nK_green_6 = np.zeros((5, 5))\nK_green_6[2, :] = [-3, 13, 0, 0, 2]\nK_green_6[:, 2] = [2, 0, 0, 13, -3]\nK_green_6 = K_green_6 / 24\nK_green_7 = np.zeros((5, 5))\nK_green_7[2, :] = [2, 0, 0, 13, -3]", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "K_green_3", + "kind": 5, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "K_green_3 = K_green_3 / 24\nK_green_6 = np.zeros((5, 5))\nK_green_6[2, :] = [-3, 13, 0, 0, 2]\nK_green_6[:, 2] = [2, 0, 0, 13, -3]\nK_green_6 = K_green_6 / 24\nK_green_7 = np.zeros((5, 5))\nK_green_7[2, :] = [2, 0, 0, 13, -3]\nK_green_7[:, 2] = [2, 0, 0, 13, -3]\nK_green_7 = K_green_7 / 24\nK_list_green = [K_identity, K_identity, K_green_2, K_green_3, K_identity, K_identity, K_green_6, K_green_7, K_green_2, K_green_3, K_identity, K_identity, K_green_6, K_green_7, K_identity, K_identity]", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "K_green_6", + "kind": 5, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "K_green_6 = np.zeros((5, 5))\nK_green_6[2, :] = [-3, 13, 0, 0, 2]\nK_green_6[:, 2] = [2, 0, 0, 13, -3]\nK_green_6 = K_green_6 / 24\nK_green_7 = np.zeros((5, 5))\nK_green_7[2, :] = [2, 0, 0, 13, -3]\nK_green_7[:, 2] = [2, 0, 0, 13, -3]\nK_green_7 = K_green_7 / 24\nK_list_green = [K_identity, K_identity, K_green_2, K_green_3, K_identity, K_identity, K_green_6, K_green_7, K_green_2, K_green_3, K_identity, K_identity, K_green_6, K_green_7, K_identity, K_identity]\nK_list_blue = [K_red_10, K_red_10, K_red_8, K_red_9, K_red_14, K_red_14, K_red_12, K_red_13, K_identity, K_identity, K_red_0, K_red_1, K_identity, K_identity, K_red_0, K_red_1]", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "K_green_6", + "kind": 5, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "K_green_6 = K_green_6 / 24\nK_green_7 = np.zeros((5, 5))\nK_green_7[2, :] = [2, 0, 0, 13, -3]\nK_green_7[:, 2] = [2, 0, 0, 13, -3]\nK_green_7 = K_green_7 / 24\nK_list_green = [K_identity, K_identity, K_green_2, K_green_3, K_identity, K_identity, K_green_6, K_green_7, K_green_2, K_green_3, K_identity, K_identity, K_green_6, K_green_7, K_identity, K_identity]\nK_list_blue = [K_red_10, K_red_10, K_red_8, K_red_9, K_red_14, K_red_14, K_red_12, K_red_13, K_identity, K_identity, K_red_0, K_red_1, K_identity, K_identity, K_red_0, K_red_1]\nker_bayer_red_blue = np.array([[1, 2, 1], [2, 4, 2], [1, 2, 1]]) / 4\nker_bayer_green = np.array([[0, 1, 0], [1, 4, 1], [0, 1, 0]]) / 4\n####", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "K_green_7", + "kind": 5, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "K_green_7 = np.zeros((5, 5))\nK_green_7[2, :] = [2, 0, 0, 13, -3]\nK_green_7[:, 2] = [2, 0, 0, 13, -3]\nK_green_7 = K_green_7 / 24\nK_list_green = [K_identity, K_identity, K_green_2, K_green_3, K_identity, K_identity, K_green_6, K_green_7, K_green_2, K_green_3, K_identity, K_identity, K_green_6, K_green_7, K_identity, K_identity]\nK_list_blue = [K_red_10, K_red_10, K_red_8, K_red_9, K_red_14, K_red_14, K_red_12, K_red_13, K_identity, K_identity, K_red_0, K_red_1, K_identity, K_identity, K_red_0, K_red_1]\nker_bayer_red_blue = np.array([[1, 2, 1], [2, 4, 2], [1, 2, 1]]) / 4\nker_bayer_green = np.array([[0, 1, 0], [1, 4, 1], [0, 1, 0]]) / 4\n####\n####", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "K_green_7", + "kind": 5, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "K_green_7 = K_green_7 / 24\nK_list_green = [K_identity, K_identity, K_green_2, K_green_3, K_identity, K_identity, K_green_6, K_green_7, K_green_2, K_green_3, K_identity, K_identity, K_green_6, K_green_7, K_identity, K_identity]\nK_list_blue = [K_red_10, K_red_10, K_red_8, K_red_9, K_red_14, K_red_14, K_red_12, K_red_13, K_identity, K_identity, K_red_0, K_red_1, K_identity, K_identity, K_red_0, K_red_1]\nker_bayer_red_blue = np.array([[1, 2, 1], [2, 4, 2], [1, 2, 1]]) / 4\nker_bayer_green = np.array([[0, 1, 0], [1, 4, 1], [0, 1, 0]]) / 4\n####\n####\n####\n#### #### #### #############\n#### ###### #### ##################", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "K_list_green", + "kind": 5, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "K_list_green = [K_identity, K_identity, K_green_2, K_green_3, K_identity, K_identity, K_green_6, K_green_7, K_green_2, K_green_3, K_identity, K_identity, K_green_6, K_green_7, K_identity, K_identity]\nK_list_blue = [K_red_10, K_red_10, K_red_8, K_red_9, K_red_14, K_red_14, K_red_12, K_red_13, K_identity, K_identity, K_red_0, K_red_1, K_identity, K_identity, K_red_0, K_red_1]\nker_bayer_red_blue = np.array([[1, 2, 1], [2, 4, 2], [1, 2, 1]]) / 4\nker_bayer_green = np.array([[0, 1, 0], [1, 4, 1], [0, 1, 0]]) / 4\n####\n####\n####\n#### #### #### #############\n#### ###### #### ##################\n#### ######## #### ####################", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "K_list_blue", + "kind": 5, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "K_list_blue = [K_red_10, K_red_10, K_red_8, K_red_9, K_red_14, K_red_14, K_red_12, K_red_13, K_identity, K_identity, K_red_0, K_red_1, K_identity, K_identity, K_red_0, K_red_1]\nker_bayer_red_blue = np.array([[1, 2, 1], [2, 4, 2], [1, 2, 1]]) / 4\nker_bayer_green = np.array([[0, 1, 0], [1, 4, 1], [0, 1, 0]]) / 4\n####\n####\n####\n#### #### #### #############\n#### ###### #### ##################\n#### ######## #### ####################\n#### ########## #### #### ########", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "ker_bayer_red_blue", + "kind": 5, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "ker_bayer_red_blue = np.array([[1, 2, 1], [2, 4, 2], [1, 2, 1]]) / 4\nker_bayer_green = np.array([[0, 1, 0], [1, 4, 1], [0, 1, 0]]) / 4\n####\n####\n####\n#### #### #### #############\n#### ###### #### ##################\n#### ######## #### ####################\n#### ########## #### #### ########\n#### ############ #### #### ####", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "ker_bayer_green", + "kind": 5, + "importPath": "src.methods.baseline.demo_reconstruction", + "description": "src.methods.baseline.demo_reconstruction", + "peekOfCode": "ker_bayer_green = np.array([[0, 1, 0], [1, 4, 1], [0, 1, 0]]) / 4\n####\n####\n####\n#### #### #### #############\n#### ###### #### ##################\n#### ######## #### ####################\n#### ########## #### #### ########\n#### ############ #### #### ####\n#### #### ######## #### #### ####", + "detail": "src.methods.baseline.demo_reconstruction", + "documentation": {} + }, + { + "label": "run_reconstruction", + "kind": 2, + "importPath": "src.methods.baseline.reconstruct", + "description": "src.methods.baseline.reconstruct", + "peekOfCode": "def run_reconstruction(y: np.ndarray, cfa: str) -> np.ndarray:\n \"\"\"Performs demosaicking on y.\n Args:\n y (np.ndarray): Mosaicked image to be reconstructed.\n cfa (str): Name of the CFA. Can be bayer or quad_bayer.\n Returns:\n np.ndarray: Demosaicked image.\n \"\"\"\n input_shape = (y.shape[0], y.shape[1], 3)\n op = CFA(cfa, input_shape)", + "detail": "src.methods.baseline.reconstruct", + "documentation": {} + }, + { + "label": "find_Knearest_neighbors", + "kind": 2, + "importPath": "src.methods.ELAMRANI_Mouna.functions", + "description": "src.methods.ELAMRANI_Mouna.functions", + "peekOfCode": "def find_Knearest_neighbors(z, chan, i, j, N, M):\n \"\"\"Finds all the neighbors of a pixel on a given channel\"\"\"\n return np.array([z[(i+di)%N, (j+dj)%M, chan] for di in range(-1, 2) for dj in range(-1, 2)])\ndef calculate_directional_gradients(neighbors):\n \"\"\"Calculates the directional derivative of a pixel\"\"\"\n P1, P2, P3, P4, P5, P6, P7, P8, P9 = neighbors\n Dx, Dy = (P4 - P6)/2, (P2 - P8)/2\n Dxd, Dyd = (P3 - P7)/(2*np.sqrt(2)), (P1 - P9)/(2*np.sqrt(2))\n return [Dx, Dy, Dxd, Dyd]\ndef calculate_adaptive_weights(z, neigh, dir_deriv,chan,i,j,N,M):", + "detail": "src.methods.ELAMRANI_Mouna.functions", + "documentation": {} + }, + { + "label": "calculate_directional_gradients", + "kind": 2, + "importPath": "src.methods.ELAMRANI_Mouna.functions", + "description": "src.methods.ELAMRANI_Mouna.functions", + "peekOfCode": "def calculate_directional_gradients(neighbors):\n \"\"\"Calculates the directional derivative of a pixel\"\"\"\n P1, P2, P3, P4, P5, P6, P7, P8, P9 = neighbors\n Dx, Dy = (P4 - P6)/2, (P2 - P8)/2\n Dxd, Dyd = (P3 - P7)/(2*np.sqrt(2)), (P1 - P9)/(2*np.sqrt(2))\n return [Dx, Dy, Dxd, Dyd]\ndef calculate_adaptive_weights(z, neigh, dir_deriv,chan,i,j,N,M):\n \"\"\"Finds all the neighbors of a pixel on a given channel\"\"\"\n [Dx,Dy,Dxd,Dyd] = dir_deriv\n [P1,P2,P3,P4,P5,P6,P7,P8,P9] = neigh", + "detail": "src.methods.ELAMRANI_Mouna.functions", + "documentation": {} + }, + { + "label": "calculate_adaptive_weights", + "kind": 2, + "importPath": "src.methods.ELAMRANI_Mouna.functions", + "description": "src.methods.ELAMRANI_Mouna.functions", + "peekOfCode": "def calculate_adaptive_weights(z, neigh, dir_deriv,chan,i,j,N,M):\n \"\"\"Finds all the neighbors of a pixel on a given channel\"\"\"\n [Dx,Dy,Dxd,Dyd] = dir_deriv\n [P1,P2,P3,P4,P5,P6,P7,P8,P9] = neigh\n E = []\n c = 1\n for k in range (-1,2):\n for k in range (-1,2):\n n = find_Knearest_neighbors(z,chan,i+k,j+k,N,M)\n dd = calculate_directional_gradients(n)", + "detail": "src.methods.ELAMRANI_Mouna.functions", + "documentation": {} + }, + { + "label": "interpolate_pixel", + "kind": 2, + "importPath": "src.methods.ELAMRANI_Mouna.functions", + "description": "src.methods.ELAMRANI_Mouna.functions", + "peekOfCode": "def interpolate_pixel(neigh,weights):\n \"\"\"interpolates pixels from a grid where one of two pixels is missing regularly spaced\"\"\"\n [P1,P2,P3,P4,P5,P6,P7,P8,P9] = neigh\n [E1,E2,E3,E4,E6,E7,E8,E9] = weights\n num5 = E2*P2 + E4*P4 + E6*P6 + E8*P8\n den5 = E2 + E4 + E6 + E8\n I5 = num5/den5\n return I5\ndef interpolate_RedBlue(neighbors, neighbors_G, weights):\n \"\"\"Interpolates the central missing pixel from the red or blue channel from a Bayer pattern.\"\"\"", + "detail": "src.methods.ELAMRANI_Mouna.functions", + "documentation": {} + }, + { + "label": "interpolate_RedBlue", + "kind": 2, + "importPath": "src.methods.ELAMRANI_Mouna.functions", + "description": "src.methods.ELAMRANI_Mouna.functions", + "peekOfCode": "def interpolate_RedBlue(neighbors, neighbors_G, weights):\n \"\"\"Interpolates the central missing pixel from the red or blue channel from a Bayer pattern.\"\"\"\n [P1,P2,P3,P4,P5,P6,P7,P8,P9] = neighbors\n [G1,G2,G3,G4,G5,G6,G7,G8,G9] = neighbors_G\n [E1,E2,E3,E4,E6,E7,E8,E9] = weights\n num5 = ((E1*P1)/G1) + ((E3*P3)/G3) + ((E7*P7)/G7) + ((E9*P9)/G9)\n den5 = E1 + E3 + E7 + E9\n I5 = G5 * num5/den5\n return I5", + "detail": "src.methods.ELAMRANI_Mouna.functions", + "documentation": {} + }, + { + "label": "run_reconstruction", + "kind": 2, + "importPath": "src.methods.ELAMRANI_Mouna.reconstruct", + "description": "src.methods.ELAMRANI_Mouna.reconstruct", + "peekOfCode": "def run_reconstruction(y: np.ndarray, cfa: str) -> np.ndarray:\n \"\"\"Performs demosaicking on y.\n Args:\n y (np.ndarray): Mosaicked image to be reconstructed.\n cfa (str): Name of the CFA. Can be bayer or quad_bayer.\n Returns:\n np.ndarray: Demosaicked image.\n \"\"\"\n # Define constants and operators\n cfa_name = 'bayer' # bayer or quad_bayer", + "detail": "src.methods.ELAMRANI_Mouna.reconstruct", + "documentation": {} + }, + { + "label": "check_path", + "kind": 2, + "importPath": "src.checks", + "description": "src.checks", + "peekOfCode": "def check_path(file_path: str) -> None:\n \"\"\"Checks if a file exists at file_path and is a png image.\n Args:\n file_path (str): Path to check\n Raises:\n Exception: Exception if the path is invalid.\n \"\"\"\n if not exists(file_path):\n raise Exception('File does not exist.')\ndef check_png(file_path: str) -> None:", + "detail": "src.checks", + "documentation": {} + }, + { + "label": "check_png", + "kind": 2, + "importPath": "src.checks", + "description": "src.checks", + "peekOfCode": "def check_png(file_path: str) -> None:\n \"\"\"Checks if the file is a png image.\n Args:\n file_path (str): Path to check.\n \"\"\"\n if not file_path.endswith('.png'):\n raise Exception(f'Path must end with \".png\". Got {file_path[-4:]}.')\ndef check_rgb(img: np.ndarray) -> None:\n \"\"\"Checks if image is a 3 dimensional array with 3 channels.\n Args:", + "detail": "src.checks", + "documentation": {} + }, + { + "label": "check_rgb", + "kind": 2, + "importPath": "src.checks", + "description": "src.checks", + "peekOfCode": "def check_rgb(img: np.ndarray) -> None:\n \"\"\"Checks if image is a 3 dimensional array with 3 channels.\n Args:\n img (np.ndarray): Image to check.\n Raises:\n Exception: Exception if image is not a 3 dimensional array with 3 channels.\n \"\"\"\n if not (len(img.shape) == 3 and img.shape[2] == 3):\n raise Exception(f'The images must be 3 dimensional (RGB) arrays. Got an array of shape {img.shape}.')\ndef check_shape(img1: np.ndarray, img2: np.ndarray) -> None:", + "detail": "src.checks", + "documentation": {} + }, + { + "label": "check_shape", + "kind": 2, + "importPath": "src.checks", + "description": "src.checks", + "peekOfCode": "def check_shape(img1: np.ndarray, img2: np.ndarray) -> None:\n \"\"\"Checks if img1 and img2 have the same shape.\n Args:\n img1 (np.ndarray): First image.\n img2 (np.ndarray): Second image.\n Raises:\n Exception: Exception if img1 and img2 do not have the same shape.\n \"\"\"\n if img1.shape != img2.shape:\n raise Exception(f'The images must have the same shape. Got {img1.shape} and {img2.shape}.')", + "detail": "src.checks", + "documentation": {} + }, + { + "label": "check_data_range", + "kind": 2, + "importPath": "src.checks", + "description": "src.checks", + "peekOfCode": "def check_data_range(img: np.ndarray) -> None:\n \"\"\"Checks if the values of img are in the interval [0, 1].\n Args:\n img (np.ndarray): Image to check.\n Raises:\n Exception: Exception if img's values are not in [0, 1].\n \"\"\"\n if np.max(img) > 1 or np.min(img) < 0:\n raise Exception(f'Pixel\\'s values must be in range [0, 1]. Got range [{np.min(img)}, {np.max(img)}].')\ndef check_cfa(cfa: str) -> None:", + "detail": "src.checks", + "documentation": {} + }, + { + "label": "check_cfa", + "kind": 2, + "importPath": "src.checks", + "description": "src.checks", + "peekOfCode": "def check_cfa(cfa: str) -> None:\n \"\"\"Checks if the CFA's name is correct.\n Args:\n cfa (str): CFA name.\n Raises:\n Exception: Exception if the name of the CFA is not correct.\n \"\"\"\n if cfa not in ['bayer', 'quad_bayer']:\n raise Exception(f'Unknown CFA name. Got {cfa} but expected either bayer or quad_bayer.')\n####", + "detail": "src.checks", + "documentation": {} + }, + { + "label": "CFA", + "kind": 6, + "importPath": "src.forward_model", + "description": "src.forward_model", + "peekOfCode": "class CFA():\n def __init__(self, cfa: str, input_shape: tuple) -> None:\n \"\"\"Constructor of the forward operator's class.\n Args:\n cfa (str): Name of the pattern. Either bayer or quad_bayer.\n input_shape (tuple): Shape of the input images of the operator.\n \"\"\"\n check_cfa(cfa)\n self.cfa = cfa\n self.input_shape = input_shape", + "detail": "src.forward_model", + "documentation": {} + }, + { + "label": "get_bayer_mask", + "kind": 2, + "importPath": "src.forward_model", + "description": "src.forward_model", + "peekOfCode": "def get_bayer_mask(input_shape: tuple) -> np.ndarray:\n \"\"\"Return the mask of the Bayer CFA.\n Args:\n input_shape (tuple): Shape of the mask.\n Returns:\n np.ndarray: Mask.\n \"\"\"\n res = np.kron(np.ones((input_shape[0], input_shape[1], 1)), [0, 1, 0])\n res[::2, 1::2] = [1, 0, 0]\n res[1::2, ::2] = [0, 0, 1]", + "detail": "src.forward_model", + "documentation": {} + }, + { + "label": "get_quad_bayer_mask", + "kind": 2, + "importPath": "src.forward_model", + "description": "src.forward_model", + "peekOfCode": "def get_quad_bayer_mask(input_shape: tuple) -> np.ndarray:\n \"\"\"Return the mask of the quad_bayer CFA.\n Args:\n input_shape (tuple): Shape of the mask.\n Returns:\n np.ndarray: Mask.\n \"\"\"\n res = np.kron(np.ones((input_shape[0], input_shape[1], 1)), [0, 1, 0])\n res[::4, 2::4] = [1, 0, 0]\n res[::4, 3::4] = [1, 0, 0]", + "detail": "src.forward_model", + "documentation": {} + }, + { + "label": "normalise_image", + "kind": 2, + "importPath": "src.utils", + "description": "src.utils", + "peekOfCode": "def normalise_image(img: np.ndarray) -> np.ndarray:\n \"\"\"Normalise the values of img in the interval [0, 1].\n Args:\n img (np.ndarray): Image to normalise.\n Returns:\n np.ndarray: Normalised image.\n \"\"\"\n return (img - np.min(img)) / np.ptp(img)\ndef load_image(file_path: str) -> np.ndarray:\n \"\"\"Loads the image located in file_path.", + "detail": "src.utils", + "documentation": {} + }, + { + "label": "load_image", + "kind": 2, + "importPath": "src.utils", + "description": "src.utils", + "peekOfCode": "def load_image(file_path: str) -> np.ndarray:\n \"\"\"Loads the image located in file_path.\n Args:\n file_path (str): Path to the file containing the image. Must end by '.png'.\n Returns:\n np.ndarray: Loaded image.\n \"\"\"\n check_path(file_path)\n check_png(file_path)\n return normalise_image(imread(file_path))", + "detail": "src.utils", + "documentation": {} + }, + { + "label": "save_image", + "kind": 2, + "importPath": "src.utils", + "description": "src.utils", + "peekOfCode": "def save_image(file_path: str, img: np.ndarray) -> None:\n \"\"\"Saves the image located in file_path.\n Args:\n file_path (str): Path to the file in which the image will be saved. Must end by '.png'.\n img (np.ndarray): Image to save.\n \"\"\"\n check_path(file_path.split('/')[-2])\n check_png(file_path)\n imsave(file_path, (img * 255).astype(np.uint8))\ndef psnr(img1: np.ndarray, img2: np.ndarray) -> float:", + "detail": "src.utils", + "documentation": {} + }, + { + "label": "psnr", + "kind": 2, + "importPath": "src.utils", + "description": "src.utils", + "peekOfCode": "def psnr(img1: np.ndarray, img2: np.ndarray) -> float:\n \"\"\"Computes the PSNR between img1 and img2 after some sanity checks.\n img1 and img2 must:\n - have the same shape;\n - be in range [0, 1].\n Args:\n img1 (np.ndarray): First image.\n img2 (np.ndarray): Second image.\n Returns:\n float: PSNR between img1 and img2.", + "detail": "src.utils", + "documentation": {} + }, + { + "label": "ssim", + "kind": 2, + "importPath": "src.utils", + "description": "src.utils", + "peekOfCode": "def ssim(img1: np.ndarray, img2: np.ndarray) -> float:\n \"\"\"Computes the SSIM between img1 and img2 after some sanity checks.\n img1 and img2 must:\n - have the same shape;\n - be in range [0, 1];\n - be 3 dimensional array with 3 channels.\n Args:\n img1 (np.ndarray): First image.\n img2 (np.ndarray): Second image.\n Returns:", + "detail": "src.utils", + "documentation": {} + } +] \ No newline at end of file diff --git a/src/methods/ELAMRANI_Mouna/functions.py b/src/methods/ELAMRANI_Mouna/functions.py new file mode 100644 index 0000000000000000000000000000000000000000..d7ad25de27a3f8f169382f0eb02f481d290b9c1d --- /dev/null +++ b/src/methods/ELAMRANI_Mouna/functions.py @@ -0,0 +1,55 @@ +import numpy as np + +def find_Knearest_neighbors(z, chan, i, j, N, M): + """Finds all the neighbors of a pixel on a given channel""" + return np.array([z[(i+di)%N, (j+dj)%M, chan] for di in range(-1, 2) for dj in range(-1, 2)]) + +def calculate_directional_gradients(neighbors): + """Calculates the directional derivative of a pixel""" + P1, P2, P3, P4, P5, P6, P7, P8, P9 = neighbors + Dx, Dy = (P4 - P6)/2, (P2 - P8)/2 + Dxd, Dyd = (P3 - P7)/(2*np.sqrt(2)), (P1 - P9)/(2*np.sqrt(2)) + return [Dx, Dy, Dxd, Dyd] + +def calculate_adaptive_weights(z, neigh, dir_deriv,chan,i,j,N,M): + """Finds all the neighbors of a pixel on a given channel""" + [Dx,Dy,Dxd,Dyd] = dir_deriv + [P1,P2,P3,P4,P5,P6,P7,P8,P9] = neigh + E = [] + c = 1 + for k in range (-1,2): + for k in range (-1,2): + + n = find_Knearest_neighbors(z,chan,i+k,j+k,N,M) + dd = calculate_directional_gradients(n) + if c == 1 or c == 9: + E.append(1/np.sqrt(1 + Dyd**2 + dd[3]**2)) + elif c == 2 or c == 8: + E.append(1/np.sqrt(1 + Dy**2 + dd[1]**2)) + elif c == 3 or c == 7: + E.append(1/np.sqrt(1 + Dxd**2 + dd[2]**2)) + elif c == 4 or c == 6: + E.append(1/np.sqrt(1 + Dx**2 + dd[0]**2)) + c += 1 + return E + +def interpolate_pixel(neigh,weights): + + """interpolates pixels from a grid where one of two pixels is missing regularly spaced""" + [P1,P2,P3,P4,P5,P6,P7,P8,P9] = neigh + [E1,E2,E3,E4,E6,E7,E8,E9] = weights + num5 = E2*P2 + E4*P4 + E6*P6 + E8*P8 + den5 = E2 + E4 + E6 + E8 + I5 = num5/den5 + return I5 + +def interpolate_RedBlue(neighbors, neighbors_G, weights): + """Interpolates the central missing pixel from the red or blue channel from a Bayer pattern.""" + [P1,P2,P3,P4,P5,P6,P7,P8,P9] = neighbors + [G1,G2,G3,G4,G5,G6,G7,G8,G9] = neighbors_G + [E1,E2,E3,E4,E6,E7,E8,E9] = weights + num5 = ((E1*P1)/G1) + ((E3*P3)/G3) + ((E7*P7)/G7) + ((E9*P9)/G9) + den5 = E1 + E3 + E7 + E9 + I5 = G5 * num5/den5 + + return I5 diff --git a/src/methods/ELAMRANI_Mouna/reconstruct.py b/src/methods/ELAMRANI_Mouna/reconstruct.py new file mode 100644 index 0000000000000000000000000000000000000000..914020f974e2bd48ac6ac6b7647073858aafce3d --- /dev/null +++ b/src/methods/ELAMRANI_Mouna/reconstruct.py @@ -0,0 +1,54 @@ +import numpy as np +from src.forward_model import CFA +from src.methods.ELAMRANI_Mouna.functions import * + + +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. + """ + + # Define constants and operators + cfa_name = 'bayer' # bayer or quad_bayer + input_shape = (y.shape[0], y.shape[1], 3) + op = CFA(cfa_name, input_shape) + + img_res = op.adjoint(y) + N = img_res[:,:,0].shape[0] + M = img_res[:,:,0].shape[1] + + def interpolate_channel(img_res, channel, first_pass, N, M): + for i in range(N): + for j in range(M): + if first_pass and ((channel == 0 and i % 2 == 1 and j % 2 == 0) or + (channel == 2 and i % 2 == 0 and j % 2 == 1)): + neighbors = find_Knearest_neighbors(img_res, channel, i, j, N, M) + neighbors_G = find_Knearest_neighbors(img_res, 1, i, j, N, M) + dir_deriv = calculate_directional_gradients(neighbors_G) + weights = calculate_adaptive_weights(img_res, neighbors_G, dir_deriv, 1, i, j, N, M) + img_res[i, j, channel] = interpolate_RedBlue(neighbors, neighbors_G, weights) + elif not first_pass and img_res[i, j, channel] == 0: + neighbors = find_Knearest_neighbors(img_res, channel, i, j, N, M) + dir_deriv = calculate_directional_gradients(neighbors) + weights = calculate_adaptive_weights(img_res, neighbors, dir_deriv, channel, i, j, N, M) + img_res[i, j, channel] = interpolate_pixel(neighbors, weights) + return img_res + +# Interpolation pour chaque canal + img_res = interpolate_channel(img_res, 1, False, N, M) # Interpolation du canal vert + img_res = interpolate_channel(img_res, 0, True, N, M) # Première interpolation du canal rouge + img_res = interpolate_channel(img_res, 0, False, N, M) # Seconde interpolation du canal rouge + img_res = interpolate_channel(img_res, 2, True, N, M) # Première interpolation du canal bleu + img_res = interpolate_channel(img_res, 2, False, N, M) # Seconde interpolation du canal bleu + + img_res[img_res > 1] = 1 + img_res[img_res < 0] = 0 + + return img_res + diff --git a/src/methods/template/reconstruct.py b/src/methods/template/reconstruct.py deleted file mode 100755 index a97bd3f6e3c68df763b36c46b2727461af078bd2..0000000000000000000000000000000000000000 --- a/src/methods/template/reconstruct.py +++ /dev/null @@ -1,53 +0,0 @@ -"""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). -""" - - -import numpy as np - -from src.forward_model import CFA - - -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. - """ - # Performing the reconstruction. - # TODO - input_shape = (y.shape[0], y.shape[1], 3) - op = CFA(cfa, input_shape) - - return np.zeros(op.input_shape) - - -#### -#### -#### - -#### #### #### ############# -#### ###### #### ################## -#### ######## #### #################### -#### ########## #### #### ######## -#### ############ #### #### #### -#### #### ######## #### #### #### -#### #### ######## #### #### #### -#### #### ######## #### #### #### -#### #### ## ###### #### #### ###### -#### #### #### ## #### #### ############ -#### #### ###### #### #### ########## -#### #### ########## #### #### ######## -#### #### ######## #### #### -#### #### ############ #### -#### #### ########## #### -#### #### ######## #### -#### #### ###### #### - -# 2023 -# Authors: Mauro Dalla Mura and Matthieu Muller