Image Histogram and Histogram Equalization
Image historgram represents the intensity distribution of an image. X-axis stands for intensity, Y-axis for the number of pixels. Histogram equalization is a method in image processing of contrast adjustment using the image’s histogram 1. It stretches out the intensity range of the image.
Use HSV
Hue saturation value (HSV) color scale is used to process the intensity separately and to focus on value channel. Thus, I changed the image from BGR to HSV first, and equalized the histogram on value channel only, and finally converted the image from HSV to RGB.
# preprocess the image 
backyard = cv2.imread(F'/content/gdrive/My Drive/Colab Notebooks/ComputerVision/beach.jpg')
backyard_rgb = cv2.cvtColor(backyard, cv2.COLOR_BGR2RGB) # BGR -> RGB
backyard_hsv = cv2.cvtColor(backyard, cv2.COLOR_BGR2HSV) # BGR -> HSV
Images before and after equalization
First image is A kid on the beach. After the equalization, overall image got darker, and color contrast enhanced (i.e. swimsuit and sand volcanoes)
# Equlize Hitogram
backyard_hsv[:,:,2] = cv2.equalizeHist(backyard_hsv[:,:,2]) # equalization
backyard_eq_color = cv2.cvtColor(backyard_hsv, cv2.COLOR_HSV2RGB) # HSV -> RGB
display_side(backyard_rgb, backyard_eq_color)
# function to display two images side by side
# for grey scale, make sure to set cmap to Greys or Greys_r 
def display_side(img1, img2, cmap_input=None):
    fig = plt.figure(figsize=(12, 10))
    ax=fig.add_subplot(121)
    ax.imshow(img1, cmap=cmap_input)
    ax=fig.add_subplot(122)
    ax.imshow(img2, cmap=cmap_input)
 
# draw histogram for the image 
color = {'b', 'g', 'r'}
plt.subplot(1,2,1)
for i, col in enumerate(color):
    histr = cv2.calcHist([backyard], [i], None, [256], [0,256])
    plt.plot(histr,color=col)
plt.title('Histogram Before Equalization')
color = {'r', 'g', 'b'}
plt.subplot(1,2,2)
for i, col in enumerate(color):
    histr = cv2.calcHist([backyard_eq_color], [i], None, [256], [0,256])
    plt.plot(histr,color=col)
plt.title('Histogram after Equalization')
plt.tight_layout()
 
It works better with a greyscale image such as x-rays.
# preprocess the image 
x_ray = cv2.imread(F'/content/gdrive/My Drive/Colab Notebooks/ComputerVision/x-ray.jpg')
x_ray_grey = cv2.cvtColor(backyard, cv2.COLOR_BGR2GRAY) # BGR -> GRAY
# focus on value channel
xray_eq = cv2.equalizeHist(x_ray_grey) # equalization
display_side(x_ray, xray_eq, "Greys_r")
display_side(x_ray_grey, xray_eq, "Greys_r")
 
# draw histogram for grey image 
color = {'b', 'g', 'r'}
plt.subplot(1,2,1)
histr = cv2.calcHist(x_ray_grey, [0], None, [256], [0,256])
plt.title('Histogram Before Equalization')
plt.plot(histr)
plt.subplot(1,2,2)
histr = cv2.calcHist(xray_eq, [0], None, [256], [0,256])
plt.title('Histogram After Equalization')
plt.plot(histr)
plt.tight_layout()
