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