1. 影像直方圖
影像直方圖,是指對整個影像在灰度範圍內的畫素值(0-255)統計出現頻率次數,據此生成的直方圖,稱為影像直方圖或直方圖。直方圖反映了影像灰度的分佈情況,是影像的統計學特徵。也可以說,直方圖是影像中畫素強度分佈的圖形表達方式,它統計了每一個強度值所具有的畫素個數。
2. 直方圖均衡化
直方圖均衡化是以累計分佈函式為核心,將原始影像灰度直方圖從比較集中的某個灰度區間,非線性地對映為在全部灰度範圍內的較均勻分佈,從而增強對比度。
直方圖均衡化的數學原理如下:
首先作原始影像灰度的機率直方圖, 然後設輸入畫素灰度值為rk,累計分佈函式為
其中ni為影像中灰度值為ri的畫素頻數,n為影像畫素總數。設輸出畫素灰度值為sk,畫素範圍為smin-smax。期望輸出灰度直方圖是均勻分佈,即
令C(sk)=C(rk),即得
所以最終直方圖均衡化的點運算元為
3. 直方圖均衡化的Python實現
根據直方圖均衡化的數學原理,用Python實現程式碼如下:
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 計算累計分佈函式
def C(rk):
# 讀取圖片灰度直方圖
# bins為直方圖直方柱的取值向量,hist為bins各取值區間上的頻數取值
hist, bins = np.histogram(rk, 256, [0, 256])
# 計算累計分佈函式
return hist.cumsum()
# 計算灰度均衡化對映
def T(rk):
cdf = C(rk)
# 均衡化
cdf = (cdf - cdf.min()) * (255 - 0) / (cdf.max() - cdf.min()) + 0
#cdf = 255.0 * cdf / cdf[-1]
return cdf.astype('uint8')
# 讀取圖片
img = cv.imread('lenna.jpg', 0)
# 將二維數字影像矩陣轉變為一維向量
rk = img.flatten()
# 原始影像灰度直方圖
plt.hist(rk, 256, [0, 255], color = 'r')
# 直方圖均衡化
imgDst = T(rk)[img]
plt.hist(imgDst.flatten(), 256, [0, 255], color = 'b')
plt.legend(['Before Equalization','Equalization'])
plt.show()
# 展示前後對比影像
plt.subplot(121), plt.imshow(img, cmap='gray'), plt.title('Original Gray')
plt.subplot(122), plt.imshow(imgDst, cmap='gray'), plt.title('Histogram Equalization')
plt.show()
均衡前後影像灰度直方圖如下所示:
直方圖均衡化前後的影像對比如下所示:
4. opencv-python中直方圖均衡化的應用
opencv-python中使用cv.equalizeHist函式即可實現直方圖均衡化,其函式原型如下:
dst=cv.equalizeHist(src[, dst])
注意:輸入需是灰度影像。
測試程式碼如下:
img = cv.imread('lenna.jpg', 0)
dst = cv.equalizeHist(img)
plt.subplot(121), plt.imshow(img, cmap='gray'), plt.title('Original Gray'), plt.axis('off')
plt.subplot(122), plt.imshow(dst, cmap='gray'), plt.title('Histogram Equalization'), plt.axis('off')
plt.show()
效果如下: