functions_for_rasterio.py 3.70 KiB
from scipy import ndimage
from skimage.transform import rescale
import numpy as np


def dummy_pansharpen(xs, pan):
    xs_zoom = ndimage.zoom(xs, zoom=(1, 4, 4), order=0)

    total = sum(xs_zoom[i, :, :] for i in range(4))

    pxs = (xs_zoom / total) * pan
    return pxs


#### DO NO WORK ####
def rcs_pansharpen(xs, pan):
    """
    Implemented by me
    cf https://www.sfpt.fr/hyperspectral/wp-content/uploads/2018/01/May_panorama_pansharpening.pdf
    """
    print(0)
    xs_zoom = ndimage.zoom(xs, zoom=(1, 4, 4), order=0)
    print(1)
    pan_low_pass = ndimage.gaussian_filter(pan, sigma=1)
    print(2)

    pansharpened = xs_zoom * (pan / pan_low_pass)
    print(3)
    return pansharpened


## NOT USED ANYMORE (can not compare speed with OTB)
# functions
def stretch(bands, lower_percent=2, higher_percent=98):
    out = np.zeros_like(bands)
    for i in range(3):
        a = 0
        b = 255
        c = np.percentile(bands[:,:,i], lower_percent)
        d = np.percentile(bands[:,:,i], higher_percent)
        t = a + (bands[:,:,i] - c) * (b - a) / (d - c)
        t[t<a] = a
        t[t>b] = b
        out[:,:,i] =t
    return out.astype(np.uint8)

def pansharpen(m, pan, method='browley', W=0.1, all_data=False):

    # change convention of pan and ms
    pan = np.moveaxis(pan, 0, -1)
    m = np.moveaxis(m, 0, -1)


    # get m_bands
    rgbn = np.empty((m.shape[0], m.shape[1], 4))
    rgbn[:,:,0] = m[:,:, 0] # red
    rgbn[:,:,1] = m[:,:, 1] # green
    rgbn[:,:,2] = m[:,:, 2] # blue
    rgbn[:,:,3] = m[:,:, 3] # NIR-1

    # scaled them
    rgbn_scaled = np.empty((m.shape[0]*4, m.shape[1]*4, 4))

    for i in range(4):
        img = rgbn[:,:,i]
        scaled = rescale(img, (4,4))
        rgbn_scaled[:,:,i] = scaled

    # check size and crop for pan band
    if pan.shape[0] < rgbn_scaled.shape[0]:
        rgbn_scaled = rgbn_scaled[:pan.shape[0], :, :]
    else:
        pan = pan[:rgbn_scaled.shape[0], :, :]

    if pan.shape[1] < rgbn_scaled.shape[1]:
        rgbn_scaled = rgbn_scaled[:, :pan.shape[1], :]
    else:
        pan = pan[:, :rgbn_scaled.shape[1], :]

    R = rgbn_scaled[:, :, 0]
    G = rgbn_scaled[:, :, 1]
    B = rgbn_scaled[:, :, 2]
    I = rgbn_scaled[:, :, 3]

    image = None

    if method == 'simple_browley':
        all_in = R+G+B
        prod = np.multiply(all_in, pan)

        r = np.multiply(R, pan/all_in)[:, :, np.newaxis]
        g = np.multiply(G, pan/all_in)[:, :, np.newaxis]
        b = np.multiply(B, pan/all_in)[:, :, np.newaxis]

        image = np.concatenate([r,g,b], axis=2)

    if method == 'sample_mean':
        r = 0.5 * (R + pan)[:, :, np.newaxis]
        g = 0.5 * (G + pan)[:, :, np.newaxis]
        b = 0.5 * (B + pan)[:, :, np.newaxis]

        image = np.concatenate([r,g,b], axis=2)

    if method == 'esri':
        ADJ = pan-rgbn_scaled.mean(axis=2)
        r = (R + ADJ)[:, :, np.newaxis]
        g = (G + ADJ)[:, :, np.newaxis]
        b = (B + ADJ)[:, :, np.newaxis]
        i = (I + ADJ)[:, :, np.newaxis]

        image = np.concatenate([r,g,b,i], axis=2)

    if method == 'browley':
        print('pan', pan.shape)
        print('W', W)
        print('I', I.shape)
        print('R', R.shape)
        print('G', G.shape)
        print('B', B.shape)
        DNF = (np.squeeze(pan) - W*I)/(W*R+W*G+W*B)

        r = (R * DNF)[:, :, np.newaxis]
        g = (G * DNF)[:, :, np.newaxis]
        b = (B * DNF)[:, :, np.newaxis]
        i = (I * DNF)[:, :, np.newaxis]

        image = np.concatenate([r,g,b,i], axis=2)

    if method == 'hsv':
        hsv = color.rgb2hsv(rgbn_scaled[:,:,:3])
        hsv[:,:,2] = pan - I*W
        image = color.hsv2rgb(hsv)


    image = np.moveaxis(image, -1, 0)

    if all_data:
        return rgbn_scaled, image, I
    else:
        return image