直方圖均衡化的作用是圖像增強。
有兩個問題比較難懂,一是爲什麼要選用累積分佈函數,二是爲什麼使用累積分佈函數處理後像素值會均勻分佈。
第一個問題。均衡化過程中,必須要保證兩個條件:①像素無論怎麼映射,一定要保證原來的大小關係不變,較亮的區域,依舊是較亮的,較暗依舊暗,只是對比度增大,絕對不能明暗顛倒;②如果是八位圖像,那麼像素映射函數的值域應在0和255之間的,不能越界。綜合以上兩個條件,累積分佈函數是個好的選擇,因爲累積分佈函數是單調增函數(控制大小關係),並且值域是0到1(控制越界問題),所以直方圖均衡化中使用的是累積分佈函數。
第二個問題。累積分佈函數具有一些好的性質,那麼如何運用累積分佈函數使得直方圖均衡化?比較概率分佈函數和累積分佈函數,前者的二維圖像是參差不齊的,後者是單調遞增的。直方圖均衡化過程中,映射方法是
其中,n是圖像中像素的總和,是當前灰度級的像素個數,L是圖像中可能的灰度級總數。
來看看通過上述公式怎樣實現的拉伸。假設有如下圖像:
得圖像的統計信息如下圖所示,並根據統計信息完成灰度值映射:
映射後的圖像如下所示:
以上就是直方圖映射均衡化的步驟。
RGB = imread('lena.jpg'); % 讀取彩色圖
subplot(131);
imshow(RGB);
title('彩色圖');
I=rgb2gray(RGB); % 將彩色圖轉化爲灰度圖
subplot(132);
imshow(I);
title('灰度圖');
[R, C] = size(I);
% 統計每個像素值出現次數
cnt = zeros(1, 256);
for i = 1 : R
for j = 1 : C
cnt(1, I(i, j) + 1) = cnt(1, I(i, j) + 1) + 1;
end
end
f = zeros(1, 256);
f = double(f); cnt = double(cnt);
% 統計每個像素值出現的概率, 得到概率直方圖
for i = 1 : 256
f(1, i) = cnt(1, i) / (R * C);
end
% 求累計概率,得到累計直方圖
for i = 2 : 256
f(1, i) = f(1, i - 1) + f(1, i);
end
% 用f數組實現像素值[0, 255]的映射。
for i = 1 : 256
f(1, i) = f(1, i) * 255;
end
% 完成每個像素點的映射
I = double(I);
for i = 1 : R
for j = 1 : C
I(i, j) = f(1, I(i, j) + 1);
end
end
% 輸出
I = uint8(I);
subplot(133);
imshow(I);
[c,b]=imhist(I);
%I=cumsum(c);
figure,bar(c);
title('直方圖均衡化');