<jupyter_start><jupyter_text>Bilateral Histogram Equalization  1. Import useful libraries and open the sample image<jupyter_code>import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

hdr_img = cv.imread("image/image.tif", -1)
cv.imshow('TiffExemple',hdr_img)
cv.waitKey(0)
cv.destroyAllWindows()<jupyter_output><empty_output><jupyter_text>2. Show histogram of the sample HDR image<jupyter_code>max_bit = 2**16
hist,bins = np.histogram(hdr_img.flatten(),max_bit,[0,max_bit])
print(bins)
print(len(bins))
cdf = hist.cumsum()
cdf_normalized = cdf * float(hist.max()) / cdf.max()
plt.plot(cdf_normalized, color = 'b')
plt.hist(hdr_img.flatten(),max_bit,[0,max_bit], color = 'r')
plt.xlim([0,max_bit])
plt.legend(('cdf','histogram'), loc = 'upper left')
plt.show()<jupyter_output>[0.0000e+00 1.0000e+00 2.0000e+00 ... 6.5534e+04 6.5535e+04 6.5536e+04]
65537<jupyter_text>3. Streched sample histogram  3.1 Show the resulting image from the stretching operation<jupyter_code>cdf_m = np.ma.masked_equal(cdf,0)
cdf_m = (cdf_m - cdf_m.min())*max_bit/(cdf_m.max()-cdf_m.min())
cdf = np.ma.filled(cdf_m,0).astype('uint16')

img_stretch = cdf[hdr_img]

cv.imshow('TiffStretchExemple',img_stretch)
cv.waitKey(0)
cv.destroyAllWindows()<jupyter_output><empty_output><jupyter_text>3.2 Plot the streched histogram<jupyter_code>max_bit = 2**16
hist,bins = np.histogram(img_stretch.flatten(),max_bit,[0,max_bit])


cdf = hist.cumsum()
cdf_normalized = cdf * float(hist.max()) / cdf.max()
plt.plot(cdf_normalized, color = 'b')
plt.hist(img_stretch.flatten(),max_bit,[0,max_bit], color = 'r')
plt.xlim([0,max_bit])
plt.legend(('cdf','histogram'), loc = 'upper left')
plt.show()<jupyter_output><empty_output><jupyter_text>4. Toolbox to get weight maps, slices and fusion<jupyter_code>from Bilateral_histogram_equalisation import showImageHDR
from typing import List

def getSlices(hdr_img: np.array, bins: int) -> List[np.ndarray]:
    """Cut image into equal sized bins.
    Args:
        hdr_img (np.ndarray): HDR image array.
        bins (int): Number of desired bins.

    Returns:
        List[nd.array]: List of image slices array.
    """
    M, N = hdr_img.shape
    x = np.linspace(0,M*N, bins)
    sk = []
    for i in range(bins-1):
        null_compare = hdr_img[:,:] >= x[i+1]
        if i > 0: 
            slice = (hdr_img - x[i]) / (x[i+1] - x[i])
            slice = slice*null_compare
            m, n = np.where(hdr_img >= x[i])
            slice[m,n] = hdr_img[m, n]
        else:
            slice = hdr_img
        sk.append(slice)
    return sk

def getWeightMap(hdr_img: np.array, bins: int) -> List[np.ndarray]:
    """Find the best candidate for the weight map wk.
    Args:
        hdr_img (np.ndarray): HDR image array.
        bins (int): Number of desired bins.

    Returns:
        List[np.ndarray]: List of weight maps array.
    """
    M, N = hdr_img.shape
    x = np.linspace(0, M*N, bins) 
    wk = []
    for i in range(bins -1):
        one_compare = hdr_img[:,:] <= x[i]
        null_compare = hdr_img[:,:] >= x[i+1]
        other_compare = (~ one_compare)*(~ null_compare)
        ik = other_compare*hdr_img
        wk.append(ik)
    return wk

def fusion(weightMap: List[np.ndarray], slices: List[np.ndarray], bins: int) -> np.ndarray: 
    """Fusion of two given array is based on the sum of their product.
    Args:
        weightMap (List[np.ndarray]): Weightmap array.
        slices (List[np.ndarray]): Slices array.
        bins (int): Number of desired bins.

    Returns:
        np.ndarray: Fusioned weightmap and slices array.
    """
    output = []
    for i in range(bins -1):
        output.append(weightMap[i] @ slices[i])
    result = output[0]
    for i in range(1, bins -1):
        result += output[i].astype('uint16')
    showImageHDR(result)
    return result<jupyter_output><empty_output><jupyter_text>5. Get slices and weigth maps then fusion both array to show the final result<jupyter_code>sk = getSlices(hdr_img, bins=30)
wk = getWeightMap(hdr_img, bins=30)
fusion(wk, sk, bins=30)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.14422369389256806, 'fraction_numerical': 0.0235467255334805, 'mean_word_length': 3.6712485681557845, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '142106', 'license': 'MIT', 'n_tokens_mistral': 1648, 'n_tokens_neox': 1534, 'n_words': 345, 'path': 'BilateralHistogramEqualization.ipynb', 'repo_name': 'MNiko97/BilateralHistogramEqualization', 'size': '4077'}