MATLAB--數字圖像處理 圖像直方圖均衡化

圖像直方圖均衡化

首先,我們要理解什麼是圖像直方圖均衡化:

把原始圖像的灰度直方圖從比較集中的某個灰度區間變成在全部灰度範圍內的均勻分佈。直方圖均衡化就是對圖像進行非線性拉伸,重新分配圖像像素值,使一定灰度範圍內的像素數量大致相同。直方圖均衡化就是把給定圖像的直方圖分佈改變成“均勻”分佈直方圖分佈,具體見下圖(說的簡單點,就是把原來的圖像的灰度分配均勻,使得0-255都有一定的取值,這樣對比度相對大一些,視覺上更好看一點):在這裏插入圖片描述
這裏我們可以直接利用histeq()、adapthisteq()函數對圖像進行均衡化

 H= imread('a1.jpg'); 
if length(size(H))>2
    H=rgb2gray(H);  
end
subplot(3,2,1);  
imshow(H); title('原圖');  
subplot(3,2,2);  
imhist(H); title('原圖直方圖');  
subplot(3,2,3);  
H1=adapthisteq(H);  
imshow(H1); title('adapthisteq均衡後圖');  
subplot(3,2,4);  
imhist(H1);title('adapthisteq均衡後直方圖');  
subplot(3,2,5);  
H2=histeq(H);  
imshow(H2); title('histeq均衡後圖');  
subplot(3,2,6);  
imhist(H1); title('histeq均衡後直方圖'); 

效果圖:
在這裏插入圖片描述

當然,我們也可以自己編寫均衡化函數,首先就要了解均衡化的算法步驟(這裏我就不多說了)
上代碼:

H= imread('a1.jpg'); 

%判斷是否爲三通道彩色圖片 若是 則將其灰度化
if length(size(H))>2
    H=rgb2gray(H);  
end

%獲取圖片的尺寸 便於計算總像素數 即m*n 
[m,n]=size(H);  

%生成一個一行256列的矩陣
p=zeros(1,256);  

% 統計各灰度的像素個數 
%find(H==i) 是在圖像矩陣裏面尋找灰度爲i的點座標 
% 因爲矩陣是從1開始的 所以爲p(i+1)
for i=0:255  
   p(i+1)=length(find(H==i))/(m*n);  
end  


subplot(2,2,1);  
imshow(H);  
title('原圖');  
subplot(2,2,2);  
% 顯示原圖的直方圖
bar(0:255,p,'b');  
title('原圖直方圖');  
 
 % 利用循環 累加概率值
s=zeros(1,256);  
for i=1:256  
     for j=1:i  
         s(i)=p(j)+s(i);                  
     end  
end  

%對s中的數先乘以255,再取整   
a=round(s*255);  
b=H;  
%更新原圖像的灰度
for i=0:255  
     b(find(H==i))=a(i+1);                
end
  
subplot(2,2,3);  
imshow(b)                            
title('均衡化後圖像');  
 %統計更新後的概率
for i=0:255  
    GPeq(i+1)=sum(p(find(a==i)));            
end  
subplot(2,2,4);  
bar(0:255,GPeq,'b'); title('均衡化後的直方圖'); 

效果圖:
在這裏插入圖片描述

方法二(從大佬那裏copy的)

Img= imread('a1.jpg'); 
if length(size(Img))>2
    Img=rgb2gray(Img);  
end
 
%繪製原始圖像的直方圖
[height,width]=size(Img);  
[counts1, x] = imhist(Img,256);  
counts2 = counts1/height/width;
figure(1),
subplot(1,2,1),
imshow(Img);title('原始圖像');
subplot(1,2,2),
stem(x, counts2); title('原始圖像直方圖');
 
%統計每個灰度的像素值累計數目
NumPixel = zeros(1,256);%統計各灰度數目,共256個灰度級  
for i = 1:height  
    for j = 1: width  
    %對應灰度值像素點數量+1  
    %NumPixel的下標是從1開始,而圖像像素的取值範圍是0~255,所以用NumPixel(Img(i,j) + 1)  
    NumPixel(Img(i,j) + 1) = NumPixel(Img(i,j) + 1) + 1;  
    end  
end  
 
%將頻數值算爲頻率
ProbPixel = zeros(1,256);  
for i = 1:256  
    ProbPixel(i) = NumPixel(i) / (height * width * 1.0);  
end  
 
%函數cumsum來計算cdf,並將頻率(取值範圍是0.0~1.0)映射到0~255的無符號整數
CumuPixel = cumsum(ProbPixel);  
CumuPixel = uint8(255 .* CumuPixel + 0.5); 
 
%直方圖均衡。賦值語句右端,Img(i,j)被用來作爲CumuPixel的索引
for i = 1:height  
    for j = 1: width  
        Img(i,j) = CumuPixel(Img(i,j)+1);  
    end  
end  
 
%顯示更新後的直方圖
figure(2),
subplot(1,2,1),
imshow(Img); title('直方圖均衡化圖像'); 
[counts1, x] = imhist(Img,256);  
counts2 = counts1/height/width;  
subplot(1,2,2),
stem(x, counts2); title('直方圖均衡化後圖像的直方圖');

上面都是對灰度圖片進行均衡化,那麼對彩色圖片怎麼均衡化呢?辦法肯定是有的。我們知道,彩色圖片無非就是RGB三通道組成的,只要我們分別對三個通道進行均衡化,再合成,得到的圖片就是彩色的,均衡化後的。
上代碼:

Img= imread('a1.jpg'); 
OutImg=Img;
%分別提取三通道的信息
R = Img(:,:,1);  
G = Img(:,:,2);  
B = Img(:,:,3);  

%分別對三通道的圖片進行均衡化 
R = histeq(R, 256);  
G = histeq(G, 256);  
B = histeq(B, 256);  
 
 %最後合成爲一張圖片
OutImg(:,:,1) = R;  
OutImg(:,:,2) = G;  
OutImg(:,:,3) = B;  
 
figure,
subplot(1,2,1),
imshow(Img);title('原始圖像');
subplot(1,2,2),
imshow(OutImg); title('均衡化後結果');

效果圖(感覺顏色更加豐富了,哈哈):
在這裏插入圖片描述
這裏其實還有一種方法,就是先把RGB轉換爲HSV,再均衡化
上代碼:

mg= imread('a1.jpg'); 
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)+1);  %注意,這裏需要+1,要不然會出問題
    end  
end  
 
V = im2double(V);  
hsvImg(:,:,3) = V;  
outputImg = hsv2rgb(hsvImg);  
figure,
subplot(1,2,1),
imshow(Img);title('原始圖像');
subplot(1,2,2),
imshow(outputImg); title('在HSV空間均衡化後結果');

效果圖(感覺沒有上一種方法好看,這個其實是要分圖片的):
在這裏插入圖片描述

更多

獲取更多資料、代碼,微信公衆號:海轟Pro
回覆 海轟 即可

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章