Skip to content
Snippets Groups Projects
Commit 95243fb3 authored by Antoine Vouillon's avatar Antoine Vouillon
Browse files

Commit of the project

parent 25942cba
No related branches found
No related tags found
No related merge requests found
import numpy as np
def find_neighbors (z,chan,i,j,N,M):
"""Finds all the neighbors of a pixel on a given channel
Args:
z: image.
chan: chosen chanel.
i: line of the pixel
j: column of the pixel
N: number of lines
M: number of columns
Returns:
np.ndarray: Neighbors of the pixel in a list (including the pixel itself)
"""
P1 = z[(i-1)%N,(j-1)%M,chan]
P2 = z[(i-1)%N,j%M,chan]
P3 = z[(i-1)%N,(j+1)%M,chan]
P4 = z[i%N,(j-1)%M,chan]
P5 = z[i%N,j%M,chan]
P6 = z[i%N,(j+1)%M,chan]
P7 = z[(i+1)%N,(j-1)%M,chan]
P8 = z[(i+1)%N,j%M,chan]
P9 = z[(i+1)%N,(j+1)%M,chan]
return np.array([P1,P2,P3,P4,P5,P6,P7,P8,P9])
def find_dir_deriv(neighbors):
"""Calculates the directional derivative of a pixel.
Args:
neighbors: list of the neighbors of the pixel
Returns:
np.ndarray: directional derivatives in this order: Dx, Dy, Ddx, Ddy
"""
[P1,P2,P3,P4,P5,P6,P7,P8,P9] = neighbors
Dx = (P4 - P6)/2
Dy = (P2 - P8)/2
Dxd = (P3 - P7)/(2*np.sqrt(2))
Dyd = (P1 - P9)/(2*np.sqrt(2))
return [Dx,Dy,Dxd,Dyd]
def find_weights(z, neigh, dir_deriv,chan,i,j,N,M):
"""Finds all the neighbors of a pixel on a given channel
Args:
z: image.
dir_deriv: directional derivatives
chan: chosen chanel.
i: line of the pixel
j: column of the pixel
N: number of lines
M: number of columns
Returns:
np.ndarray: Weights from E1 to E9
"""
[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_neighbors(z,chan,i+k,j+k,N,M)
dd = find_dir_deriv(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(neigh,weights):
"""interpolates pixels from a grid where one of two pixels is missing regularly spaced
Args:
neigh: neighbors of the pixel.
weights: weight of the neighbors.
Returns:
np.ndarray: The value of the interpolated pixel
"""
[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_RB(neigh, neigh_G, weights):
"""interpolates the central missing pixel from the red or blue channel from a bayer patern
Args:
neigh: neighbors of the pixel in the red or blue channel.
neigh_G: neighbors of the pixel in the green channel.
weights: weight of the neighbors.
Returns:
np.ndarray: The value of the interpolated pixel in the red or blue channel
"""
[P1,P2,P3,P4,P5,P6,P7,P8,P9] = neigh
[G1,G2,G3,G4,G5,G6,G7,G8,G9] = neigh_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
def correction_G(neigh_G ,neigh_R ,neigh_B, weights):
"""corrects the value of the green pixel in the third phase of the kimmel algorythme
Args:
neigh_G: neighbors of the pixel in the green channel.
neigh_R: neighbors of the pixel in the red channel.
neigh_B: neighbors of the pixel in the blue channel.
weights: weight of the neighbors.
Returns:
np.ndarray: The value of the corrected pixel in the green channel
"""
[G1,G2,G3,G4,G5,G6,G7,G8,G9] = neigh_G
[R1,R2,R3,R4,R5,R6,R7,R8,R9] = neigh_R
[B1,B2,B3,B4,B5,B6,B7,B8,B9] = neigh_B
[E1,E2,E3,E4,E6,E7,E8,E9] = weights
num_Gb5 = ((E2*G2)/B2) + ((E4*G4)/B4) + ((E6*G6)/B6) + ((E8*G8)/B8)
num_Gr5 = ((E2*G2)/R2) + ((E4*G4)/R4) + ((E6*G6)/R6) + ((E8*G8)/R8)
den5 = E2 + E4 + E6 + E8
Gb5 = B5 * num_Gb5/den5
Gr5 = R5 * num_Gr5/den5
G5 = (Gb5 + Gr5)/2
return Gr5
def correction_R(neigh_G, neigh_R, weights):
"""corrects the value of the red pixel in the third phase of the kimmel algorythme
Args:
neigh_G: neighbors of the pixel in the green channel.
neigh_R: neighbors of the pixel in the red channel.
weights: weight of the neighbors.
Returns:
np.ndarray: The value of the corrected pixel in the red channel
"""
[G1,G2,G3,G4,G5,G6,G7,G8,G9] = neigh_G
[R1,R2,R3,R4,R5,R6,R7,R8,R9] = neigh_R
[E1,E2,E3,E4,E6,E7,E8,E9] = weights
num_R5 = ((E1*R1)/G1) + ((E2*R2)/G2) + ((E3*R3)/G3) + ((E4*R4)/G4) + ((E6*R6)/G6) + ((E7*R7)/G7) + ((E8*R8)/G8) + ((E9*R9)/G9)
den5 = sum(weights)
R5 = G5 * num_R5/den5
return R5
def correction_B(neigh_G ,neigh_B, weights):
"""corrects the value of the blue pixel in the third phase of the kimmel algorythme
Args:
neigh_G: neighbors of the pixel in the green channel.
neigh_B: neighbors of the pixel in the blue channel.
weights: weight of the neighbors.
Returns:
np.ndarray: The value of the corrected pixel in the blue channel
"""
[G1,G2,G3,G4,G5,G6,G7,G8,G9] = neigh_G
[B1,B2,B3,B4,B5,B6,B7,B8,B9] = neigh_B
[E1,E2,E3,E4,E6,E7,E8,E9] = weights
num_B5 = ((E1*B1)/G1) + ((E2*B2)/G2) + ((E3*B3)/G3) + ((E4*B4)/G4) + ((E6*B6)/G6) + ((E7*B7)/G7) + ((E8*B8)/G8) + ((E9*B9)/G9)
den5 = sum(weights)
B5 = G5 * num_B5/den5
return B5
File added
......@@ -7,7 +7,9 @@ Students can call their functions (declared in others files of src/methods/your_
import numpy as np
from src.forward_model import CFA
from src.methods.antoine_vouillon.functions import *
#!!!!!!!! It is normal that the reconstructions lasts several minutes (3min on my computer)
def run_reconstruction(y: np.ndarray, cfa: str) -> np.ndarray:
"""Performs demosaicking on y.
......@@ -19,12 +21,93 @@ def run_reconstruction(y: np.ndarray, cfa: str) -> np.ndarray:
Returns:
np.ndarray: Demosaicked image.
"""
# Performing the reconstruction.
# TODO
# Define constants and operators
cfa_name = 'bayer' # bayer or quad_bayer
input_shape = (y.shape[0], y.shape[1], 3)
op = CFA(cfa, input_shape)
op = CFA(cfa_name, input_shape)
img_res = op.adjoint(y)
N = img_res[:,:,0].shape[0]
M = img_res[:,:,0].shape[1]
#interpolating green channel
for i in range (N):
for j in range (M):
if img_res[i,j,1] ==0:
neighbors = find_neighbors(img_res,1,i,j,N,M)
dir_deriv = find_dir_deriv(neighbors)
weights = find_weights(img_res, neighbors, dir_deriv,1,i,j,N,M)
img_res[i,j,1] = interpolate(neighbors,weights)
img_res[img_res>1] = 1
img_res[img_res<0] = 0
#first intepolation of red channel
for i in range (1,N,2):
for j in range (0,M,2):
neighbors = find_neighbors(img_res,0,i,j,N,M)
neighbors_G = find_neighbors(img_res,1,i,j,N,M)
dir_deriv = find_dir_deriv(neighbors_G)
weights = find_weights(img_res,neighbors_G, dir_deriv,1,i,j,N,M)
img_res[i,j,0] = interpolate_RB(neighbors, neighbors_G, weights)
# second interpolation of red channel
for i in range (N):
for j in range (M):
if img_res[i,j,0] ==0:
neighbors = find_neighbors(img_res,0,i,j,N,M)
dir_deriv = find_dir_deriv(neighbors)
weights = find_weights(img_res,neighbors, dir_deriv,0,i,j,N,M)
img_res[i,j,0] = interpolate(neighbors,weights)
img_res[img_res>1] = 1
img_res[img_res<0] = 0
#first interpolation of blue channel
for i in range (0,N,2):
for j in range (1,M,2):
neighbors = find_neighbors(img_res,2,i,j,N,M)
neighbors_G = find_neighbors(img_res,1,i,j,N,M)
dir_deriv = find_dir_deriv(neighbors_G)
weights = find_weights(img_res,neighbors_G, dir_deriv,1,i,j,N,M)
img_res[i,j,2] = interpolate_RB(neighbors, neighbors_G, weights)
#second interpolation of blue channel
for i in range (N):
for j in range (M):
if img_res[i,j,2] ==0:
neighbors = find_neighbors(img_res,2,i,j,N,M)
dir_deriv = find_dir_deriv(neighbors)
weights = find_weights(img_res, neighbors, dir_deriv,2,i,j,N,M)
img_res[i,j,2] = interpolate(neighbors,weights)
img_res[img_res>1] = 1
img_res[img_res<0] = 0
return np.zeros(op.input_shape)
return img_res
####
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment