OpenCV Histogram Equalization

Goal:
Learning the concept of histogram equailze and how to use it to improve the contrast of pictures


Theory:
If most of the pixel values in an images are concentrated in one pixel range.For example, if a picture is bright as a whole, all pixels should be very high, but the pixel value distribution of a high quality image should be very wide.So we should horizontally stretch the histogram.
In general,this operation will improve the contrast of the image.
OpenCV Histogram Equalization_第1张图片
First we use Numpy for histogram equlaization, and then learn how to use OpenCV for it.


Numpy

# -*- coding: utf-8 -*-
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('wiki.jpg',0)
# flatten() Change to one-dimensional array
hist,bins = np.histogram(img.flatten(),256,[0,256])
# Calculate cumulative distribution
cdf = hist.cumsum()  # accumulation
cdf_normalized = cdf * hist.max()/ cdf.max()  # normalized
plt.plot(cdf_normalized, color = 'b')
plt.hist(img.flatten(),256,[0,256], color = 'r')
plt.xlim([0,256])
plt.legend(('cdf','histogram'), loc = 'upper left')
plt.show()

OpenCV Histogram Equalization_第2张图片
We can see that most of the higher gray value is very concentrated.
However, we hope that the histogram distribution is relatively scattered and can cover the whole x-axis.So, we need a transform function to help us map the current histogram to a widely distributed histogram.
Now we need to find the minimum value in the histogram (except 0), and use it in the histogram equalization formula in this picture.We used numpy’s mask array, all operations on mask arrays are only valid for non-masked elements.

# -*- coding: utf-8 -*-
import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('wiki.jpg',0)
# flatten() Change to one-dimensional array
hist,bins = np.histogram(img.flatten(),256,[0,256])
# Calculate cumulative distribution
cdf = hist.cumsum()  # accumulation
# create Numpy Mask array. CDF is the original array,If the array element is 0.Calculation ignored
cdf_m = np.ma.masked_equal(cdf,0)
cdf_m = (cdf_m - cdf_m.min())*255/(cdf_m.max()-cdf_m.min())
# Masked elements is 0
cdf = np.ma.filled(cdf_m,0).astype('uint8')
# Apply this transformation to the image
img2 = cdf[img]
hist1,bins = np.histogram(img2.flatten(),256,[0,256])
cdf2 = hist1.cumsum()  # accumulation
cdf_normalized = cdf2 * hist.max()/ cdf2.max()  # normalized
plt.plot(cdf_normalized, color = 'b')
plt.hist(img2.flatten(),256,[0,256], color = 'r')
plt.xlim([0,256])
plt.legend(('cdf','histogram'), loc = 'upper left')
plt.show()

OpenCV Histogram Equalization_第3张图片
The important feature is that even if our input image is a darker image, we can get the same result after histogram equalization.Therefore, histogram equalization is often used as a reference tool to judge that the image has the same brightness.


OpenCV

The histogram equalization function in OpenCV is cv2. cv2.equalizeHist(),Input image of this function is only a gray image, and the result is the balanced image.

import cv2
import numpy as np

img = cv2.imread('wiki.jpg',0)
equ = cv2.equalizeHist(img)
res = np.hstack((img,equ))
#stacking images side-by-side
cv2.imshow('res.png',res)
cv2.waitKey(-1)

OpenCV Histogram Equalization_第4张图片
Histogram equalization is very useful when the data in histogram is concentrated in a certain range.
However, if the pixel changes greatly and occupies a very wide range, it will not change much.


CLAHE
Adaptive histogram equalization: The image will be divided into many pieces, which are called “tiles”(The default size of tiles in OpenCV is 8x8), and equalize each block. The histogram will be concentrated in a small area.

import cv2

img = cv2.imread('tsukuba_l.png',0)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
cl1 = clahe.apply(img)
cv2.imshow('img',cl1)
cv2.waitKey(0)

OpenCV Histogram Equalization_第5张图片

你可能感兴趣的:(计算机视觉)