Histograms in Image Processing

Deepanshusachdeva
4 min readMay 8, 2021

Hello everyone!

If you are new to computer vision you must have faced some difficulty when the image contrast is not ideal or some information is not clearly visible!

Histogram equalization provides a solution to this problem, just applying this technique to your input data improves the performance of your machine learning model.

So , lets start!

What is Image Histogram?

In simple words it is nothing but the count of pixel intensities in an image. Lets say this is the image given to you

Input Image

Implementation in Python

Now, we lets say we need to plot the image histogram for this image.
For this OpenCV provides cv2.calcHist function to calculate the histogram of the image. This function takes four arguments namely:

hist = cv2.calcHist([images], [channels], mask, [hist size], range of pixel intensity)

in cv2.calcHist , first argument is the source image of type uint8 or float32.
second argument is the index of channel for which we have to calculate histogram , example : if it is a grayscale image, its value is [0] , otherwise give [0] , [1] or [2] for the respective B , G and R channel of the image.
third argument is given as None if you want to calculate histogram of the full image otherwise give the mask for region in the argument.
fourth argument is the bin count of the histogram.
fifth argument is the range of pixel intensities of the given image.

Now, applying this function to our input image after gray scaling we get,

import cv2
import matplotlib.pyplot as plt
image = cv2.imread('sample_image.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
hist = cv2.calcHist([gray], [0], None, [256], [0, 256])
plt.figure()
plt.xlabel('bins')
plt.ylabel('# No of pixels')
plt.plot(hist)
plt.xlim([0, 256])
plt.show()

Let’s understand this plot, if you look into the plot you will see that most of the pixels(y values) are mostly in the range of 50–150 or there are much more pixels with intensity in 0- 100 then between 200–250.

Now , the same thing can be applied with the help of Numpy only difference will be that it will return 257 bins.
Let’s take a look,

hist,bins = np.histogram(gray.ravel(),256,[0,256])

Now , lets take a quick look at b , g and r channels of the histogram.

image = cv2.imread(args['image'])
(b, g, r) = cv2.split(image)
#calculate histograms separately of B , G and R channel
hist_b = cv2.calcHist([b], [0], None, [256], [0, 256])
hist_g = cv2.calcHist([g], [0], None, [256], [0, 256])
hist_r = cv2.calcHist([r], [0], None, [256], [0, 256])
plt.figure
plt.title('color_histograms')
plt.xlabel('bins')
plt.ylabel('# of pixels')
plt.plot(hist_b, color='b')
plt.plot(hist_g, color='g')
plt.plot(hist_r, color='r')
plt.show()

This produced the following result,

Here, the pixel intensities of Blue , Green and Red are shown , you can infer the results as we did before.

Now all these were one dimensional Histograms , what if we want to visualize a Two dimensional Histogram ?

we just need to tweak some parameters, like:

plt.figure()
plt.title('2D histogram of blue and green')
hist = cv2.calcHist([b, g], [0, 1], None, [32, 32], [0, 256, 0, 256])
plt.imshow(hist)
plt.colorbar()

Now, cv2.calcHist will return a numpy array of shape (32,32) which will record the intensities of blue and green channels together and using the plot’s color bar we can visualize what color combination was recorded how many times.

So, this is your 2D histogram of Blue and Green channel , you can also visualize different combinations as per your need!

With this we end this tutorial and up next we will see how histogram equalization works and why it is so important in Image Processing.

References:

--

--