Skip to content
Snippets Groups Projects
mdwi.py 7.51 KiB
import numpy as np


def is_green(i, j):
    return (not i%2 and not j%2) or (i%2 and j%2)

def is_red(i, j):
    return not i%2 and j%2

def is_blue(i, j):
    return i%2 and not j%2



def MDWI(image):
    
    res = np.empty((image.shape[0], image.shape[1], 3))
    estimated_green = np.zeros_like(image)
    estimated_red = np.zeros_like(image)
    estimated_blue = np.zeros_like(image)

    EPSILON = 10e-4

    # Estimation of green plan first

    pre_estimation = {}
    diag_gradient_factor = {}
    weight = {}
    H = [-8/256, 23/256, -48/256, 161/256, 161/256, -48/256, 23/256, -8/256]
    coord_NE = [(-4, -3), (-3, -2), (-2, -1), (-1, 0), (0, 1), (1, 2), (2, 3), (3, 4)]
    coord_SE = [(-3, -4), (-2, -3), (-1, -2), (0, -1), (1, 0), (2, 1), (3, 2), (4, 3)]
    coord_NW = [(3, -4), (2, -3), (1, -2), (0, -1), (-1, 0), (-2, 1), (-3, 2), (-4, 3)]
    coord_SW = [(4, -3), (3, -2), (2, -1), (1, 0), (0, 1), (-1, 2), (-2, 3), (-3, 4)]

    for i in range(3, image.shape[0] - 4):
        for j in range(3, image.shape[1] - 4):
            

            if (not is_green(i, j)):       
                pre_estimation["N"] = image[i-1, j] + (image[i, j] - image[i-2, j]) / 2   
                pre_estimation["S"] = image[i+1, j] + (image[i, j] - image[i+2, j]) / 2
                pre_estimation["W"] = image[i, j-1] + (image[i, j] - image[i, j-2]) / 2
                pre_estimation["E"] = image[i, j+1] + (image[i, j] - image[i, j+2]) / 2

                diag_gradient_factor["N"] = abs(image[i-2, j-1] - image[i, j-1]) + abs(image[i-3, j] - image[i-1, j]) + abs(image[i-2, j+1] - image[i, j+1]) + abs(image[i-3, j-1] - image[i-1, j-1]) + abs(image[i-3, j+1] - image[i-1, j+1]) + abs(image[i-2, j] - image[i, j]) + EPSILON
                diag_gradient_factor["S"] = abs(image[i+2, j-1] - image[i, j-1]) + abs(image[i+3, j] - image[i+1, j]) + abs(image[i+2, j+1] - image[i, j+1]) + abs(image[i+3, j-1] - image[i+1, j-1]) + abs(image[i+3, j+1] - image[i+1, j+1]) + abs(image[i+2, j] - image[i, j]) + EPSILON
                diag_gradient_factor["W"] = abs(image[i-1, j-2] - image[i-1, j]) + abs(image[i, j-3] - image[i, j-1]) + abs(image[i+1, j-2] - image[i+1, j]) + abs(image[i-1, j-3] - image[i-1, j-1]) + abs(image[i+1, j-3] - image[i+1, j-1]) + abs(image[i, j-2] - image[i, j]) + EPSILON
                diag_gradient_factor["E"] = abs(image[i-1, j+2] - image[i-1, j]) + abs(image[i, j+3] - image[i, j+1]) + abs(image[i+1, j+2] - image[i+1, j]) + abs(image[i-1, j+3] - image[i-1, j+1]) + abs(image[i+1, j+3] - image[i+1, j+1]) + abs(image[i, j+2] - image[i, j]) + EPSILON


                pre_estimation["NW"] = 0
                pre_estimation["SW"] = 0
                pre_estimation["NE"] = 0
                pre_estimation["SE"] = 0
                for k in range(8):
                    pre_estimation["NW"] += image[i + coord_NW[k][0], j + coord_NW[k][1]] * H[k]
                    pre_estimation["SW"] += image[i + coord_SW[k][0], j + coord_SW[k][1]] * H[k]
                    pre_estimation["NE"] += image[i + coord_NE[k][0], j + coord_NE[k][1]] * H[k]
                    pre_estimation["SE"] += image[i + coord_SE[k][0], j + coord_SE[k][1]] * H[k]
                
                diag_gradient_factor["NW"] = abs(image[i-2, j-1] - image[i-1, j]) + abs(image[i-1, j] - image[i, j+1]) + abs(image[i-1, j-2] - image[i, j-1]) + abs(image[i, j-1] - image[i+1, j]) + abs(image[i-1, j-1] - image[i+1, j+1]) + abs(image[i-2, j-2] - image[i, j]) + EPSILON
                diag_gradient_factor["SW"] = abs(image[i-1, j] - image[i, j-1]) + abs(image[i, j+1] - image[i+1, j]) + abs(image[i-1, j+1] - image[i+1, j-1]) + abs(image[i, j-1] - image[i+1, j-2]) + abs(image[i+1, j] - image[i+2, j-1]) + abs(image[i, j] - image[i+2, j-2]) + EPSILON
                diag_gradient_factor["NE"] = abs(image[i-1, j] - image[i, j-1]) + abs(image[i, j+1] - image[i+1, j]) + abs(image[i-1, j+1] - image[i+1, j-1]) + abs(image[i-1, j] - image[i-2, j+1]) + abs(image[i, j+1] - image[i-1, j+2]) + abs(image[i, j] - image[i-2, j+2]) + EPSILON
                diag_gradient_factor["SE"] = abs(image[i+2, j+1] - image[i+1, j]) + abs(image[i-1, j] - image[i, j+1]) + abs(image[i+1, j+2] - image[i, j+1]) + abs(image[i, j-1] - image[i+1, j]) + abs(image[i-1, j-1] - image[i+1, j+1]) + abs(image[i+2, j+2] - image[i, j]) + EPSILON

                
                for k, v in diag_gradient_factor.items():
                    weight[k] =  1 / v

                num = 0
                den = 0
                for k, v in pre_estimation.items():
                    num += v * weight[k]
                    den += weight[k]

                estimated_green[i, j] = num / den

            else:
                estimated_green[i, j] = image[i, j]


    # Then we work on blue and red plans
    
    diag = [(-1, -1), (-1, 1), (1, -1), (1, 1)]
    
    for i in range(3, image.shape[0] - 4):
        for j in range(3, image.shape[1] - 4):
            if (is_red(i, j) or is_blue(i, j)):
                ksi_nw = image[i-1, j-1] - estimated_green[i-1, j-1]
                ksi_ne = image[i-1, j+1] - estimated_green[i-1, j+1]
                ksi_sw = image[i+1, j-1] - estimated_green[i+1, j-1]
                ksi_se = image[i+1, j+1] - estimated_green[i+1, j+1]
                
                g_nw = abs(estimated_green[i-2, j-1] - estimated_green[i-1, j]) + abs(estimated_green[i-1, j-2] - estimated_green[i, j-1]) + abs(estimated_green[i-2, j-2] - estimated_green[i-1, j-1]) + abs(estimated_green[i-1, j-1] - estimated_green[i, j]) + abs(image[i-1, j-1] - image[i+1, j+1]) + EPSILON
                g_ne = abs(estimated_green[i-2, j+1] - estimated_green[i-1, j]) + abs(estimated_green[i-1, j+2] - estimated_green[i, j+1]) + abs(estimated_green[i-2, j+2] - estimated_green[i-1, j+1]) + abs(estimated_green[i-1, j+1] - estimated_green[i, j]) + abs(image[i-1, j+1] - image[i+1, j-1]) + EPSILON
                g_sw = abs(estimated_green[i+2, j-1] - estimated_green[i+1, j]) + abs(estimated_green[i+1, j-2] - estimated_green[i, j-1]) + abs(estimated_green[i+2, j-2] - estimated_green[i+1, j-1]) + abs(estimated_green[i+1, j-1] - estimated_green[i, j]) + abs(image[i+1, j-1] - image[i-1, j+1]) + EPSILON
                g_se = abs(estimated_green[i+2, j+1] - estimated_green[i+1, j]) + abs(estimated_green[i+1, j+2] - estimated_green[i, j+1]) + abs(estimated_green[i+2, j+2] - estimated_green[i+1, j+1]) + abs(estimated_green[i+1, j+1] - estimated_green[i, j]) + abs(image[i+1, j+1] - image[i-1, j-1]) + EPSILON

                pre_est = estimated_green[i, j] + (ksi_nw/g_nw + ksi_ne/g_ne + ksi_sw/g_sw + ksi_se/g_se) / (1/g_nw + 1/g_ne + 1/g_sw + 1/g_se)

                sum_dif = 0
                sum_sig = 0

                for coord in diag:
                    mu = image[i + coord[0], j + coord[1]] - pre_est
                    sum_dif += mu / (1 + abs(mu))
                    sum_sig += 1 / (1 + abs(mu))

                if (is_red(i, j)):
                    estimated_blue[i, j] = pre_est
                    estimated_red[i, j] = image[i, j]
                else:
                    estimated_red[i, j] = pre_est
                    estimated_blue[i, j] = image[i, j]

            else:
                if (is_red(i-1, j)):
                    estimated_red[i, j] = (image[i-1, j] + image[i+1, j]) / 2
                    estimated_blue[i, j] = (image[i, j-1] + image[i, j+1]) / 2
                else:
                    estimated_red[i, j] = (image[i, j-1] + image[i, j+1]) / 2
                    estimated_blue[i, j] = (image[i-1, j] + image[i+1, j]) / 2


    res[:, :, 0] = estimated_red
    res[:, :, 1] = estimated_green
    res[:, :, 2] = estimated_blue

    return res