matlab计算多张图像的灰度直方图_MATLAB--数字图像处理 图像直方图均衡化

88550d7124b08dceaf5d85d5d812071a.png

图像直方图均衡化

首先,我们要理解什么是图像直方图均衡化:

把原始图像的灰度直方图从比较集中的某个灰度区间变成在全部灰度范围内的均匀分布。直方图均衡化就是对图像进行非线性拉伸,重新分配图像像素值,使一定灰度范围内的像素数量大致相同。直方图均衡化就是把给定图像的直方图分布改变成“均匀”分布直方图分布,具体见下图(说的简单点,就是把原来的图像的灰度分配均匀,使得0-255都有一定的取值,这样对比度相对大一些,视觉上更好看一点):

0be2f47979a17360a6525769285dd1ea.png


这里我们可以直接利用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均衡后直方图');

效果图:

964157f61fd2b4b7e89611c2bde1fc40.png

当然,我们也可以自己编写均衡化函数,首先就要了解均衡化的算法步骤(这里我就不多说了)
上代码:

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('均衡化后的直方图');

效果图:

29a7e8431a0bb1861d90ba687cc468a3.png

方法二(从大佬那里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('均衡化后结果');

效果图(感觉颜色更加丰富了,哈哈):

35ed9d056e781e551dd85cacbffdc1e9.png


这里其实还有一种方法,就是先把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空间均衡化后结果');

效果图(感觉没有上一种方法好看,这个其实是要分图片的):

28357eefbee8efbe7554f11f37e78535.png

7c3cd476b53b42d1e44d28d00d7ff40e.png
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值