基于直方圖的圖像增強算法(HE、CLAHE、Retinex)之(一)
直方圖是圖像色彩統(tǒng)計特征的抽象表述。基于直方圖可以實現(xiàn)很多有趣的算法。例如,圖像增強中利用直方圖來調(diào)整圖像的對比度、有人利用直方圖來進(jìn)行大規(guī)模無損數(shù)據(jù)隱藏、還有人利用梯度直方圖HOG來構(gòu)建圖像特征進(jìn)而實現(xiàn)目標(biāo)檢測。本節(jié)我們就來討論重要的直方圖均衡化算法,說它重要是因為以此為基礎(chǔ)后續(xù)又衍生出了許多實用而有趣的算法。
本文引用地址:http://m.butianyuan.cn/article/201702/344363.htmHistogram equalization
如果一幅圖像的像素灰度值在一個過于有限的范圍內(nèi)聚集,那么圖像的程序效果即會很糟糕,直接觀感就是對比度很弱。下圖來自維基百科,第一幅圖的直方圖分布非常不均衡。如果把直方圖均勻地延展到整個分布域內(nèi),則圖像的效果顯得好了很多。
Matlab中提供了現(xiàn)成的函數(shù)“histeq()”來實現(xiàn)圖像的直方圖均衡。但為了演示說明算法的原理,下面我將在Matlab中自行編碼實現(xiàn)圖像的直方圖均衡。通過代碼來演示這個算法顯然更加直觀,更加易懂。當(dāng)然,其實我還不得不感嘆,如果僅僅是作為圖像算法研究之用,Matlab確實非常好用。
首先讀入圖像,并將其轉(zhuǎn)化為灰度圖。然后提取圖像的長和寬。
image = imread('Unequalized_Hawkes_Bay_NZ.jpg');
Img = rgb2gray(image);
[height,width]=size(image);
然后繪制一下原始圖像的直方圖。
[plain] view plain copy
[counts1, x] = imhist(Img,256);
counts2 = counts1/height/width;
stem(x, counts2);
統(tǒng)計每個灰度的像素值累計數(shù)目。
NumPixel = zeros(1,256);%統(tǒng)計各灰度數(shù)目,共256個灰度級
for i = 1:height
for j = 1: width
%對應(yīng)灰度值像素點數(shù)量增加一
%因為NumPixel的下標(biāo)是從1開始,但是圖像像素的取值范圍是0~255,所以用NumPixel(Img(i,j) + 1)
NumPixel(Img(i,j) + 1) = NumPixel(Img(i,j) + 1) + 1;
end
end
然后將頻數(shù)值算為頻率
ProbPixel = zeros(1,256);
for i = 1:256
ProbPixel(i) = NumPixel(i) / (height * width * 1.0);
end
再用函數(shù)cumsum來計算cdf,并將頻率(取值范圍是0.0~1.0)映射到0~255的無符號整數(shù)。
CumuPixel = cumsum(ProbPixel);
CumuPixel = uint8(255 .* CumuPixel + 0.5);
直方圖均衡。賦值語句右端,Img(i,j)被用來作為CumuPixel的索引。比如Img(i,j) = 120,則從CumuPixel中取出第120個值作為Img(i,j) 的新像素值。
for i = 1:height
for j = 1: width
Img(i,j) = CumuPixel(Img(i,j));
end
end
最后顯示新圖像的直方圖。
imshow(Img);
[counts1, x] = imhist(Img,256);
counts2 = counts1/height/width;
stem(x, counts2);
當(dāng)然,上述討論的是灰度圖像的直方圖均衡。對于彩色圖像而言,你可能會想到分別對R、G、B三個分量來做處理,這也確實是一種方法。但有些時候,這樣做很有可能導(dǎo)致結(jié)果圖像色彩失真。因此有人建議將RGB空間轉(zhuǎn)換為HSV之后,對V分量進(jìn)行直方圖均衡處理以保存圖像色彩不失真。下面我們來做一些對比實驗。待處理圖像是標(biāo)準(zhǔn)的圖像處理測試用圖couple圖,如下所示。
首先,我們分別處理R、G、B三個分量,為了簡便我們直接使用matlab中的函數(shù)histeq()。
a = imread('couple.tiff');
R = a(:,:,1);
G = a(:,:,2);
B = a(:,:,3);
R = histeq(R, 256);
G = histeq(G, 256);
B = histeq(B, 256);
a(:,:,1) = R;
a(:,:,2) = G;
a(:,:,3) = B;
imshow(a)
下面的代碼使用了另外一種方式,即將色彩空間轉(zhuǎn)換到HSV后,對V通道進(jìn)行處理。由于代碼基本與前面介紹的一致,這里我們不再做過多解釋了。
Img = imread('couple.tiff');
hsvImg = rgb2hsv(Img);
V=hsvImg(:,:,3);
[height,width]=size(V);
V = uint8(V*255);
NumPixel = zeros(1,256);
for i = 1:height
for j = 1: width
NumPixel(V(i,j) + 1) = NumPixel(V(i,j) + 1) + 1;
end
end
ProbPixel = zeros(1,256);
for i = 1:256
ProbPixel(i) = NumPixel(i) / (height * width * 1.0);
end
CumuPixel = cumsum(ProbPixel);
CumuPixel = uint8(255 .* CumuPixel + 0.5);
for i = 1:height
for j = 1: width
V(i,j) = CumuPixel(V(i,j));
end
end
V = im2double(V);
hsvImg(:,:,3) = V;
outputImg = hsv2rgb(hsvImg);
imshow(outputImg);
最后,來對比一下不同方法對彩色圖像的處理效果。下面的左圖是采用R、G、B三分量分別處理得到的結(jié)果。右圖是對HSV空間下V通道處理之結(jié)果。顯然,右圖的效果更理想,而左圖則出現(xiàn)了一定的色彩失真。事實上,對彩色圖像進(jìn)行直方圖均衡是圖像處理研究領(lǐng)域一個看似簡單,但是一直有人在研究的話題。我們所說的對HSV空間中V分量進(jìn)行處理的方法也是比較基本的策略。很多相關(guān)的研究文章都提出了更進(jìn)一步的、適應(yīng)性更強的彩色圖像直方圖均衡化算法。有興趣的讀者可以參閱相關(guān)文獻(xiàn)以了解更多。
分別處理R、G、B三個分量之結(jié)果 轉(zhuǎn)換到HSV空間后處理V分量
這是本系列文章的第一篇,在下一篇文章中我們將要討論CLAHE算法,也就是限制對比度的自適應(yīng)直方圖均衡算法。
評論