Histogram Equalisation From Scratch in Python
What is Histogram?
It is a way to visually represent the distribution of a dataset by dividing it into equal intervals (or “bins”) and counting the number of data points that fall into each bin. The resulting bars in the histogram display the frequency of the data points that belong to each bin.
Histogram/Image Equalisation
Often images may be difficult for human observer to decipher due to the picture being, for example, too dark. It has been determined that humans can distinguish between 700 and 900 shades of grey under optimal viewing conditions, Although in very dark or bright sections of a image the just noticeable difference (JND) reduces significantly. However, it is also clear that it is easier for humans to distinguish larger differences.
So if the distribution of grey-scale in an image is improved, this facilitates better understandability by human observers. One technique for improving the distribution of grey-scale in an image is histogram equalisation.
This technique attempts to distribute the greyscale of an image evenly, so that the resulting histogram is almost flat, which results in increasing the contrast of the image.
So, you get the idea of what is it, now get into the implementation in python.
the steps are;
1. Find the histogram of the grayscale of the image
When equalising a colour image, we generally only equalise the luminance channel(gray scale) as otherwise the colours can become distorted. For that convert the RGB or CMY image into YUV or HSV image format.
In the YUV format Y channel is the luminance, U and V are chrominance. In HSV format V channel is the luminance others are Saturation and Hue.
image = cv2.imread("<path-to-img>")
image = cv2.cvtColor(image, cv2.COLOR_BGR2YUV)
hist, _ = np.histogram(luminance_channel.flatten(), 256, [0, 255])
2. Calculate the cumulative density function of the histogram
The algorithm is trying to effectively spreading out the number of intensities of each pixel value in the image almost evenly without removing the information containing the luminance.
Note: in the above plot of the cumulative density function is normalized between 0 and 10,000.
So, now if you ask me “ok, our goal is to try to equalize the number of pixels, but why do we have to calculate the cdf?”
It is to map new intensities to the image, which results in equalising the channel.
you will get clear understanding if you check out the below plots.
As you can see there are not that much number of pixels values between 40 and 65, so if we put almost same value(the cdf in that region) in that region then the pixels of those places will become almost same(according to the cdf) which will increase the contrast.
hist, _ = np.histogram(luminance_channel.flatten(), 256, [0, 255])
cdf = hist.cumsum()
3. Normalize the cumulative sum distribution between 0 and 255
When we map the intensitie of the cdf into the image, it is obvious that in a 8 bit image the minimum pixel value that can hold is 0 and maximum is 255, but the cumulative density function will be far bigger than that, so we gotta normalize it between 0 and 255.
cdf_normalized = ((cdf - cdf.min()) * 255) / (cdf.max() - cdf.min())
4. Map the intensities of the cumulative sum into the image
# NOTE: cdf_normalized is a np.ndarray
channel_result = cdf_normalized[luminance_channel.flatten()]
channel_result = np.reshape(channel_result, luminance_channel.shape)
The complete code,
Limitations of Global Histogram Equalization
If an image contains multiple varying image brightnesses, then this method won’t work as expected, in those cases you can use Adaptive Histogram Equlization or Contrast Limited Adaptive Histogram Equlization(CLAHE).
Conclusion
I hope you now have a clear understanding of Histogram Equalization Algorithm.
When you work on real-world projects you don’t have to do all this struggle, you can use libraries such as OpenCV for your needs. In Python using OpenCV, you can perform the Histogram Equlisation as below,
import cv2
img = cv2.imread("<path-to-img>")
result = cv2.equalizeHist(img)
If this article helps you in any way, i really appreciate if you could support me through BuyMeACoffee, it really motivates me to produce amazing articles for you guys 🥰.