import numpy as np | |
import math | |
import time | |
import utility | |
from scipy import signal | |
# ============================================================= | |
# function: dbayer_mhc | |
# demosaicing using Malvar-He-Cutler algorithm | |
# http://www.ipol.im/pub/art/2011/g_mhcd/ | |
# ============================================================= | |
def debayer_mhc(raw, bayer_pattern="rggb", clip_range=[0, 65535], timeshow=False): | |
# convert to float32 in case it was not | |
raw = np.float32(raw) | |
# dimensions | |
width, height = utility.helpers(raw).get_width_height() | |
# number of pixels to pad | |
no_of_pixel_pad = 2 | |
raw = np.pad(raw, \ | |
(no_of_pixel_pad, no_of_pixel_pad),\ | |
'reflect') # reflect would not repeat the border value | |
# allocate space for the R, G, B planes | |
R = np.empty( (height + no_of_pixel_pad * 2, width + no_of_pixel_pad * 2), dtype = np.float32 ) | |
G = np.empty( (height + no_of_pixel_pad * 2, width + no_of_pixel_pad * 2), dtype = np.float32 ) | |
B = np.empty( (height + no_of_pixel_pad * 2, width + no_of_pixel_pad * 2), dtype = np.float32 ) | |
# create a RGB output | |
demosaic_out = np.empty( (height, width, 3), dtype = np.float32 ) | |
# fill up the directly available values according to the Bayer pattern | |
if (bayer_pattern == "rggb"): | |
G[::2, 1::2] = raw[::2, 1::2] | |
G[1::2, ::2] = raw[1::2, ::2] | |
R[::2, ::2] = raw[::2, ::2] | |
B[1::2, 1::2] = raw[1::2, 1::2] | |
# Green channel | |
for i in range(no_of_pixel_pad, height + no_of_pixel_pad): | |
# to display progress | |
t0 = time.process_time() | |
for j in range(no_of_pixel_pad, width + no_of_pixel_pad): | |
# G at Red location | |
if (((i % 2) == 0) and ((j % 2) == 0)): | |
G[i, j] = 0.125 * np.sum([-1. * R[i-2, j], \ | |
2. * G[i-1, j], \ | |
-1. * R[i, j-2], 2. * G[i, j-1], 4. * R[i,j], 2. * G[i, j+1], -1. * R[i, j+2],\ | |
2. * G[i+1, j], \ | |
-1. * R[i+2, j]]) | |
# G at Blue location | |
elif (((i % 2) != 0) and ((j % 2) != 0)): | |
G[i, j] = 0.125 * np.sum([-1. * B[i-2, j], \ | |
2. * G[i-1, j], \ | |
-1. * B[i, j-2], 2. * G[i, j-1], 4. * B[i,j], 2. * G[i, j+1], -1. * B[i, j+2], \ | |
2. * G[i+1, j],\ | |
-1. * B[i+2, j]]) | |
if (timeshow): | |
elapsed_time = time.process_time() - t0 | |
print("Green: row index: " + str(i-1) + " of " + str(height) + \ | |
" | elapsed time: " + "{:.3f}".format(elapsed_time) + " seconds") | |
# Red and Blue channel | |
for i in range(no_of_pixel_pad, height + no_of_pixel_pad): | |
# to display progress | |
t0 = time.process_time() | |
for j in range(no_of_pixel_pad, width + no_of_pixel_pad): | |
# Green locations in Red rows | |
if (((i % 2) == 0) and ((j % 2) != 0)): | |
# R at Green locations in Red rows | |
R[i, j] = 0.125 * np.sum([.5 * G[i-2, j],\ | |
-1. * G[i-1, j-1], -1. * G[i-1, j+1], \ | |
-1. * G[i, j-2], 4. * R[i, j-1], 5. * G[i,j], 4. * R[i, j+1], -1. * G[i, j+2], \ | |
-1. * G[i+1, j-1], -1. * G[i+1, j+1], \ | |
.5 * G[i+2, j]]) | |
# B at Green locations in Red rows | |
B[i, j] = 0.125 * np.sum([-1. * G[i-2, j], \ | |
-1. * G[i-1, j-1], 4. * B[i-1, j], -1. * G[i-1, j+1], \ | |
.5 * G[i, j-2], 5. * G[i,j], .5 * G[i, j+2], \ | |
-1. * G[i+1, j-1], 4. * B[i+1,j], -1. * G[i+1, j+1], \ | |
-1. * G[i+2, j]]) | |
# Green locations in Blue rows | |
elif (((i % 2) != 0) and ((j % 2) == 0)): | |
# R at Green locations in Blue rows | |
R[i, j] = 0.125 * np.sum([-1. * G[i-2, j], \ | |
-1. * G[i-1, j-1], 4. * R[i-1, j], -1. * G[i-1, j+1], \ | |
.5 * G[i, j-2], 5. * G[i,j], .5 * G[i, j+2], \ | |
-1. * G[i+1, j-1], 4. * R[i+1, j], -1. * G[i+1, j+1], \ | |
-1. * G[i+2, j]]) | |
# B at Green locations in Blue rows | |
B[i, j] = 0.125 * np.sum([.5 * G[i-2, j], \ | |
-1. * G [i-1, j-1], -1. * G[i-1, j+1], \ | |
-1. * G[i, j-2], 4. * B[i, j-1], 5. * G[i,j], 4. * B[i, j+1], -1. * G[i, j+2], \ | |
-1. * G[i+1, j-1], -1. * G[i+1, j+1], \ | |
.5 * G[i+2, j]]) | |
# R at Blue locations | |
elif (((i % 2) != 0) and ((j % 2) != 0)): | |
R[i, j] = 0.125 * np.sum([-1.5 * B[i-2, j], \ | |
2. * R[i-1, j-1], 2. * R[i-1, j+1], \ | |
-1.5 * B[i, j-2], 6. * B[i,j], -1.5 * B[i, j+2], \ | |
2. * R[i+1, j-1], 2. * R[i+1, j+1], \ | |
-1.5 * B[i+2, j]]) | |
# B at Red locations | |
elif (((i % 2) == 0) and ((j % 2) == 0)): | |
B[i, j] = 0.125 * np.sum([-1.5 * R[i-2, j], \ | |
2. * B[i-1, j-1], 2. * B[i-1, j+1], \ | |
-1.5 * R[i, j-2], 6. * R[i,j], -1.5 * R[i, j+2], \ | |
2. * B[i+1, j-1], 2. * B[i+1, j+1], \ | |
-1.5 * R[i+2, j]]) | |
if (timeshow): | |
elapsed_time = time.process_time() - t0 | |
print("Red/Blue: row index: " + str(i-1) + " of " + str(height) + \ | |
" | elapsed time: " + "{:.3f}".format(elapsed_time) + " seconds") | |
elif (bayer_pattern == "gbrg"): | |
G[::2, ::2] = raw[::2, ::2] | |
G[1::2, 1::2] = raw[1::2, 1::2] | |
R[1::2, ::2] = raw[1::2, ::2] | |
B[::2, 1::2] = raw[::2, 1::2] | |
# Green channel | |
for i in range(no_of_pixel_pad, height + no_of_pixel_pad): | |
# to display progress | |
t0 = time.process_time() | |
for j in range(no_of_pixel_pad, width + no_of_pixel_pad): | |
# G at Red location | |
if (((i % 2) != 0) and ((j % 2) == 0)): | |
G[i, j] = 0.125 * np.sum([-1. * R[i-2, j], \ | |
2. * G[i-1, j], \ | |
-1. * R[i, j-2], 2. * G[i, j-1], 4. * R[i,j], 2. * G[i, j+1], -1. * R[i, j+2],\ | |
2. * G[i+1, j], \ | |
-1. * R[i+2, j]]) | |
# G at Blue location | |
elif (((i % 2) == 0) and ((j % 2) != 0)): | |
G[i, j] = 0.125 * np.sum([-1. * B[i-2, j], \ | |
2. * G[i-1, j], \ | |
-1. * B[i, j-2], 2. * G[i, j-1], 4. * B[i,j], 2. * G[i, j+1], -1. * B[i, j+2], \ | |
2. * G[i+1, j],\ | |
-1. * B[i+2, j]]) | |
if (timeshow): | |
elapsed_time = time.process_time() - t0 | |
print("Green: row index: " + str(i-1) + " of " + str(height) + \ | |
" | elapsed time: " + "{:.3f}".format(elapsed_time) + " seconds") | |
# Red and Blue channel | |
for i in range(no_of_pixel_pad, height + no_of_pixel_pad): | |
# to display progress | |
t0 = time.process_time() | |
for j in range(no_of_pixel_pad, width + no_of_pixel_pad): | |
# Green locations in Red rows | |
if (((i % 2) != 0) and ((j % 2) != 0)): | |
# R at Green locations in Red rows | |
R[i, j] = 0.125 * np.sum([.5 * G[i-2, j],\ | |
-1. * G[i-1, j-1], -1. * G[i-1, j+1], \ | |
-1. * G[i, j-2], 4. * R[i, j-1], 5. * G[i,j], 4. * R[i, j+1], -1. * G[i, j+2], \ | |
-1. * G[i+1, j-1], -1. * G[i+1, j+1], \ | |
.5 * G[i+2, j]]) | |
# B at Green locations in Red rows | |
B[i, j] = 0.125 * np.sum([-1. * G[i-2, j], \ | |
-1. * G[i-1, j-1], 4. * B[i-1, j], -1. * G[i-1, j+1], \ | |
.5 * G[i, j-2], 5. * G[i,j], .5 * G[i, j+2], \ | |
-1. * G[i+1, j-1], 4. * B[i+1,j], -1. * G[i+1, j+1], \ | |
-1. * G[i+2, j]]) | |
# Green locations in Blue rows | |
elif (((i % 2) == 0) and ((j % 2) == 0)): | |
# R at Green locations in Blue rows | |
R[i, j] = 0.125 * np.sum([-1. * G[i-2, j], \ | |
-1. * G[i-1, j-1], 4. * R[i-1, j], -1. * G[i-1, j+1], \ | |
.5 * G[i, j-2], 5. * G[i,j], .5 * G[i, j+2], \ | |
-1. * G[i+1, j-1], 4. * R[i+1, j], -1. * G[i+1, j+1], \ | |
-1. * G[i+2, j]]) | |
# B at Green locations in Blue rows | |
B[i, j] = 0.125 * np.sum([.5 * G[i-2, j], \ | |
-1. * G [i-1, j-1], -1. * G[i-1, j+1], \ | |
-1. * G[i, j-2], 4. * B[i, j-1], 5. * G[i,j], 4. * B[i, j+1], -1. * G[i, j+2], \ | |
-1. * G[i+1, j-1], -1. * G[i+1, j+1], \ | |
.5 * G[i+2, j]]) | |
# R at Blue locations | |
elif (((i % 2) == 0) and ((j % 2) != 0)): | |
R[i, j] = 0.125 * np.sum([-1.5 * B[i-2, j], \ | |
2. * R[i-1, j-1], 2. * R[i-1, j+1], \ | |
-1.5 * B[i, j-2], 6. * B[i,j], -1.5 * B[i, j+2], \ | |
2. * R[i+1, j-1], 2. * R[i+1, j+1], \ | |
-1.5 * B[i+2, j]]) | |
# B at Red locations | |
elif (((i % 2) != 0) and ((j % 2) == 0)): | |
B[i, j] = 0.125 * np.sum([-1.5 * R[i-2, j], \ | |
2. * B[i-1, j-1], 2. * B[i-1, j+1], \ | |
-1.5 * R[i, j-2], 6. * R[i,j], -1.5 * R[i, j+2], \ | |
2. * B[i+1, j-1], 2. * B[i+1, j+1], \ | |
-1.5 * R[i+2, j]]) | |
if (timeshow): | |
elapsed_time = time.process_time() - t0 | |
print("Red/Blue: row index: " + str(i-1) + " of " + str(height) + \ | |
" | elapsed time: " + "{:.3f}".format(elapsed_time) + " seconds") | |
elif (bayer_pattern == "grbg"): | |
G[::2, ::2] = raw[::2, ::2] | |
G[1::2, 1::2] = raw[1::2, 1::2] | |
R[::2, 1::2] = raw[::2, 1::2] | |
B[1::2, ::2] = raw[1::2, ::2] | |
# Green channel | |
for i in range(no_of_pixel_pad, height + no_of_pixel_pad): | |
# to display progress | |
t0 = time.process_time() | |
for j in range(no_of_pixel_pad, width + no_of_pixel_pad): | |
# G at Red location | |
if (((i % 2) == 0) and ((j % 2) != 0)): | |
G[i, j] = 0.125 * np.sum([-1. * R[i-2, j], \ | |
2. * G[i-1, j], \ | |
-1. * R[i, j-2], 2. * G[i, j-1], 4. * R[i,j], 2. * G[i, j+1], -1. * R[i, j+2],\ | |
2. * G[i+1, j], \ | |
-1. * R[i+2, j]]) | |
# G at Blue location | |
elif (((i % 2) != 0) and ((j % 2) == 0)): | |
G[i, j] = 0.125 * np.sum([-1. * B[i-2, j], \ | |
2. * G[i-1, j], \ | |
-1. * B[i, j-2], 2. * G[i, j-1], 4. * B[i,j], 2. * G[i, j+1], -1. * B[i, j+2], \ | |
2. * G[i+1, j],\ | |
-1. * B[i+2, j]]) | |
if (timeshow): | |
elapsed_time = time.process_time() - t0 | |
print("Green: row index: " + str(i-1) + " of " + str(height) + \ | |
" | elapsed time: " + "{:.3f}".format(elapsed_time) + " seconds") | |
# Red and Blue channel | |
for i in range(no_of_pixel_pad, height + no_of_pixel_pad): | |
# to display progress | |
t0 = time.process_time() | |
for j in range(no_of_pixel_pad, width + no_of_pixel_pad): | |
# Green locations in Red rows | |
if (((i % 2) == 0) and ((j % 2) == 0)): | |
# R at Green locations in Red rows | |
R[i, j] = 0.125 * np.sum([.5 * G[i-2, j],\ | |
-1. * G[i-1, j-1], -1. * G[i-1, j+1], \ | |
-1. * G[i, j-2], 4. * R[i, j-1], 5. * G[i,j], 4. * R[i, j+1], -1. * G[i, j+2], \ | |
-1. * G[i+1, j-1], -1. * G[i+1, j+1], \ | |
.5 * G[i+2, j]]) | |
# B at Green locations in Red rows | |
B[i, j] = 0.125 * np.sum([-1. * G[i-2, j], \ | |
-1. * G[i-1, j-1], 4. * B[i-1, j], -1. * G[i-1, j+1], \ | |
.5 * G[i, j-2], 5. * G[i,j], .5 * G[i, j+2], \ | |
-1. * G[i+1, j-1], 4. * B[i+1,j], -1. * G[i+1, j+1], \ | |
-1. * G[i+2, j]]) | |
# Green locations in Blue rows | |
elif (((i % 2) != 0) and ((j % 2) != 0)): | |
# R at Green locations in Blue rows | |
R[i, j] = 0.125 * np.sum([-1. * G[i-2, j], \ | |
-1. * G[i-1, j-1], 4. * R[i-1, j], -1. * G[i-1, j+1], \ | |
.5 * G[i, j-2], 5. * G[i,j], .5 * G[i, j+2], \ | |
-1. * G[i+1, j-1], 4. * R[i+1, j], -1. * G[i+1, j+1], \ | |
-1. * G[i+2, j]]) | |
# B at Green locations in Blue rows | |
B[i, j] = 0.125 * np.sum([.5 * G[i-2, j], \ | |
-1. * G [i-1, j-1], -1. * G[i-1, j+1], \ | |
-1. * G[i, j-2], 4. * B[i, j-1], 5. * G[i,j], 4. * B[i, j+1], -1. * G[i, j+2], \ | |
-1. * G[i+1, j-1], -1. * G[i+1, j+1], \ | |
.5 * G[i+2, j]]) | |
# R at Blue locations | |
elif (((i % 2) != 0) and ((j % 2) == 0)): | |
R[i, j] = 0.125 * np.sum([-1.5 * B[i-2, j], \ | |
2. * R[i-1, j-1], 2. * R[i-1, j+1], \ | |
-1.5 * B[i, j-2], 6. * B[i,j], -1.5 * B[i, j+2], \ | |
2. * R[i+1, j-1], 2. * R[i+1, j+1], \ | |
-1.5 * B[i+2, j]]) | |
# B at Red locations | |
elif (((i % 2) == 0) and ((j % 2) != 0)): | |
B[i, j] = 0.125 * np.sum([-1.5 * R[i-2, j], \ | |
2. * B[i-1, j-1], 2. * B[i-1, j+1], \ | |
-1.5 * R[i, j-2], 6. * R[i,j], -1.5 * R[i, j+2], \ | |
2. * B[i+1, j-1], 2. * B[i+1, j+1], \ | |
-1.5 * R[i+2, j]]) | |
if (timeshow): | |
elapsed_time = time.process_time() - t0 | |
print("Red/Blue: row index: " + str(i-1) + " of " + str(height) + \ | |
" | elapsed time: " + "{:.3f}".format(elapsed_time) + " seconds") | |
elif (bayer_pattern == "bggr"): | |
G[::2, 1::2] = raw[::2, 1::2] | |
G[1::2, ::2] = raw[1::2, ::2] | |
R[1::2, 1::2] = raw[1::2, 1::2] | |
B[::2, ::2] = raw[::2, ::2] | |
# Green channel | |
for i in range(no_of_pixel_pad, height + no_of_pixel_pad): | |
# to display progress | |
t0 = time.process_time() | |
for j in range(no_of_pixel_pad, width + no_of_pixel_pad): | |
# G at Red location | |
if (((i % 2) != 0) and ((j % 2) != 0)): | |
G[i, j] = 0.125 * np.sum([-1. * R[i-2, j], \ | |
2. * G[i-1, j], \ | |
-1. * R[i, j-2], 2. * G[i, j-1], 4. * R[i,j], 2. * G[i, j+1], -1. * R[i, j+2],\ | |
2. * G[i+1, j], \ | |
-1. * R[i+2, j]]) | |
# G at Blue location | |
elif (((i % 2) == 0) and ((j % 2) == 0)): | |
G[i, j] = 0.125 * np.sum([-1. * B[i-2, j], \ | |
2. * G[i-1, j], \ | |
-1. * B[i, j-2], 2. * G[i, j-1], 4. * B[i,j], 2. * G[i, j+1], -1. * B[i, j+2], \ | |
2. * G[i+1, j],\ | |
-1. * B[i+2, j]]) | |
if (timeshow): | |
elapsed_time = time.process_time() - t0 | |
print("Green: row index: " + str(i-1) + " of " + str(height) + \ | |
" | elapsed time: " + "{:.3f}".format(elapsed_time) + " seconds") | |
# Red and Blue channel | |
for i in range(no_of_pixel_pad, height + no_of_pixel_pad): | |
# to display progress | |
t0 = time.process_time() | |
for j in range(no_of_pixel_pad, width + no_of_pixel_pad): | |
# Green locations in Red rows | |
if (((i % 2) != 0) and ((j % 2) == 0)): | |
# R at Green locations in Red rows | |
R[i, j] = 0.125 * np.sum([.5 * G[i-2, j],\ | |
-1. * G[i-1, j-1], -1. * G[i-1, j+1], \ | |
-1. * G[i, j-2], 4. * R[i, j-1], 5. * G[i,j], 4. * R[i, j+1], -1. * G[i, j+2], \ | |
-1. * G[i+1, j-1], -1. * G[i+1, j+1], \ | |
.5 * G[i+2, j]]) | |
# B at Green locations in Red rows | |
B[i, j] = 0.125 * np.sum([-1. * G[i-2, j], \ | |
-1. * G[i-1, j-1], 4. * B[i-1, j], -1. * G[i-1, j+1], \ | |
.5 * G[i, j-2], 5. * G[i,j], .5 * G[i, j+2], \ | |
-1. * G[i+1, j-1], 4. * B[i+1,j], -1. * G[i+1, j+1], \ | |
-1. * G[i+2, j]]) | |
# Green locations in Blue rows | |
elif (((i % 2) == 0) and ((j % 2) != 0)): | |
# R at Green locations in Blue rows | |
R[i, j] = 0.125 * np.sum([-1. * G[i-2, j], \ | |
-1. * G[i-1, j-1], 4. * R[i-1, j], -1. * G[i-1, j+1], \ | |
.5 * G[i, j-2], 5. * G[i,j], .5 * G[i, j+2], \ | |
-1. * G[i+1, j-1], 4. * R[i+1, j], -1. * G[i+1, j+1], \ | |
-1. * G[i+2, j]]) | |
# B at Green locations in Blue rows | |
B[i, j] = 0.125 * np.sum([.5 * G[i-2, j], \ | |
-1. * G [i-1, j-1], -1. * G[i-1, j+1], \ | |
-1. * G[i, j-2], 4. * B[i, j-1], 5. * G[i,j], 4. * B[i, j+1], -1. * G[i, j+2], \ | |
-1. * G[i+1, j-1], -1. * G[i+1, j+1], \ | |
.5 * G[i+2, j]]) | |
# R at Blue locations | |
elif (((i % 2) == 0) and ((j % 2) == 0)): | |
R[i, j] = 0.125 * np.sum([-1.5 * B[i-2, j], \ | |
2. * R[i-1, j-1], 2. * R[i-1, j+1], \ | |
-1.5 * B[i, j-2], 6. * B[i,j], -1.5 * B[i, j+2], \ | |
2. * R[i+1, j-1], 2. * R[i+1, j+1], \ | |
-1.5 * B[i+2, j]]) | |
# B at Red locations | |
elif (((i % 2) != 0) and ((j % 2) != 0)): | |
B[i, j] = 0.125 * np.sum([-1.5 * R[i-2, j], \ | |
2. * B[i-1, j-1], 2. * B[i-1, j+1], \ | |
-1.5 * R[i, j-2], 6. * R[i,j], -1.5 * R[i, j+2], \ | |
2. * B[i+1, j-1], 2. * B[i+1, j+1], \ | |
-1.5 * R[i+2, j]]) | |
if (timeshow): | |
elapsed_time = time.process_time() - t0 | |
print("Red/Blue: row index: " + str(i-1) + " of " + str(height) + \ | |
" | elapsed time: " + "{:.3f}".format(elapsed_time) + " seconds") | |
else: | |
print("Invalid bayer pattern. Valid pattern can be rggb, gbrg, grbg, bggr") | |
return demosaic_out # This will be all zeros | |
# Fill up the RGB output with interpolated values | |
demosaic_out[0:height, 0:width, 0] = R[no_of_pixel_pad : height + no_of_pixel_pad, \ | |
no_of_pixel_pad : width + no_of_pixel_pad] | |
demosaic_out[0:height, 0:width, 1] = G[no_of_pixel_pad : height + no_of_pixel_pad, \ | |
no_of_pixel_pad : width + no_of_pixel_pad] | |
demosaic_out[0:height, 0:width, 2] = B[no_of_pixel_pad : height + no_of_pixel_pad, \ | |
no_of_pixel_pad : width + no_of_pixel_pad] | |
demosaic_out = np.clip(demosaic_out, clip_range[0], clip_range[1]) | |
return demosaic_out | |
def fill_channel_directional_weight(data, bayer_pattern): | |
#== Calculate the directional weights (weight_N, weight_E, weight_S, weight_W. | |
# where N, E, S, W stand for north, east, south, and west.) | |
data = np.asarray(data) | |
v = np.asarray(signal.convolve2d(data, [[1],[0],[-1]], mode="same", boundary="symm")) | |
h = np.asarray(signal.convolve2d(data, [[1, 0, -1]], mode="same", boundary="symm")) | |
weight_N = np.zeros(np.shape(data), dtype=np.float32) | |
weight_E = np.zeros(np.shape(data), dtype=np.float32) | |
weight_S = np.zeros(np.shape(data), dtype=np.float32) | |
weight_W = np.zeros(np.shape(data), dtype=np.float32) | |
value_N = np.zeros(np.shape(data), dtype=np.float32) | |
value_E = np.zeros(np.shape(data), dtype=np.float32) | |
value_S = np.zeros(np.shape(data), dtype=np.float32) | |
value_W = np.zeros(np.shape(data), dtype=np.float32) | |
if ((bayer_pattern == "rggb") or (bayer_pattern == "bggr")): | |
# note that in the following the locations in the comments are given | |
# assuming the bayer_pattern rggb | |
#== CALCULATE WEIGHTS IN B LOCATIONS | |
weight_N[1::2, 1::2] = np.abs(v[1::2, 1::2]) + np.abs(v[::2, 1::2]) | |
# repeating the column before the last to the right so that sampling | |
# does not cause any dimension mismatch | |
temp_h_b = np.hstack((h, np.atleast_2d(h[:, -2]).T)) | |
weight_E[1::2, 1::2] = np.abs(h[1::2, 1::2]) + np.abs(temp_h_b[1::2, 2::2]) | |
# repeating the row before the last row to the bottom so that sampling | |
# does not cause any dimension mismatch | |
temp_v_b = np.vstack((v, v[-1])) | |
weight_S[1::2, 1::2] = np.abs(v[1::2, 1::2]) + np.abs(temp_v_b[2::2, 1::2]) | |
weight_W[1::2, 1::2] = np.abs(h[1::2, 1::2]) + np.abs(h[1::2, ::2]) | |
#== CALCULATE WEIGHTS IN R LOCATIONS | |
# repeating the second row at the top of matrix so that sampling does | |
# not cause any dimension mismatch, also remove the bottom row | |
temp_v_r = np.delete(np.vstack((v[1], v)), -1, 0) | |
weight_N[::2, ::2] = np.abs(v[::2, ::2]) + np.abs(temp_v_r[::2, ::2]) | |
weight_E[::2, ::2] = np.abs(h[::2, ::2]) + np.abs(h[::2, 1::2]) | |
weight_S[::2, ::2] = np.abs(v[::2, ::2]) + np.abs(v[1::2, ::2]) | |
# repeating the second column at the left of matrix so that sampling | |
# does not cause any dimension mismatch, also remove the rightmost | |
# column | |
temp_h_r = np.delete(np.hstack((np.atleast_2d(h[:, 1]).T, h)), -1, 1) | |
weight_W[::2, ::2] = np.abs(h[::2, ::2]) + np.abs(temp_h_r[::2, ::2]) | |
weight_N = np.divide(1., 1. + weight_N) | |
weight_E = np.divide(1., 1. + weight_E) | |
weight_S = np.divide(1., 1. + weight_S) | |
weight_W = np.divide(1., 1. + weight_W) | |
#== CALCULATE DIRECTIONAL ESTIMATES IN B LOCATIONS | |
value_N[1::2, 1::2] = data[::2, 1::2] + v[::2, 1::2] / 2. | |
# repeating the column before the last to the right so that sampling | |
# does not cause any dimension mismatch | |
temp = np.hstack((data, np.atleast_2d(data[:, -2]).T)) | |
value_E[1::2, 1::2] = temp[1::2, 2::2] - temp_h_b[1::2, 2::2] / 2. | |
# repeating the row before the last row to the bottom so that sampling | |
# does not cause any dimension mismatch | |
temp = np.vstack((data, data[-1])) | |
value_S[1::2, 1::2] = temp[2::2, 1::2] - temp_v_b[2::2, 1::2] / 2. | |
value_W[1::2, 1::2] = data[1::2, ::2] + h[1::2, ::2] / 2. | |
#== CALCULATE DIRECTIONAL ESTIMATES IN R LOCATIONS | |
# repeating the second row at the top of matrix so that sampling does | |
# not cause any dimension mismatch, also remove the bottom row | |
temp = np.delete(np.vstack((data[1], data)), -1, 0) | |
value_N[::2, ::2] = temp[::2, ::2] + temp_v_r[::2, ::2] / 2. | |
value_E[::2, ::2] = data[::2, 1::2] - h[::2, 1::2] / 2. | |
value_S[::2, ::2] = data[1::2, ::2] - v[1::2, ::2] / 2. | |
# repeating the second column at the left of matrix so that sampling | |
# does not cause any dimension mismatch, also remove the rightmost | |
# column | |
temp = np.delete(np.hstack((np.atleast_2d(data[:, 1]).T, data)), -1, 1) | |
value_W[::2, ::2] = temp[::2, ::2] + temp_h_r[::2, ::2] / 2. | |
output = np.zeros(np.shape(data), dtype=np.float32) | |
output = np.divide((np.multiply(value_N, weight_N) + \ | |
np.multiply(value_E, weight_E) + \ | |
np.multiply(value_S, weight_S) + \ | |
np.multiply(value_W, weight_W)),\ | |
(weight_N + weight_E + weight_S + weight_W)) | |
output[::2, 1::2] = data[::2, 1::2] | |
output[1::2, ::2] = data[1::2, ::2] | |
return output | |
elif ((bayer_pattern == "gbrg") or (bayer_pattern == "grbg")): | |
# note that in the following the locations in the comments are given | |
# assuming the bayer_pattern gbrg | |
#== CALCULATE WEIGHTS IN B LOCATIONS | |
# repeating the second row at the top of matrix so that sampling does | |
# not cause any dimension mismatch, also remove the bottom row | |
temp_v_b = np.delete(np.vstack((v[1], v)), -1, 0) | |
weight_N[::2, 1::2] = np.abs(v[::2, 1::2]) + np.abs(temp_v_b[::2, 1::2]) | |
# repeating the column before the last to the right so that sampling | |
# does not cause any dimension mismatch | |
temp_h_b = np.hstack((h, np.atleast_2d(h[:, -2]).T)) | |
weight_E[::2, 1::2] = np.abs(h[::2, 1::2]) + np.abs(temp_h_b[::2, 2::2]) | |
# repeating the row before the last row to the bottom so that sampling | |
# does not cause any dimension mismatch | |
weight_S[::2, 1::2] = np.abs(v[::2, 1::2]) + np.abs(v[1::2, 1::2]) | |
weight_W[::2, 1::2] = np.abs(h[::2, 1::2]) + np.abs(h[::2, ::2]) | |
#== CALCULATE WEIGHTS IN R LOCATIONS | |
weight_N[1::2, ::2] = np.abs(v[1::2, ::2]) + np.abs(v[::2, ::2]) | |
weight_E[1::2, ::2] = np.abs(h[1::2, ::2]) + np.abs(h[1::2, 1::2]) | |
# repeating the row before the last row to the bottom so that sampling | |
# does not cause any dimension mismatch | |
temp_v_r = np.vstack((v, v[-1])) | |
weight_S[1::2, ::2] = np.abs(v[1::2, ::2]) + np.abs(temp_v_r[2::2, ::2]) | |
# repeating the second column at the left of matrix so that sampling | |
# does not cause any dimension mismatch, also remove the rightmost | |
# column | |
temp_h_r = np.delete(np.hstack((np.atleast_2d(h[:, 1]).T, h)), -1, 1) | |
weight_W[1::2, ::2] = np.abs(h[1::2, ::2]) + np.abs(temp_h_r[1::2, ::2]) | |
weight_N = np.divide(1., 1. + weight_N) | |
weight_E = np.divide(1., 1. + weight_E) | |
weight_S = np.divide(1., 1. + weight_S) | |
weight_W = np.divide(1., 1. + weight_W) | |
#== CALCULATE DIRECTIONAL ESTIMATES IN B LOCATIONS | |
# repeating the second row at the top of matrix so that sampling does | |
# not cause any dimension mismatch, also remove the bottom row | |
temp = np.delete(np.vstack((data[1], data)), -1, 0) | |
value_N[::2, 1::2] = temp[::2, 1::2] + temp_v_b[::2, 1::2] / 2. | |
# repeating the column before the last to the right so that sampling | |
# does not cause any dimension mismatch | |
temp = np.hstack((data, np.atleast_2d(data[:, -2]).T)) | |
value_E[::2, 1::2] = temp[::2, 2::2] - temp_h_b[::2, 2::2] / 2. | |
# repeating the row before the last row to the bottom so that sampling | |
# does not cause any dimension mismatch | |
value_S[::2, 1::2] = data[1::2, 1::2] - v[1::2, 1::2] / 2. | |
value_W[::2, 1::2] = data[::2, ::2] + h[::2, ::2] / 2. | |
#== CALCULATE DIRECTIONAL ESTIMATES IN R LOCATIONS | |
# repeating the second row at the top of matrix so that sampling does | |
# not cause any dimension mismatch, also remove the bottom row | |
value_N[1::2, ::2] = data[::2, ::2] + v[::2, ::2] / 2. | |
value_E[1::2, ::2] = data[1::2, 1::2] - h[1::2, 1::2] / 2. | |
# repeating the row before the last row to the bottom so that sampling | |
# does not cause any dimension mismatch | |
temp = np.vstack((data, data[-1])) | |
value_S[1::2, ::2] = temp[2::2, ::2] - temp_v_r[2::2, ::2] / 2. | |
# repeating the second column at the left of matrix so that sampling | |
# does not cause any dimension mismatch, also remove the rightmost | |
# column | |
temp = np.delete(np.hstack((np.atleast_2d(data[:, 1]).T, data)), -1, 1) | |
value_W[1::2, ::2] = temp[1::2, ::2] + temp_h_r[1::2, ::2] / 2. | |
output = np.zeros(np.shape(data), dtype=np.float32) | |
output = np.divide((np.multiply(value_N, weight_N) + \ | |
np.multiply(value_E, weight_E) + \ | |
np.multiply(value_S, weight_S) + \ | |
np.multiply(value_W, weight_W)),\ | |
(weight_N + weight_E + weight_S + weight_W)) | |
output[::2, ::2] = data[::2, ::2] | |
output[1::2, 1::2] = data[1::2, 1::2] | |
return output | |
def fill_br_locations(data, G, bayer_pattern): | |
# Fill up the B/R values interpolated at R/B locations | |
B = np.zeros(np.shape(data), dtype=np.float32) | |
R = np.zeros(np.shape(data), dtype=np.float32) | |
data = np.asarray(data) | |
G = np.asarray(G) | |
d1 = np.asarray(signal.convolve2d(data, [[-1, 0, 0],[0, 0, 0], [0, 0, 1]], mode="same", boundary="symm")) | |
d2 = np.asarray(signal.convolve2d(data, [[0, 0, 1], [0, 0, 0], [-1, 0, 0]], mode="same", boundary="symm")) | |
df_NE = np.asarray(signal.convolve2d(G, [[0, 0, 0], [0, 1, 0], [-1, 0, 0]], mode="same", boundary="symm")) | |
df_SE = np.asarray(signal.convolve2d(G, [[-1, 0, 0], [0, 1, 0], [0, 0, 0]], mode="same", boundary="symm")) | |
df_SW = np.asarray(signal.convolve2d(G, [[0, 0, -1], [0, 1, 0], [0, 0, 0]], mode="same", boundary="symm")) | |
df_NW = np.asarray(signal.convolve2d(G, [[0, 0, 0], [0, 1, 0], [0, 0, -1]], mode="same", boundary="symm")) | |
weight_NE = np.zeros(np.shape(data), dtype=np.float32) | |
weight_SE = np.zeros(np.shape(data), dtype=np.float32) | |
weight_SW = np.zeros(np.shape(data), dtype=np.float32) | |
weight_NW = np.zeros(np.shape(data), dtype=np.float32) | |
value_NE = np.zeros(np.shape(data), dtype=np.float32) | |
value_SE = np.zeros(np.shape(data), dtype=np.float32) | |
value_SW = np.zeros(np.shape(data), dtype=np.float32) | |
value_NW = np.zeros(np.shape(data), dtype=np.float32) | |
if ((bayer_pattern == "rggb") or (bayer_pattern == "bggr")): | |
#== weights for B in R locations | |
weight_NE[::2, ::2] = np.abs(d2[::2, ::2]) + np.abs(df_NE[::2, ::2]) | |
weight_SE[::2, ::2] = np.abs(d1[::2, ::2]) + np.abs(df_SE[::2, ::2]) | |
weight_SW[::2, ::2] = np.abs(d2[::2, ::2]) + np.abs(df_SW[::2, ::2]) | |
weight_NW[::2, ::2] = np.abs(d1[::2, ::2]) + np.abs(df_NW[::2, ::2]) | |
#== weights for R in B locations | |
weight_NE[1::2, 1::2] = np.abs(d2[1::2, 1::2]) + np.abs(df_NE[1::2, 1::2]) | |
weight_SE[1::2, 1::2] = np.abs(d1[1::2, 1::2]) + np.abs(df_SE[1::2, 1::2]) | |
weight_SW[1::2, 1::2] = np.abs(d2[1::2, 1::2]) + np.abs(df_SW[1::2, 1::2]) | |
weight_NW[1::2, 1::2] = np.abs(d1[1::2, 1::2]) + np.abs(df_NW[1::2, 1::2]) | |
weight_NE = np.divide(1., 1. + weight_NE) | |
weight_SE = np.divide(1., 1. + weight_SE) | |
weight_SW = np.divide(1., 1. + weight_SW) | |
weight_NW = np.divide(1., 1. + weight_NW) | |
#== directional estimates of B in R locations | |
# repeating the second row at the top of matrix so that sampling does | |
# not cause any dimension mismatch, also remove the bottom row | |
temp = np.delete(np.vstack((data[1], data)), -1, 0) | |
value_NE[::2, ::2] = temp[::2, 1::2] + df_NE[::2, ::2] / 2. | |
value_SE[::2, ::2] = data[1::2, 1::2] + df_SE[::2, ::2] / 2. | |
# repeating the second column at the left of matrix so that sampling | |
# does not cause any dimension mismatch, also remove the rightmost | |
# column | |
temp = np.delete(np.hstack((np.atleast_2d(data[:, 1]).T, data)), -1, 1) | |
value_SW[::2, ::2] = temp[1::2, ::2] + df_SW[::2, ::2] / 2. | |
# repeating the second row at the top of matrix so that sampling does | |
# not cause any dimension mismatch, also remove the bottom row | |
temp = np.delete(np.vstack((data[1], data)), -1, 0) | |
# repeating the second column at the left of matrix so that sampling | |
# does not cause any dimension mismatch, also remove the rightmost | |
# column | |
temp = np.delete(np.hstack((np.atleast_2d(temp[:, 1]).T, temp)), -1, 1) | |
value_NW[::2, ::2] = temp[::2, ::2] + df_NW[::2, ::2] | |
#== directional estimates of R in B locations | |
# repeating the column before the last to the right so that sampling | |
# does not cause any dimension mismatch | |
temp = np.hstack((data, np.atleast_2d(data[:, -2]).T)) | |
value_NE[1::2, 1::2] = temp[::2, 2::2] + df_NE[1::2, 1::2] / 2. | |
# repeating the column before the last to the right so that sampling | |
# does not cause any dimension mismatch | |
temp = np.hstack((data, np.atleast_2d(data[:, -2]).T)) | |
# repeating the row before the last row to the bottom so that sampling | |
# does not cause any dimension mismatch | |
temp = np.vstack((temp, temp[-1])) | |
value_SE[1::2, 1::2] = temp[2::2, 2::2] + df_SE[1::2, 1::2] / 2. | |
# repeating the row before the last row to the bottom so that sampling | |
# does not cause any dimension mismatch | |
temp = np.vstack((data, data[-1])) | |
value_SW[1::2, 1::2] = temp[2::2, ::2] + df_SW[1::2, 1::2] / 2. | |
value_NW[1::2, 1::2] = data[::2, ::2] + df_NW[1::2, 1::2] / 2. | |
RB = np.divide(np.multiply(weight_NE, value_NE) + \ | |
np.multiply(weight_SE, value_SE) + \ | |
np.multiply(weight_SW, value_SW) + \ | |
np.multiply(weight_NW, value_NW),\ | |
(weight_NE + weight_SE + weight_SW + weight_NW)) | |
if (bayer_pattern == "rggb"): | |
R[1::2, 1::2] = RB[1::2, 1::2] | |
R[::2, ::2] = data[::2, ::2] | |
B[::2, ::2] = RB[::2, ::2] | |
B[1::2, 1::2] = data[1::2, 1::2] | |
elif (bayer_pattern == "bggr"): | |
R[::2, ::2] = RB[::2, ::2] | |
R[1::2, 1::2] = data[1::2, 1::2] | |
B[1::2, 1::2] = RB[1::2, 1::2] | |
B[::2, ::2] = data[::2, ::2] | |
R[1::2, ::2] = G[1::2, ::2] | |
R[::2, 1::2] = G[::2, 1::2] | |
R = fill_channel_directional_weight(R, "gbrg") | |
B[1::2, ::2] = G[1::2, ::2] | |
B[::2, 1::2] = G[::2, 1::2] | |
B = fill_channel_directional_weight(B, "gbrg") | |
elif ((bayer_pattern == "grbg") or (bayer_pattern == "gbrg")): | |
#== weights for B in R locations | |
weight_NE[::2, 1::2] = np.abs(d2[::2, 1::2]) + np.abs(df_NE[::2, 1::2]) | |
weight_SE[::2, 1::2] = np.abs(d1[::2, 1::2]) + np.abs(df_SE[::2, 1::2]) | |
weight_SW[::2, 1::2] = np.abs(d2[::2, 1::2]) + np.abs(df_SW[::2, 1::2]) | |
weight_NW[::2, 1::2] = np.abs(d1[::2, 1::2]) + np.abs(df_NW[::2, 1::2]) | |
#== weights for R in B locations | |
weight_NE[1::2, ::2] = np.abs(d2[1::2, ::2]) + np.abs(df_NE[1::2, ::2]) | |
weight_SE[1::2, ::2] = np.abs(d1[1::2, ::2]) + np.abs(df_SE[1::2, ::2]) | |
weight_SW[1::2, ::2] = np.abs(d2[1::2, ::2]) + np.abs(df_SW[1::2, ::2]) | |
weight_NW[1::2, ::2] = np.abs(d1[1::2, ::2]) + np.abs(df_NW[1::2, ::2]) | |
weight_NE = np.divide(1., 1. + weight_NE) | |
weight_SE = np.divide(1., 1. + weight_SE) | |
weight_SW = np.divide(1., 1. + weight_SW) | |
weight_NW = np.divide(1., 1. + weight_NW) | |
#== directional estimates of B in R locations | |
# repeating the second row at the top of matrix so that sampling does | |
# not cause any dimension mismatch, also remove the bottom row | |
temp = np.delete(np.vstack((data[1], data)), -1, 0) | |
# repeating the column before the last to the right so that sampling | |
# does not cause any dimension mismatch | |
temp = np.hstack((temp, np.atleast_2d(temp[:, -2]).T)) | |
value_NE[::2, 1::2] = temp[::2, 2::2] + df_NE[::2, 1::2] / 2. | |
# repeating the column before the last to the right so that sampling | |
# does not cause any dimension mismatch | |
temp = np.hstack((data, np.atleast_2d(data[:, -2]).T)) | |
value_SE[::2, 1::2] = temp[1::2, 2::2] + df_SE[::2, 1::2] / 2. | |
value_SW[::2, 1::2] = data[1::2, ::2] + df_SW[::2, 1::2] / 2. | |
# repeating the second row at the top of matrix so that sampling does | |
# not cause any dimension mismatch, also remove the bottom row | |
temp = np.delete(np.vstack((data[1], data)), -1, 0) | |
value_NW[::2, 1::2] = temp[::2, ::2] + df_NW[::2, 1::2] | |
#== directional estimates of R in B locations | |
value_NE[1::2, ::2] = data[::2, 1::2] + df_NE[1::2, ::2] / 2. | |
# repeating the column before the last to the right so that sampling | |
# does not cause any dimension mismatch | |
temp = np.hstack((data, np.atleast_2d(data[:, -2]).T)) | |
# repeating the row before the last row to the bottom so that sampling | |
# does not cause any dimension mismatch | |
temp = np.vstack((temp, temp[-1])) | |
value_SE[1::2, ::2] = temp[2::2, 1::2] + df_SE[1::2, ::2] / 2. | |
# repeating the row before the last row to the bottom so that sampling | |
# does not cause any dimension mismatch | |
temp = np.vstack((data, data[-1])) | |
# repeating the second column at the left of matrix so that sampling | |
# does not cause any dimension mismatch, also remove the rightmost | |
# column | |
temp = np.delete(np.hstack((np.atleast_2d(temp[:, 1]).T, temp)), -1, 1) | |
value_SW[1::2, ::2] = temp[2::2, ::2] + df_SW[1::2, ::2] / 2. | |
# repeating the second column at the left of matrix so that sampling | |
# does not cause any dimension mismatch, also remove the rightmost | |
# column | |
temp = np.delete(np.hstack((np.atleast_2d(data[:, 1]).T, data)), -1, 1) | |
value_NW[1::2, ::2] = temp[::2, ::2] + df_NW[1::2, ::2] / 2. | |
RB = np.divide(np.multiply(weight_NE, value_NE) + \ | |
np.multiply(weight_SE, value_SE) + \ | |
np.multiply(weight_SW, value_SW) + \ | |
np.multiply(weight_NW, value_NW),\ | |
(weight_NE + weight_SE + weight_SW + weight_NW)) | |
if (bayer_pattern == "grbg"): | |
R[1::2, ::2] = RB[1::2, ::2] | |
R[::2, 1::2] = data[::2, 1::2] | |
B[::2, 1::2] = RB[::2, 1::2] | |
B[1::2, ::2] = data[1::2, ::2] | |
elif (bayer_pattern == "gbrg"): | |
R[::2, 1::2] = RB[::2, 1::2] | |
R[1::2, ::2] = data[1::2, ::2] | |
B[1::2, ::2] = RB[1::2, ::2] | |
B[::2, 1::2] = data[::2, 1::2] | |
R[::2, ::2] = G[::2, ::2] | |
R[1::2, 1::2] = G[1::2, 1::2] | |
R = fill_channel_directional_weight(R, "rggb") | |
B[1::2, 1::2] = G[1::2, 1::2] | |
B[::2, ::2] = G[::2, ::2] | |
B = fill_channel_directional_weight(B, "rggb") | |
return B, R | |
# # ============================================================= | |
# # function: dbayer_mhc_fast | |
# # demosaicing using Malvar-He-Cutler algorithm | |
# # http://www.ipol.im/pub/art/2011/g_mhcd/ | |
# # ============================================================= | |
# def debayer_mhc_fast(raw, bayer_pattern="rggb", clip_range=[0, 65535], timeshow=False): | |
# | |
# # convert to float32 in case it was not | |
# raw = np.float32(raw) | |
# | |
# # dimensions | |
# width, height = utility.helpers(raw).get_width_height() | |
# | |
# # allocate space for the R, G, B planes | |
# R = np.empty((height, width), dtype = np.float32) | |
# G = np.empty((height, width), dtype = np.float32) | |
# B = np.empty((height, width), dtype = np.float32) | |
# | |
# # create a RGB output | |
# demosaic_out = np.empty( (height, width, 3), dtype = np.float32 ) | |
# | |
# # define the convolution kernels | |
# kernel_g_at_rb = [[0., 0., -1., 0., 0.],\ | |
# [0., 0., 2., 0., 0.],\ | |
# [-1., 2., 4., 2., -1.],\ | |
# [0., 0., 2., 0., 0.],\ | |
# [0., 0., -1., 0., 0.]] * .125 | |
# | |
# kernel_r_at_gr = [[0., 0., .5, 0., 0.],\ | |
# [0., -1., 0., -1., 0.],\ | |
# [-1., 4., 5., 4., -1.],\ | |
# [0., -1., 0., -1., 0.],\ | |
# [0., 0., .5, 0., 0.]] * .125 | |
# | |
# kernel_b_at_gr = [[0., 0., -1., 0., 0.],\ | |
# [0., -1., 4., -1., 0.],\ | |
# [.5., 0., 5., 0., .5],\ | |
# [0., -1., 4., -1., 0],\ | |
# [0., 0., -1., 0., 0.]] * .125 | |
# | |
# kernel_r_at_gb = [[0., 0., -1., 0., 0.],\ | |
# [0., -1., 4., -1., 0.],\ | |
# [.5, 0., 5., 0., .5],\ | |
# [0., -1., 4., -1., 0.],\ | |
# [0., 0., -1., 0., 0.]] * .125 | |
# | |
# kernel_b_at_gb = [[0., 0., .5, 0., 0.],\ | |
# [0., -1., 0., -1., 0.],\ | |
# [-1., 4., 5., 4., -1.],\ | |
# [0., -1., 0., -1., 0.],\ | |
# [0., 0., .5, 0., 0.]] * .125 | |
# | |
# kernel_r_at_b = [[0., 0., -1.5, 0., 0.],\ | |
# [0., 2., 0., 2., 0.],\ | |
# [-1.5, 0., 6., 0., -1.5],\ | |
# [0., 2., 0., 2., 0.],\ | |
# [0., 0., -1.5, 0., 0.]] * .125 | |
# | |
# kernel_b_at_r = [[0., 0., -1.5, 0., 0.],\ | |
# [0., 2., 0., 2., 0.],\ | |
# [-1.5, 0., 6., 0., -1.5],\ | |
# [0., 2., 0., 2., 0.],\ | |
# [0., 0., -1.5, 0., 0.]] * .125 | |
# | |
# | |
# | |
# # fill up the directly available values according to the Bayer pattern | |
# if (bayer_pattern == "rggb"): | |
# | |
# G[::2, 1::2] = raw[::2, 1::2] | |
# G[1::2, ::2] = raw[1::2, ::2] | |
# R[::2, ::2] = raw[::2, ::2] | |
# B[1::2, 1::2] = raw[1::2, 1::2] | |
# | |
# # Green channel | |
# for i in range(no_of_pixel_pad, height + no_of_pixel_pad): | |
# | |
# # to display progress | |
# t0 = time.process_time() | |
# | |
# for j in range(no_of_pixel_pad, width + no_of_pixel_pad): | |
# | |
# # G at Red location | |
# if (((i % 2) == 0) and ((j % 2) == 0)): | |
# G[i, j] = 0.125 * np.sum([-1. * R[i-2, j], \ | |
# 2. * G[i-1, j], \ | |
# -1. * R[i, j-2], 2. * G[i, j-1], 4. * R[i,j], 2. * G[i, j+1], -1. * R[i, j+2],\ | |
# 2. * G[i+1, j], \ | |
# -1. * R[i+2, j]]) | |
# # G at Blue location | |
# elif (((i % 2) != 0) and ((j % 2) != 0)): | |
# G[i, j] = 0.125 * np.sum([-1. * B[i-2, j], \ | |
# 2. * G[i-1, j], \ | |
# -1. * B[i, j-2], 2. * G[i, j-1], 4. * B[i,j], 2. * G[i, j+1], -1. * B[i, j+2], \ | |
# 2. * G[i+1, j],\ | |
# -1. * B[i+2, j]]) | |
# if (timeshow): | |
# elapsed_time = time.process_time() - t0 | |
# print("Green: row index: " + str(i-1) + " of " + str(height) + \ | |
# " | elapsed time: " + "{:.3f}".format(elapsed_time) + " seconds") | |
# | |
# # Red and Blue channel | |
# for i in range(no_of_pixel_pad, height + no_of_pixel_pad): | |
# | |
# # to display progress | |
# t0 = time.process_time() | |
# | |
# for j in range(no_of_pixel_pad, width + no_of_pixel_pad): | |
# | |
# # Green locations in Red rows | |
# if (((i % 2) == 0) and ((j % 2) != 0)): | |
# # R at Green locations in Red rows | |
# R[i, j] = 0.125 * np.sum([.5 * G[i-2, j],\ | |
# -1. * G[i-1, j-1], -1. * G[i-1, j+1], \ | |
# -1. * G[i, j-2], 4. * R[i, j-1], 5. * G[i,j], 4. * R[i, j+1], -1. * G[i, j+2], \ | |
# -1. * G[i+1, j-1], -1. * G[i+1, j+1], \ | |
# .5 * G[i+2, j]]) | |
# | |
# # B at Green locations in Red rows | |
# B[i, j] = 0.125 * np.sum([-1. * G[i-2, j], \ | |
# -1. * G[i-1, j-1], 4. * B[i-1, j], -1. * G[i-1, j+1], \ | |
# .5 * G[i, j-2], 5. * G[i,j], .5 * G[i, j+2], \ | |
# -1. * G[i+1, j-1], 4. * B[i+1,j], -1. * G[i+1, j+1], \ | |
# -1. * G[i+2, j]]) | |
# | |
# # Green locations in Blue rows | |
# elif (((i % 2) != 0) and ((j % 2) == 0)): | |
# | |
# # R at Green locations in Blue rows | |
# R[i, j] = 0.125 * np.sum([-1. * G[i-2, j], \ | |
# -1. * G[i-1, j-1], 4. * R[i-1, j], -1. * G[i-1, j+1], \ | |
# .5 * G[i, j-2], 5. * G[i,j], .5 * G[i, j+2], \ | |
# -1. * G[i+1, j-1], 4. * R[i+1, j], -1. * G[i+1, j+1], \ | |
# -1. * G[i+2, j]]) | |
# | |
# # B at Green locations in Blue rows | |
# B[i, j] = 0.125 * np.sum([.5 * G[i-2, j], \ | |
# -1. * G [i-1, j-1], -1. * G[i-1, j+1], \ | |
# -1. * G[i, j-2], 4. * B[i, j-1], 5. * G[i,j], 4. * B[i, j+1], -1. * G[i, j+2], \ | |
# -1. * G[i+1, j-1], -1. * G[i+1, j+1], \ | |
# .5 * G[i+2, j]]) | |
# | |
# # R at Blue locations | |
# elif (((i % 2) != 0) and ((j % 2) != 0)): | |
# R[i, j] = 0.125 * np.sum([-1.5 * B[i-2, j], \ | |
# 2. * R[i-1, j-1], 2. * R[i-1, j+1], \ | |
# -1.5 * B[i, j-2], 6. * B[i,j], -1.5 * B[i, j+2], \ | |
# 2. * R[i+1, j-1], 2. * R[i+1, j+1], \ | |
# -1.5 * B[i+2, j]]) | |
# | |
# # B at Red locations | |
# elif (((i % 2) == 0) and ((j % 2) == 0)): | |
# B[i, j] = 0.125 * np.sum([-1.5 * R[i-2, j], \ | |
# 2. * B[i-1, j-1], 2. * B[i-1, j+1], \ | |
# -1.5 * R[i, j-2], 6. * R[i,j], -1.5 * R[i, j+2], \ | |
# 2. * B[i+1, j-1], 2. * B[i+1, j+1], \ | |
# -1.5 * R[i+2, j]]) | |
# | |
# if (timeshow): | |
# elapsed_time = time.process_time() - t0 | |
# print("Red/Blue: row index: " + str(i-1) + " of " + str(height) + \ | |
# " | elapsed time: " + "{:.3f}".format(elapsed_time) + " seconds") | |
# | |
# | |
# elif (bayer_pattern == "gbrg"): | |
# | |
# G[::2, ::2] = raw[::2, ::2] | |
# G[1::2, 1::2] = raw[1::2, 1::2] | |
# R[1::2, ::2] = raw[1::2, ::2] | |
# B[::2, 1::2] = raw[::2, 1::2] | |
# | |
# # Green channel | |
# for i in range(no_of_pixel_pad, height + no_of_pixel_pad): | |
# | |
# # to display progress | |
# t0 = time.process_time() | |
# | |
# for j in range(no_of_pixel_pad, width + no_of_pixel_pad): | |
# | |
# # G at Red location | |
# if (((i % 2) != 0) and ((j % 2) == 0)): | |
# G[i, j] = 0.125 * np.sum([-1. * R[i-2, j], \ | |
# 2. * G[i-1, j], \ | |
# -1. * R[i, j-2], 2. * G[i, j-1], 4. * R[i,j], 2. * G[i, j+1], -1. * R[i, j+2],\ | |
# 2. * G[i+1, j], \ | |
# -1. * R[i+2, j]]) | |
# # G at Blue location | |
# elif (((i % 2) == 0) and ((j % 2) != 0)): | |
# G[i, j] = 0.125 * np.sum([-1. * B[i-2, j], \ | |
# 2. * G[i-1, j], \ | |
# -1. * B[i, j-2], 2. * G[i, j-1], 4. * B[i,j], 2. * G[i, j+1], -1. * B[i, j+2], \ | |
# 2. * G[i+1, j],\ | |
# -1. * B[i+2, j]]) | |
# if (timeshow): | |
# elapsed_time = time.process_time() - t0 | |
# print("Green: row index: " + str(i-1) + " of " + str(height) + \ | |
# " | elapsed time: " + "{:.3f}".format(elapsed_time) + " seconds") | |
# | |
# # Red and Blue channel | |
# for i in range(no_of_pixel_pad, height + no_of_pixel_pad): | |
# | |
# # to display progress | |
# t0 = time.process_time() | |
# | |
# for j in range(no_of_pixel_pad, width + no_of_pixel_pad): | |
# | |
# # Green locations in Red rows | |
# if (((i % 2) != 0) and ((j % 2) != 0)): | |
# # R at Green locations in Red rows | |
# R[i, j] = 0.125 * np.sum([.5 * G[i-2, j],\ | |
# -1. * G[i-1, j-1], -1. * G[i-1, j+1], \ | |
# -1. * G[i, j-2], 4. * R[i, j-1], 5. * G[i,j], 4. * R[i, j+1], -1. * G[i, j+2], \ | |
# -1. * G[i+1, j-1], -1. * G[i+1, j+1], \ | |
# .5 * G[i+2, j]]) | |
# | |
# # B at Green locations in Red rows | |
# B[i, j] = 0.125 * np.sum([-1. * G[i-2, j], \ | |
# -1. * G[i-1, j-1], 4. * B[i-1, j], -1. * G[i-1, j+1], \ | |
# .5 * G[i, j-2], 5. * G[i,j], .5 * G[i, j+2], \ | |
# -1. * G[i+1, j-1], 4. * B[i+1,j], -1. * G[i+1, j+1], \ | |
# -1. * G[i+2, j]]) | |
# | |
# # Green locations in Blue rows | |
# elif (((i % 2) == 0) and ((j % 2) == 0)): | |
# | |
# # R at Green locations in Blue rows | |
# R[i, j] = 0.125 * np.sum([-1. * G[i-2, j], \ | |
# -1. * G[i-1, j-1], 4. * R[i-1, j], -1. * G[i-1, j+1], \ | |
# .5 * G[i, j-2], 5. * G[i,j], .5 * G[i, j+2], \ | |
# -1. * G[i+1, j-1], 4. * R[i+1, j], -1. * G[i+1, j+1], \ | |
# -1. * G[i+2, j]]) | |
# | |
# # B at Green locations in Blue rows | |
# B[i, j] = 0.125 * np.sum([.5 * G[i-2, j], \ | |
# -1. * G [i-1, j-1], -1. * G[i-1, j+1], \ | |
# -1. * G[i, j-2], 4. * B[i, j-1], 5. * G[i,j], 4. * B[i, j+1], -1. * G[i, j+2], \ | |
# -1. * G[i+1, j-1], -1. * G[i+1, j+1], \ | |
# .5 * G[i+2, j]]) | |
# | |
# # R at Blue locations | |
# elif (((i % 2) == 0) and ((j % 2) != 0)): | |
# R[i, j] = 0.125 * np.sum([-1.5 * B[i-2, j], \ | |
# 2. * R[i-1, j-1], 2. * R[i-1, j+1], \ | |
# -1.5 * B[i, j-2], 6. * B[i,j], -1.5 * B[i, j+2], \ | |
# 2. * R[i+1, j-1], 2. * R[i+1, j+1], \ | |
# -1.5 * B[i+2, j]]) | |
# | |
# # B at Red locations | |
# elif (((i % 2) != 0) and ((j % 2) == 0)): | |
# B[i, j] = 0.125 * np.sum([-1.5 * R[i-2, j], \ | |
# 2. * B[i-1, j-1], 2. * B[i-1, j+1], \ | |
# -1.5 * R[i, j-2], 6. * R[i,j], -1.5 * R[i, j+2], \ | |
# 2. * B[i+1, j-1], 2. * B[i+1, j+1], \ | |
# -1.5 * R[i+2, j]]) | |
# | |
# if (timeshow): | |
# elapsed_time = time.process_time() - t0 | |
# print("Red/Blue: row index: " + str(i-1) + " of " + str(height) + \ | |
# " | elapsed time: " + "{:.3f}".format(elapsed_time) + " seconds") | |
# | |
# elif (bayer_pattern == "grbg"): | |
# | |
# G[::2, ::2] = raw[::2, ::2] | |
# G[1::2, 1::2] = raw[1::2, 1::2] | |
# R[::2, 1::2] = raw[::2, 1::2] | |
# B[1::2, ::2] = raw[1::2, ::2] | |
# | |
# # Green channel | |
# for i in range(no_of_pixel_pad, height + no_of_pixel_pad): | |
# | |
# # to display progress | |
# t0 = time.process_time() | |
# | |
# for j in range(no_of_pixel_pad, width + no_of_pixel_pad): | |
# | |
# # G at Red location | |
# if (((i % 2) == 0) and ((j % 2) != 0)): | |
# G[i, j] = 0.125 * np.sum([-1. * R[i-2, j], \ | |
# 2. * G[i-1, j], \ | |
# -1. * R[i, j-2], 2. * G[i, j-1], 4. * R[i,j], 2. * G[i, j+1], -1. * R[i, j+2],\ | |
# 2. * G[i+1, j], \ | |
# -1. * R[i+2, j]]) | |
# # G at Blue location | |
# elif (((i % 2) != 0) and ((j % 2) == 0)): | |
# G[i, j] = 0.125 * np.sum([-1. * B[i-2, j], \ | |
# 2. * G[i-1, j], \ | |
# -1. * B[i, j-2], 2. * G[i, j-1], 4. * B[i,j], 2. * G[i, j+1], -1. * B[i, j+2], \ | |
# 2. * G[i+1, j],\ | |
# -1. * B[i+2, j]]) | |
# if (timeshow): | |
# elapsed_time = time.process_time() - t0 | |
# print("Green: row index: " + str(i-1) + " of " + str(height) + \ | |
# " | elapsed time: " + "{:.3f}".format(elapsed_time) + " seconds") | |
# | |
# # Red and Blue channel | |
# for i in range(no_of_pixel_pad, height + no_of_pixel_pad): | |
# | |
# # to display progress | |
# t0 = time.process_time() | |
# | |
# for j in range(no_of_pixel_pad, width + no_of_pixel_pad): | |
# | |
# # Green locations in Red rows | |
# if (((i % 2) == 0) and ((j % 2) == 0)): | |
# # R at Green locations in Red rows | |
# R[i, j] = 0.125 * np.sum([.5 * G[i-2, j],\ | |
# -1. * G[i-1, j-1], -1. * G[i-1, j+1], \ | |
# -1. * G[i, j-2], 4. * R[i, j-1], 5. * G[i,j], 4. * R[i, j+1], -1. * G[i, j+2], \ | |
# -1. * G[i+1, j-1], -1. * G[i+1, j+1], \ | |
# .5 * G[i+2, j]]) | |
# | |
# # B at Green locations in Red rows | |
# B[i, j] = 0.125 * np.sum([-1. * G[i-2, j], \ | |
# -1. * G[i-1, j-1], 4. * B[i-1, j], -1. * G[i-1, j+1], \ | |
# .5 * G[i, j-2], 5. * G[i,j], .5 * G[i, j+2], \ | |
# -1. * G[i+1, j-1], 4. * B[i+1,j], -1. * G[i+1, j+1], \ | |
# -1. * G[i+2, j]]) | |
# | |
# # Green locations in Blue rows | |
# elif (((i % 2) != 0) and ((j % 2) != 0)): | |
# | |
# # R at Green locations in Blue rows | |
# R[i, j] = 0.125 * np.sum([-1. * G[i-2, j], \ | |
# -1. * G[i-1, j-1], 4. * R[i-1, j], -1. * G[i-1, j+1], \ | |
# .5 * G[i, j-2], 5. * G[i,j], .5 * G[i, j+2], \ | |
# -1. * G[i+1, j-1], 4. * R[i+1, j], -1. * G[i+1, j+1], \ | |
# -1. * G[i+2, j]]) | |
# | |
# # B at Green locations in Blue rows | |
# B[i, j] = 0.125 * np.sum([.5 * G[i-2, j], \ | |
# -1. * G [i-1, j-1], -1. * G[i-1, j+1], \ | |
# -1. * G[i, j-2], 4. * B[i, j-1], 5. * G[i,j], 4. * B[i, j+1], -1. * G[i, j+2], \ | |
# -1. * G[i+1, j-1], -1. * G[i+1, j+1], \ | |
# .5 * G[i+2, j]]) | |
# | |
# # R at Blue locations | |
# elif (((i % 2) != 0) and ((j % 2) == 0)): | |
# R[i, j] = 0.125 * np.sum([-1.5 * B[i-2, j], \ | |
# 2. * R[i-1, j-1], 2. * R[i-1, j+1], \ | |
# -1.5 * B[i, j-2], 6. * B[i,j], -1.5 * B[i, j+2], \ | |
# 2. * R[i+1, j-1], 2. * R[i+1, j+1], \ | |
# -1.5 * B[i+2, j]]) | |
# | |
# # B at Red locations | |
# elif (((i % 2) == 0) and ((j % 2) != 0)): | |
# B[i, j] = 0.125 * np.sum([-1.5 * R[i-2, j], \ | |
# 2. * B[i-1, j-1], 2. * B[i-1, j+1], \ | |
# -1.5 * R[i, j-2], 6. * R[i,j], -1.5 * R[i, j+2], \ | |
# 2. * B[i+1, j-1], 2. * B[i+1, j+1], \ | |
# -1.5 * R[i+2, j]]) | |
# | |
# if (timeshow): | |
# elapsed_time = time.process_time() - t0 | |
# print("Red/Blue: row index: " + str(i-1) + " of " + str(height) + \ | |
# " | elapsed time: " + "{:.3f}".format(elapsed_time) + " seconds") | |
# | |
# elif (bayer_pattern == "bggr"): | |
# | |
# G[::2, 1::2] = raw[::2, 1::2] | |
# G[1::2, ::2] = raw[1::2, ::2] | |
# R[1::2, 1::2] = raw[1::2, 1::2] | |
# B[::2, ::2] = raw[::2, ::2] | |
# | |
# # Green channel | |
# for i in range(no_of_pixel_pad, height + no_of_pixel_pad): | |
# | |
# # to display progress | |
# t0 = time.process_time() | |
# | |
# for j in range(no_of_pixel_pad, width + no_of_pixel_pad): | |
# | |
# # G at Red location | |
# if (((i % 2) != 0) and ((j % 2) != 0)): | |
# G[i, j] = 0.125 * np.sum([-1. * R[i-2, j], \ | |
# 2. * G[i-1, j], \ | |
# -1. * R[i, j-2], 2. * G[i, j-1], 4. * R[i,j], 2. * G[i, j+1], -1. * R[i, j+2],\ | |
# 2. * G[i+1, j], \ | |
# -1. * R[i+2, j]]) | |
# # G at Blue location | |
# elif (((i % 2) == 0) and ((j % 2) == 0)): | |
# G[i, j] = 0.125 * np.sum([-1. * B[i-2, j], \ | |
# 2. * G[i-1, j], \ | |
# -1. * B[i, j-2], 2. * G[i, j-1], 4. * B[i,j], 2. * G[i, j+1], -1. * B[i, j+2], \ | |
# 2. * G[i+1, j],\ | |
# -1. * B[i+2, j]]) | |
# if (timeshow): | |
# elapsed_time = time.process_time() - t0 | |
# print("Green: row index: " + str(i-1) + " of " + str(height) + \ | |
# " | elapsed time: " + "{:.3f}".format(elapsed_time) + " seconds") | |
# | |
# # Red and Blue channel | |
# for i in range(no_of_pixel_pad, height + no_of_pixel_pad): | |
# | |
# # to display progress | |
# t0 = time.process_time() | |
# | |
# for j in range(no_of_pixel_pad, width + no_of_pixel_pad): | |
# | |
# # Green locations in Red rows | |
# if (((i % 2) != 0) and ((j % 2) == 0)): | |
# # R at Green locations in Red rows | |
# R[i, j] = 0.125 * np.sum([.5 * G[i-2, j],\ | |
# -1. * G[i-1, j-1], -1. * G[i-1, j+1], \ | |
# -1. * G[i, j-2], 4. * R[i, j-1], 5. * G[i,j], 4. * R[i, j+1], -1. * G[i, j+2], \ | |
# -1. * G[i+1, j-1], -1. * G[i+1, j+1], \ | |
# .5 * G[i+2, j]]) | |
# | |
# # B at Green locations in Red rows | |
# B[i, j] = 0.125 * np.sum([-1. * G[i-2, j], \ | |
# -1. * G[i-1, j-1], 4. * B[i-1, j], -1. * G[i-1, j+1], \ | |
# .5 * G[i, j-2], 5. * G[i,j], .5 * G[i, j+2], \ | |
# -1. * G[i+1, j-1], 4. * B[i+1,j], -1. * G[i+1, j+1], \ | |
# -1. * G[i+2, j]]) | |
# | |
# # Green locations in Blue rows | |
# elif (((i % 2) == 0) and ((j % 2) != 0)): | |
# | |
# # R at Green locations in Blue rows | |
# R[i, j] = 0.125 * np.sum([-1. * G[i-2, j], \ | |
# -1. * G[i-1, j-1], 4. * R[i-1, j], -1. * G[i-1, j+1], \ | |
# .5 * G[i, j-2], 5. * G[i,j], .5 * G[i, j+2], \ | |
# -1. * G[i+1, j-1], 4. * R[i+1, j], -1. * G[i+1, j+1], \ | |
# -1. * G[i+2, j]]) | |
# | |
# # B at Green locations in Blue rows | |
# B[i, j] = 0.125 * np.sum([.5 * G[i-2, j], \ | |
# -1. * G [i-1, j-1], -1. * G[i-1, j+1], \ | |
# -1. * G[i, j-2], 4. * B[i, j-1], 5. * G[i,j], 4. * B[i, j+1], -1. * G[i, j+2], \ | |
# -1. * G[i+1, j-1], -1. * G[i+1, j+1], \ | |
# .5 * G[i+2, j]]) | |
# | |
# # R at Blue locations | |
# elif (((i % 2) == 0) and ((j % 2) == 0)): | |
# R[i, j] = 0.125 * np.sum([-1.5 * B[i-2, j], \ | |
# 2. * R[i-1, j-1], 2. * R[i-1, j+1], \ | |
# -1.5 * B[i, j-2], 6. * B[i,j], -1.5 * B[i, j+2], \ | |
# 2. * R[i+1, j-1], 2. * R[i+1, j+1], \ | |
# -1.5 * B[i+2, j]]) | |
# | |
# # B at Red locations | |
# elif (((i % 2) != 0) and ((j % 2) != 0)): | |
# B[i, j] = 0.125 * np.sum([-1.5 * R[i-2, j], \ | |
# 2. * B[i-1, j-1], 2. * B[i-1, j+1], \ | |
# -1.5 * R[i, j-2], 6. * R[i,j], -1.5 * R[i, j+2], \ | |
# 2. * B[i+1, j-1], 2. * B[i+1, j+1], \ | |
# -1.5 * R[i+2, j]]) | |
# | |
# if (timeshow): | |
# elapsed_time = time.process_time() - t0 | |
# print("Red/Blue: row index: " + str(i-1) + " of " + str(height) + \ | |
# " | elapsed time: " + "{:.3f}".format(elapsed_time) + " seconds") | |
# | |
# else: | |
# print("Invalid bayer pattern. Valid pattern can be rggb, gbrg, grbg, bggr") | |
# return demosaic_out # This will be all zeros | |
# | |
# # Fill up the RGB output with interpolated values | |
# demosaic_out[0:height, 0:width, 0] = R[no_of_pixel_pad : height + no_of_pixel_pad, \ | |
# no_of_pixel_pad : width + no_of_pixel_pad] | |
# demosaic_out[0:height, 0:width, 1] = G[no_of_pixel_pad : height + no_of_pixel_pad, \ | |
# no_of_pixel_pad : width + no_of_pixel_pad] | |
# demosaic_out[0:height, 0:width, 2] = B[no_of_pixel_pad : height + no_of_pixel_pad, \ | |
# no_of_pixel_pad : width + no_of_pixel_pad] | |
# | |
# demosaic_out = np.clip(demosaic_out, clip_range[0], clip_range[1]) | |
# return demosaic_out | |