I am trying to implement image enhancement by first converting RGB color space to HSI color space, do histogram equalization on intensity channel, and convert back to RGB color space.
However, the output image does not look good and I could not figure out why. Please help me.
My RGB HSI conversion method is based on this website : https://hypjudy.github.io/2017/03/19/dip-histogram-equalization/
My input image :enter image description here My output image : enter image description here
import cv2
from math import acos
from math import cos
from math import sqrt
from math import pi
# Read the bmp file
img = cv2.imread('/Users/xxx/xxx/input3.bmp')
# Read the width and height of the image
shape = img.shape
# HSI array to store original histogram
H_origin_hist = [[0 for i in range(0, shape[1])] for j in range(0, shape[0])]
S_origin_hist = [[0 for i in range(0, shape[1])] for j in range(0, shape[0])]
I_origin_hist = [0] * 256
I_hist = [0] * 256
# Convert colors from RGB to HSI and calculate histogram
for i in range(0, shape[0]) :
for j in range(0, shape[1]) :
# px[0], px[1], and px[2] represents B, G, and R respectively
px = img[i,j]
R = int(px[2])
G = int(px[1])
B = int(px[0])
# Calculate HSI original histogram
numerator = float(0.5 * ((R - G) + (R - B)))
denominator = float(sqrt((R - G) * (R - G) + (R - B) * (G - B)))
if (denominator == 0) :
val = 0.0
else :
val = numerator / denominator
theta = acos(val)
I = (B + G + R) / 3
if (B <= G) :
H_origin_hist[i][j]= theta
else :
H_origin_hist[i][j] = 2 * pi - theta
if(R == 0 or G == 0 or B == 0) :
S_origin_hist[i][j] = 0
H_origin_hist[i][j] = 0
else :
S_origin_hist[i][j] = 1 - (3.0 / (R + G + B) * min(R, G, B))
I_origin_hist[I] = I_origin_hist[I] + 1
# Do histogram equalization on the intensity channel
for i in range(0, 256) :
I_hist[i] = ((sum(I_origin_hist[0:i+1]) - min(I_origin_hist)) * 255) / (shape[0] * shape[1])
# Convert colors from HSI to RGB
for i in range(0, shape[0]) :
for j in range(0, shape[1]) :
px = img[i,j]
R = int(px[2])
G = int(px[1])
B = int(px[0])
I = (R + G + B) / 3
if (H_origin_hist[i][j] >= 0 and H_origin_hist[i][j] < 2 * pi / 3) :
H = H_origin_hist[i][j]
h = ((pi / 3) - H_origin_hist[i][j])
px[0] = (1 - S_origin_hist[i][j]) * I_hist[I]
px[2] = (1 + (S_origin_hist[i][j] * cos(H) / cos(h))) * I_hist[I]
px[1] = 1 - B - R
elif (H_origin_hist[i][j] >= 2 * pi / 3 and H_origin_hist[i][j] < 4 * pi / 3) :
H = (H_origin_hist[i][j] - (2 * pi / 3))
h = (pi - H_origin_hist[i][j])
px[2] = (1 - S_origin_hist[i][j]) * I_hist[I]
px[1] = (1 + (S_origin_hist[i][j] * cos(H) / cos(h))) * I_hist[I]
px[0] = 1 - G - R
else :
H = (H_origin_hist[i][j] - (4 * pi / 3))
h = ((5 * pi / 6) - H_origin_hist[i][j])
px[1] = (1 - S_origin_hist[i][j]) * I_hist[I]
px[0] = (1 + (S_origin_hist[i][j] * cos(H) / cos(h))) * I_hist[I]
px[2] = 1 - B - G
# Write back to bmp file
cv2.imwrite('/Users/xxx/xxx/output3.bmp', img)