The intensity histogram of an image is the histogram of its pixels' intensities values. Typically the binning is given in such a way that each single intensity value is a bin, so we count the number of pixels with intensity value 0, the number of pixels with intensity value 1, ..., the number of pixels with intensity value 255.
The broader an intensity histogram is, the larger the contrast of the image is.
For the code in this part, you need to use OpenCV on top of some regular imports:
import cv2from matplotlib import pyplot as plt
We will read our sample image and then we'll plot its intensity histograms, both for the grayscale version and for the 3 channels of the coloured one. You will see that due to the large amount of red in the image, the RED channel has its peak at a high intensity, while the GREEN channel is really peaked at low intensity.
I will use a photo I've taken of some pens on a desk.
# First read an imageimage = cv2.imread('pens.jpg')# Transform into grayscale and into RGB (for Matplotlib)gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)RGB_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)# show them bothf, (ax1, ax2) = plt.subplots(1, 2, sharey=True)ax1.grid()ax1.imshow(RGB_image)plt.gray()ax2.grid()ax2.imshow(gray)plt.show();
Let's calculate and plot the intensity histogram of the grayscale image.
# Hist of the gray image: channel 0, no mask, 256 pixels, range (0, 256)gray_hist = cv2.calcHist([gray], , None, , (0, 256)) # the method can do multiple images at a time# Hists of the color image, each channel, same argsR_hist = cv2.calcHist([RGB_image], , None, , (0, 256))G_hist = cv2.calcHist([RGB_image], , None, , (0, 256))B_hist = cv2.calcHist([RGB_image], , None, , (0, 256))
# Plot of the grayscale image histplt.plot(hist, c='k')plt.title('Grayscale image intensity hist')plt.xlabel('Pixel value')plt.ylabel('Count')plt.show();
# Plot of the RGB image histsplt.plot(R_hist, c='r', label='RED channel')plt.plot(G_hist, c='g', label='GREEN channel')plt.plot(B_hist, c='b', label='BLUE channel')plt.title('Coloured image intensity histograms')plt.xlabel('Pixel value')plt.ylabel('Count')plt.legend()plt.show();
Given the intensity histogram (see page) of an image, the procedure of equalising it increases the contrast of the image (see page).
Equalisation maps the intensity histogram to a wider and more uniform distribution so that intensity values are more spread over (pixels are reassigned). The pixels of the image get reassigned in such a way that their distribution in the output image is nearer to a uniform distribution, through the use of a transfer function.
Using the grayscale image created above, we can run
# equalisegray_eq = cv2.equalizeHist(gray)
and we can plot them both, here they are:
Note that it generally not a good idea to apply histogram equalisation to the colour channel histograms, because that would change the balance of colours (unless this is desired, of course).