I am trying to implement CLAHE(contrast-limited adaptive histogram equalization) algorithm using python3, numpy and cv2. I am using the slower non-interpolation method. Just dividing image to tiles and trying to equalize histograms of sub-images to enhance contrast. But the output is is very weird. I looked up some github repo's and find one which my histogram and clipped_histogram_equaliziation method is same with that methods from the repo.
Repo link: https://github.com/asalmada/x-ray-images-enhancement/blob/master/src/algorithms/clahe.py
Below you can see my code, cv2 output and my output. I spent hours and I can't see what I am missing
def clahe(img, tile_size: int = 8, clip_limit: int = 40):
width = img.shape[1]
height = img.shape[0]
padding_size = tile_size // 2
padded_img = padding(img, padding_size)
p_width, p_height = padded_img.shape[1], padded_img.shape[0]
clahed_img = np.zeros((p_height, p_width), 'uint8')
for i in range(padding_size, p_height - padding_size):
for j in range(padding_size, p_width - padding_size):
tile = padded_img[i-padding_size:i +
padding_size, j-padding_size:j+padding_size]
hist = clipped_histogram_equalization(tile, 255, clip_limit=40)
clahed_img[i][j] = hist[padded_img[i][j]]
enhanced_img = clahed_img[padding_size:p_height -
padding_size, padding_size:p_width - padding_size].astype(np.uint8)
return enhanced_img
def histogram(data):
pixels, count = np.unique(data, return_counts=True)
hist = col.OrderedDict()
for i in range(len(pixels)):
hist[pixels[i]] = count[i]
return np.array(list(hist.values())), np.array(list(hist.keys()))
def clipped_histogram_equalization(region, max_val, clip_limit):
hist, bins = histogram(region)
n_bins = len(bins)
# Removing values above clip_limit
excess = 0
for i in range(n_bins):
if hist[i] > clip_limit:
excess += hist[i] - clip_limit
hist[i] = clip_limit
## Redistributing exceding values ##
# Calculating the values to be put on all bins
for_each_bin = excess // n_bins
# Calculating the values left
leftover = excess % n_bins
hist += for_each_bin
for i in range(leftover):
hist[i] += 1
# Calculating probability for each pixel
pixel_probability = hist / hist.sum()
# Calculating the CDF (Cumulative Distribution Function)
cdf = np.cumsum(pixel_probability)
cdf_normalized = cdf * 255
hist_eq = {}
for i in range(len(cdf)):
hist_eq[bins[i]] = round(cdf_normalized[i])
return hist_eq
And here is my main method:
img = cv.imread("test6.jpg", 0)
enhanced_img = clahe(img)
cv.imshow("Image after CLAHE", enhanced_img)