Image Enhancement Part2 - Histogram Manipulation
Camera sensors are designed like the human eye. Both can focus the light and capture the image. However, given the light background, there are objects captured by the camera not visible to the naked eye. Having the image too bright can be classified as overexposed, while too dark images as underexposed. These image conditions can be subject to image enhancement in which a technique called Histogram Manipulation performs exceptionally well.
Let's take a look on a dark image to be enhanced and try to use white balancing method discussed previously. But before that. Let us load the required libraries such as numpy, matplotlib and skimage.
import numpy as np
import matplotlib.pyplot as plt
from skimage.io import imread, imshow
from skimage import img_as_ubyte, img_as_float
Let us load the image.
# load image
dark_image = imread('darkplants.jpg')
And... run the white balancing method relative to the max value.
There a slight improvement, but can we get more information out of this? Let's try using the Histogram Manipulation Method.
There are 3 qays of implementing the method.
Histogram Equalization
Other Histogram Manipulation Such as Gaussian distribution
Contrast stretching
The following additional libraries will be loaded in order to proceed. :
histogram and cummulative distribution from skimage.exposure for histogram and cdf
skimage.color rgb2gray to simplify sample by turning the image to grayscale.
scipy stats for statistics functions
import matplotlib.gridspec as gridspec
from skimage.exposure import histogram, cumulative_distribution
from skimage.color import rgb2gray
from scipy.stats import norm
import scipy.stats as stats
1. Histogram equalization
Since we are talking about histogram here. We'll check first on the dark image' histogram. So simplify the concept, the dark image will be converted to grayscale.
Looking on the distribution of pixels, it is shifted more on the lower intensity values which also describes why we have a dark image. The goal is to make the distribution uniform in order to balance the intensity. This can be done when the CDF plot (blue curve) of the image will be converted linearly, referring to the red line as the target.
To do this, we have to match the intensity value per percentile to the target CDF (red line). Say for example at 96th (96.12) percentile, we have the 50 as the intensity value, the value of target CDF should be around 244. By interpolation, we will replace all the intensity values having 50 with the target matched value 244.
The above code is only for the 96th percentile. Below shows the new values for the other percentile. We will use the numpy's One-dimensional linear interpolation - np.interp to interpolate the values of the freq to the target.
And Viola! the we have a clear image for the dark image.
Let's visit the new histogram of the new image. Adjusting the histogram and making the cdf plot linear by distributing the values across the percentile would yield a better exposure of the image.
2. Other Distribution - Gaussian Distribution
For some case, the target distribution to be uniform (linear) is not a requirement. Setting Gaussian distribution as the target allows varying intensity values which can make the output more natural.
3. Contrast stretching
In contrast to the above method, contrast stretching do not manipulate the image's intensity histogram. But instead, is to rescale the intensities only to those within a range of percentiles. skimage.exposure.rescale_intensity library is used for this.
That's it!.
On the next section, shows the images for the Histogram Manipulation for RGB.
Linear Interpolation
Normal Gaussian
Gamma Distribution
Beta Distribution
Summary of Comparison
Comments