目錄
直方圖均衡就是讓圖像的像素個數多的灰度級拉的更寬,對像素個數少的灰度級進行壓縮,從而達到提高圖像的對比度的目的。從直方圖的直觀效果來看,就是讓y軸比較高的位置變矮向x軸方向膨脹,y軸比較矮的位置變高並在x軸方向壓縮。
1、直方圖均衡equalizeHist
equalizeHist()可以實現圖像的直方圖均衡,它是一種全局直方圖均衡,考量的對象是整幅圖像。
接口形式:
cv2.equalizeHist(src[, dst]) ->dst
- 參數含義:
- src:輸入圖像,8bit單通道;
- dst:均衡后的輸出圖像,類型同src;
下面這個例子讀入圖像后做直方圖均衡,然后對比其直方圖:
import numpy as np
import matplotlib.pyplot as plt
import cv2
print('VX公眾號: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)
plt.rc('font',family='Youyuan',size='9')
plt.rc('axes',unicode_minus='False')
img_src = cv2.imread('..\\samples\\data\\fruits.jpg',0)
img_dst = cv2.equalizeHist(img_src)
histSize = 512
histRange = (0, 256)
hist_src = cv2.calcHist([img_src], [0], None, [histSize], histRange)
hist_dst = cv2.calcHist([img_dst], [0], None, [histSize], histRange)
#顯示圖像
fig,ax = plt.subplots(2,2)
ax[0,0].set_title('hist_src')
ax[0,0].plot(hist_src)
ax[0,1].set_title('hist_dst')
ax[0,1].plot(hist_dst)
ax[1,0].set_title('src')
ax[1,0].imshow(cv2.cvtColor( img_src, cv2.COLOR_BGR2RGB),'gray')
ax[1,1].set_title('dst')
ax[1,1].imshow(cv2.cvtColor(img_dst,cv2.COLOR_BGR2RGB),'gray')
#ax[0,0].axis('off');ax[0,1].axis('off');
ax[1,0].axis('off');ax[1,1].axis('off')#關閉坐標軸顯示
plt.show()
運行結果:
從運行結果看,原來整體較暗的圖像,經過直方圖均衡后,整體要亮一些。這點也和直方圖顯示的效果是一樣的,原圖的直方圖整體要偏左,而經過直方圖均衡后的直方圖在x軸上分布更均勻。
2、自適應直方圖均衡createCLAHE
equalizeHist()方法是一種全局直方圖均衡方法,在某些場合可能會導致原本對比度高的區域反而變得更低,像下面這個例子中原圖上半部分的樹葉對比度高,但是下半部分對比度低,如果使用equalizeHist()方法得到的圖片如下圖右下部分所示:

直方圖均衡處理后雖然樹葉下半部分的細節都呈現出來了 ,但是上半部分卻因為過亮導致丟失了很多細節。
CLAHE是對比度抑制自適應直方圖均衡(Contrast Limited Adaptive Histogram Equalization)的簡稱,不同於普通的直方圖均衡,它是一種局部直方圖均衡方法。
調用接口分2步,先創建實例,再調用apply()方法:
cv2.createCLAHE([, clipLimit[, tileGridSize]]) ->retval
dst=retval.apply(src)
- 參數含義:
- clipLimit:對比對限制閾值,默認為40;
- tileGridSize:直方圖均衡的柵格尺寸,輸入圖像將會按照該尺寸分隔后進行局部直方圖均衡,默認是8×8大小;
- src:輸入圖像,8bit單通道;
- dst:均衡后的輸出圖像,類型同src;
下面這個例子將普通直方圖均衡和自適應直方圖均衡做對比:
import numpy as np
import matplotlib.pyplot as plt
import cv2
print('VX公眾號: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)
plt.rc('font',family='Youyuan',size='9')
plt.rc('axes',unicode_minus='False')
img_src = cv2.imread('..\\samples\\picture\\leaf2.jpeg',0)
#普通直方圖均衡
img_dst = cv2.equalizeHist(img_src)
#自適應直方圖均衡
clahe = cv2.createCLAHE(clipLimit=5.0, tileGridSize=(8,8))
img_dst_clahe = clahe.apply(img_src)
histSize = 256
histRange = (0, 256)
hist_src = cv2.calcHist([img_src], [0], None, [histSize], histRange)
hist_dst = cv2.calcHist([img_dst], [0], None, [histSize], histRange)
hist_dst_clahe = cv2.calcHist([img_dst_clahe], [0], None, [histSize], histRange)
#顯示圖像
fig,ax = plt.subplots(2,3)
ax[0,0].set_title('hist_src')
ax[0,0].plot(hist_src)
ax[0,1].set_title('hist_dst')
ax[0,1].plot(hist_dst)
ax[0,2].set_title('hist_dst_clahe')
ax[0,2].plot(hist_dst_clahe)
ax[1,0].set_title('img_src')
ax[1,0].imshow(cv2.cvtColor( img_src, cv2.COLOR_BGR2RGB),'gray')
ax[1,1].set_title('img_dst')
ax[1,1].imshow(cv2.cvtColor(img_dst,cv2.COLOR_BGR2RGB),'gray')
ax[1,2].set_title('img_dst_clahe')
ax[1,2].imshow(cv2.cvtColor(img_dst_clahe,cv2.COLOR_BGR2RGB),'gray')
#ax[0,0].axis('off');ax[0,1].axis('off');
ax[1,0].axis('off');ax[1,1].axis('off');ax[1,2].axis('off')#關閉坐標軸顯示
plt.show()
運行結果:
從運行結果可以看到,使用自適應直方圖均衡后,不但樹葉下半部分的細節呈現出來了 ,而且上半部分的細節也得到了保留。