OpenCV-Python教程:24.histogram-2:histogram均衡

理論:

一張像素值被限制在一個(gè)特定值范圍內(nèi)的圖像,比如,亮圖被限制所有像素都是亮值。但是一個(gè)好的圖片應(yīng)該是有所有范圍的像素。所以我們需要把histogram拉伸到兩端,這就是histogram均衡。這個(gè)一般是用來(lái)提升圖片的對(duì)比度。

我會(huì)建議你閱讀wikipedia


http://en.wikipedia.org/wiki/Histogram_equalization


我們這里看Numpy的實(shí)現(xiàn),之后,會(huì)看OpenCV的函數(shù)。

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('wiki.jpg',0)

hist,bins = np.histogram(img.flatten(),256,[0,256])

cdf = hist.cumsum()
cdf_normalized = cdf * 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()

你可以看到histogram在高亮區(qū)域,我們需要全范圍的,為了這個(gè)目的,我們需要一個(gè)轉(zhuǎn)換函數(shù)來(lái)把高亮區(qū)的像素映射到全范圍的像素。這就是histogram均衡做的。

現(xiàn)在我們找到了最小的histogram值然后應(yīng)用histogram均衡。但是我這里用的masked數(shù)組,所有的運(yùn)算時(shí)在非掩的元素上的

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')

現(xiàn)在我們有了查詢表可以給我們對(duì)于每個(gè)輸入像素值得對(duì)應(yīng)輸出像素值。然后我們應(yīng)用這個(gè)轉(zhuǎn)換。

img2=cdf[img]

現(xiàn)在我們計(jì)算它的histogram

另一個(gè)信息是即使如果圖像是個(gè)暗圖,當(dāng)均衡之后我們會(huì)得到和之前那次幾乎一樣的圖片,所以這個(gè)可以用來(lái)讓所有圖片擁有同樣的亮度。在面部識(shí)別里,在訓(xùn)練面部數(shù)據(jù)之前,面部的圖片會(huì)做histogram均衡以讓他們所有都是同樣的亮度條件。

OpenCV里的Histograms均衡

OpenCV有一個(gè)函數(shù)可以做這個(gè),cv2.equalizeHist()。它的輸入是灰度圖像,輸出時(shí)我們的histogram均衡圖像。

下面是一個(gè)簡(jiǎn)單的代碼來(lái)展示它的使用:

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

所以現(xiàn)在你可以把不同亮度的圖像均衡以后看結(jié)果

histogram均衡在圖片的histogram被限制在一個(gè)范圍內(nèi)時(shí)很有用,它在histogram覆蓋大范圍時(shí)并不好用。

對(duì)比度受限自適應(yīng)直方圖均衡

我們第一個(gè)histogram均衡考慮的是圖片全部對(duì)比度,在很多情況下,這不是好主意,比如下面的圖片和做了全局histogram均衡的結(jié)果:

背景對(duì)比度在均衡后確實(shí)提高了。但是對(duì)比兩張圖里的雕像,我們由于過(guò)度亮而導(dǎo)致失去了大部分面部信息。這是由于圖像的histogram并不是像之前的圖片那樣限制在特定范圍內(nèi)。

要解決這個(gè)問(wèn)題,要用適應(yīng)性histogram均衡。在這里,圖像被分成小塊,這些小塊叫做瓷磚(瓷磚的大小在OpenCV里默認(rèn)是8x8)。然后這些小塊還和平常一樣做均衡,所以在小塊里,histogram是在小范圍內(nèi)的,如果有噪點(diǎn),會(huì)被放大。要避免這個(gè),要應(yīng)用對(duì)比度限制。如果任何histogram 高于特定的對(duì)比度限制(OpenCV里默認(rèn)是40),那些像素會(huì)被修剪掉并被無(wú)變化的放到其他然后再做histogram均衡。均衡后,要移除瓷磚邊界的人工因素,要應(yīng)用雙線性插值。

下面的代碼顯示了OpenCV里的CLAHE:

import numpy as np
import cv2

img = cv2.imread('tsukuba_l.png',0)

# create a CLAHE object (Arguments are optional).
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
cl1 = clahe.apply(img)

cv2.imwrite('clahe_2.jpg',cl1)

看下面的結(jié)果并和前面的結(jié)果對(duì)比,特別是雕塑部分

END

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容