本文介紹了python OpenCV學習筆記之直方圖均衡化,分享給大家,具體如下:
官方文檔 – https://docs.opencv.org/3.4.0/d5/daf/tutorial_py_histogram_equalization.html
考慮一個圖像,其像素值僅限制在特定的值范圍內。例如,更明亮的圖像將使所有像素都限制在高值中。但是一個好的圖像會有來自圖像的所有區域的像素。所以你需要把這個直方圖拉伸到兩端(如下圖所給出的),這就是直方圖均衡的作用(用簡單的話說)。這通常會改善圖像的對比度。
建議閱讀關于直方圖均衡的wikipedia頁面Histogram Equalization,了解更多有關它的詳細信息。它給出了一個很好的解釋,給出了一些例子,這樣你就能在讀完之后理解所有的東西。同樣,我們將看到它的Numpy實現。之后,我們將看到OpenCV函數。
import numpy as npimport cv2 as cvfrom matplotlib import pyplot as pltimg = cv.imread('wiki.jpg', 0)hist, bins = np.histogram(img.flatten(), 256, [0,256])cdf = hist.cumsum()cdf_normalized = cdf*float(hist.max())/cdf.max()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()
你可以看到,直方圖位于更亮的區域。我們需要完整的頻譜。為此,我們需要一個轉換函數,它將更亮區域的輸入像素映射到全區域的輸出像素。這就是直方圖均衡所做的。
現在我們找到了最小的直方圖值(不包括0),并應用了在wiki頁面中給出的直方圖均衡等式。但我用在Numpy的遮罩數組的概念數組上。對于遮罩數組,所有操作都是在非遮罩元素上執行的。
cdf_m = np.ma.masked_equal(cdf, 0)cdf_m = (cdf_m-cdf_m.min()) * 255 / (cdf_m.max()-cdf_m.min())cdf = np.ma.filled(cdf_m, 0).astype('uint8')現在我們有了一個查找表,它提供了關于每個輸入像素值的輸出像素值的信息。所以我們只要應用變換。
img2 = cdf[img]
現在我們計算它的直方圖和cdf,就像之前一樣,結果如下:

另一個重要的特征是,即使圖像是一個較暗的圖像(而不是我們使用的更亮的圖像),在均衡之后,我們將得到幾乎相同的圖像。因此,它被用作一種“參考工具”,使所有的圖像都具有相同的光照條件。這在很多情況下都很有用。例如,在人臉識別中,在對人臉數據進行訓練之前,人臉的圖像是均勻的,使它們具有相同的光照條件。
OpenCV中的直方圖均衡化
新聞熱點
疑難解答