Histogram Equalization — a simple way to improve the contrast of your image
source link: https://www.tuicool.com/articles/nyIJVbZ
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Histogram Equalization — a simple way to improve the contrast of your image
Oct 25 ·3min read
I learnt about histogram equalization from Professor Shilkrot in my Computer Vision class at Stony Brook University. This is a very simple concept and takes few lines of code to realize.
What do you think a histogram representation of an image look like? Something like the red plot on the left? YES!
(a) input image and its histogram
We see from the plot above that the histogram lies in brighter region in (a). But, if we need a uniform distribution of the brightness, we are going to need a transformation function which maps the input pixels in brighter region to output pixels in full region. That is what histogram equalization does. It enhances the contrast of the image. The resultant image from histogram equalization can be seen on the right in (b).
(b) resulting image post histogram equalization technique
## code to plot histogram in pythonimport numpy as np import cv2 from matplotlib import pyplot as pltimg = cv2.imread('Chatth_Puja_Bihar_India.jpeg',0) hist,bins = np.histogram(img.flatten(),256,[0,256]) plt.hist(img.flatten(),256,[0,256], color = 'r') plt.xlim([0,256]) plt.show()
We can do this in OpenCV using a function cv2.equalizeHist() . If its input is just grayscale image, then output is our histogram equalized image. If it is colored (RGB) image, we can segregate all three different streams — red, green, blue; call cv2.equalizeHist() individually on these channels and finally merge back, as shown in the code below. I am also providing code through numpy arrays for better comprehension.
def histogram_equalization(img_in):# segregate color streams b,g,r = cv2.split(img_in) h_b, bin_b = np.histogram(b.flatten(), 256, [0, 256]) h_g, bin_g = np.histogram(g.flatten(), 256, [0, 256]) h_r, bin_r = np.histogram(r.flatten(), 256, [0, 256])# calculate cdf cdf_b = np.cumsum(h_b) cdf_g = np.cumsum(h_g) cdf_r = np.cumsum(h_r) # mask all pixels with value=0 and replace it with mean of the pixel values cdf_m_b = np.ma.masked_equal(cdf_b,0) cdf_m_b = (cdf_m_b - cdf_m_b.min())*255/(cdf_m_b.max()-cdf_m_b.min()) cdf_final_b = np.ma.filled(cdf_m_b,0).astype('uint8') cdf_m_g = np.ma.masked_equal(cdf_g,0) cdf_m_g = (cdf_m_g - cdf_m_g.min())*255/(cdf_m_g.max()-cdf_m_g.min()) cdf_final_g = np.ma.filled(cdf_m_g,0).astype('uint8')cdf_m_r = np.ma.masked_equal(cdf_r,0) cdf_m_r = (cdf_m_r - cdf_m_r.min())*255/(cdf_m_r.max()-cdf_m_r.min()) cdf_final_r = np.ma.filled(cdf_m_r,0).astype('uint8')# merge the images in the three channels img_b = cdf_final_b[b] img_g = cdf_final_g[g] img_r = cdf_final_r[r] img_out = cv2.merge((img_b, img_g, img_r))# validation equ_b = cv2.equalizeHist(b) equ_g = cv2.equalizeHist(g) equ_r = cv2.equalizeHist(r) equ = cv2.merge((equ_b, equ_g, equ_r)) #print(equ) #cv2.imwrite('output_name.png', equ)return img_out
Applications
- You can use histogram equalization to improve the lighting of any low contrast image.
- In face recognition techniques, before training the face data, the images of faces are histogram equalized to make them all with same lighting conditions.
Bonus
For starters, convert an image to gray and black & white using the following code.
import cv2 originalImage = cv2.imread('avalon_lake.jpeg') grayImage = cv2.cvtColor(originalImage, cv2.COLOR_BGR2GRAY) (thresh, blackAndWhiteImage) = cv2.threshold(grayImage, 127, 255, cv2.THRESH_BINARY)cv2.imwrite('blackAndWhiteImage.png', blackAndWhiteImage) cv2.imwrite('grayImage.png', grayImage)
Original -> Gray -> BW
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK