Image Enhancement using Histogram Equalization

Developing Data Products Course Project - Coursera

Raymond Phan - Bubl Technology Inc.

Premise

  • Images with poor contrast are those that look too dark, too bright, or too washed out
  • By plotting histogram using intensity / colour channel as the bins, values have little spread
  • Histogram equalization: The histogram becomes flat and gives a better contrast image
  • The effect of histogram equalization is that it stretches the dynamic range of the histogram
  • Histograms can easily be converted into discrete PDFs. You assume that the probability of encountering a particular pixel is fair

Some Math (for grayscale images)!

  • Given the bin count \(h_i\) of an intensity \(i\) of an image, the probability of encountering this intensity \(i\) is: \(p_i = \frac{h_i}{MN}\) where \(M\),\(N\) are the number of rows and columns in the image
  • To do histogram equalization, you choose the desired intensity levels you want to see, \(L\)
  • Given \(L\), the output intensity \(g_i\), given an input intensity \(i\) is thus:

\[g_i = (L-1)\sum_{i=0}^{L-1} p_i = \frac{L-1}{MN} \sum_{i=0}^{L-1} h_i\]

  • The above produces a mapping where we take each pixel with an intensity \(i\) and determine what its output intensity is, \(g_i\)
  • The above sum may be familiar to you. We are essentially computing the CDF of the image
  • The above equation stretches the histogram so that encountering each pixel is equiprobable
  • By making each pixel equiprobable to be encountered, the best contrast is obtained
  • The math in proving the above is beyond the scope of this talk. Check this link out for the proof

Histogram Equalization Demonstration

  • Showing the original image
library(png); img <- readPNG('pout.png');
image(t(img)[,nrow(img):1], axes = FALSE, col = grey(seq(0, 1, length = 256)))

plot of chunk unnamed-chunk-1

Histogram Equalization Demonstration

  • Output with 256 intensities. Histogram Equalization source is long is on Github
source("histEq.R"); library(png); img <- readPNG('pout.png'); outImg <- histEq(img, 256)
image(t(outImg)[,nrow(outImg):1], axes = FALSE, col = grey(seq(0, 1, length = 256)))

plot of chunk unnamed-chunk-2