MATLAB对图像进行直方图均衡化,直方图规定化处理(非函数版本)

直方图均衡化:

clc;
close all;
clear all;
[pathname filename] = uigetfile('*.*,*.jpg','请选择文件','*.jpg');
im = imread([filename pathname]);
if numel(size(im)) > 2
    im = rgb2gray(im);
end
figure
subplot(221);
imshow(im);
xlabel('原图像');

[m n] = size(im);
%灰度统计
num = zeros(1,256);
for i = 1:m
   for j = 1:n
       num(im(i,j) + 1) = num(im(i,j) + 1) + 1;
   end
end
subplot(222);
plot(1:256,num);
xlabel('像数统计图');
%概率
p = num / (m*n);

%累计
cnum = zeros(1,256);
for i = 1:256
    if i==1
        cnum(i) = p(i);
    else
        cnum(i) = cnum(i-1)  + p(i);
    end
end
  
%累计取整
cnum = uint8(255 .* cnum + 0.5);
%均衡化
for i = 1:m
    for j = 1:n
        im(i,j) = cnum(im(i,j) + 1);
    end
end
subplot(223);
imshow(im);
xlabel('均衡化增强后图像');

subplot(224);
imhist(im);
xlabel('直方图');

结果:
在这里插入图片描述


直方图规定化:(单映射规则)

clc;    
clear all;  
close all;  
% 直方图规定化法:单映射规则 
[filename pathname ] = uigetfile('*.*,*.jpg','请选择文件','*.jpg');
im_o = imread([pathname filename]);    %原始图像
[filename pathname ] = uigetfile('*.*,*.jpg','请选择文件','*.jpg');
im_s = imread([pathname filename]);    %标准图像

[m_o, n_o] = size(im_o);     %原始图像的大小
[m_s, n_s] = size(im_s);     %标准图像的大小

hist_o = zeros(1, 256);
hist_s = zeros(1, 256);
for i = 1 : m_o             %计算原始图像每级灰度的个数
    for j = 1 : n_o
        hist_o(im_o(i, j) + 1) = hist_o(im_o(i, j) + 1) + 1;
    end
end

for i = 1 : m_s             %计算标准图像每级灰度的个数
    for j = 1 : n_s
        hist_s(im_s(i, j) + 1) = hist_s(im_s(i, j) + 1) + 1;
    end
end

hist_o = hist_o / (m_o * n_o);       %计算原始图像的灰度分布概率
hist_s = hist_s / (m_s * n_s);       %计算标准图像的灰度分布概率

v1 = zeros(1, 256);                   %原始图像的累积直方图
v2 = zeros(1, 256);                   %标准图像的累积直方图

for i = 1 : 256                       %计算原始图和标准图像的累积直方图
   if i == 1
       v1(i) = hist_o(i);
       v2(i) = hist_s(i);
   else
       v1(i) = v1(i - 1) + hist_o(i);
       v2(i) = v2(i - 1) + hist_s(i);
   end
end
      
for i = 1 : 256
%     value{i} = v2 - v1(i);  %元胞数组的方式求两个累积直方图的差值,因:原始累积直方图的一个值减规定直方图的所有的数据
%     value{i} = abs(value{i});  
%     [temp index(i)] = min(value{i});
      value = zeros(1, 256);
      for j = 1 : 256
          value(j) = v1(i) - v2(j);
      end
      value = abs(value);
      [temp index(i)] = min(value); %就是返回value中的最小值temp然后把他的位置存到index里面。
end  
newimg = zeros(m_o,n_o);  
for i = 1 : m_o  
    for j = 1 : n_o  
        newimg(i,j) = index(im_o(i,j) + 1) - 1;  %记录位置
    end  
end  
newimg = uint8(newimg);  
      
subplot(2,3,1);imshow(im_o);title('原图');  
subplot(2,3,2);imshow(im_s);title('标准图');  
subplot(2,3,3);imshow(newimg);title('myself匹配到标准图');  
subplot(2,3,4);imhist(im_o);  
title('原图');  
subplot(2,3,5);imhist(im_s);  
title('标准图');  
subplot(2,3,6);imhist(newimg);  
title('myself匹配到标准图'); 


直方图规定化:(多映射规则)
%组映射(GML)代码示例2
clc;
close all;
clear all;
[filename pathname ] = uigetfile('*.*,*.jpg','请选择文件','*.jpg');
im_o = imread([pathname filename]);    %原始图像
[filename pathname ] = uigetfile('*.*,*.jpg','请选择文件','*.jpg');
im_s = imread([pathname filename]);    %标准图像

[m_o, n_o] = size(im_o);     %原始图像的大小
[m_s, n_s] = size(im_s);     %标准图像的大小

hist_o = zeros(1, 256);
hist_s = zeros(1, 256);
for i = 1 : m_o             %计算原始图像每级灰度的个数
    for j = 1 : n_o
        hist_o(im_o(i, j) + 1) = hist_o(im_o(i, j) + 1) + 1;
    end
end

for i = 1 : m_s             %计算标准图像每级灰度的个数
    for j = 1 : n_s
        hist_s(im_s(i, j) + 1) = hist_s(im_s(i, j) + 1) + 1;
    end
end

hist_o = hist_o / (m_o * n_o);       %计算原始图像的灰度分布概率
hist_s = hist_s / (m_s * n_s);       %计算标准图像的灰度分布概率

v1 = zeros(1, 256);                   %原始图像的累积直方图
v2 = zeros(1, 256);                   %标准图像的累积直方图

for i = 1 : 256                       %计算原始图和标准图像的累积直方图
   if i == 1
       v1(i) = hist_o(i);
       v2(i) = hist_s(i);
   else
       v1(i) = v1(i - 1) + hist_o(i);
       v2(i) = v2(i - 1) + hist_s(i);
   end
end


end1 = 1;                              %分段的段首
end2 = 1;                              %分段的段尾
index1 = zeros(1, 256);                %映射关系,(数组下标-1)映射到(数组元素值-1)

%根据组映射规则,去计算位置,并取出数据,进行映射
for i = 1 : 256
    value  = zeros(1, 256);            %每次进行初始化
    if v2(i) == 0    %0,则略过
        continue;
    else
        for j = 1 : 256   %v2(i) - v1中所有的数据的绝对值
            value(j) = abs(v2(i) - v1(j));
        end
    end
    
    [tmp end2] = min(value);          %求差值的最小值的位置
                                      %原始图像的某区间end1~end2映射到i去
    for j = end1 : end2               %产生映射关系,注意:此时存放的是位置(即:映射后的灰度值,比实际灰度的多1,因此,在下面要-1
        index1(j) = i;
    end
    end1 = end2 + 1;                  %更改下次组映射的段首位置,是本次段尾+1
end

out_im = zeros(m_o, n_o);             %对原始图像的每个像素进行映射
for i = 1 : m_o
    for j = 1 : n_o
        out_im(i, j) = index1(im_o(i, j) + 1) - 1;   %+1是灰度像素是从0开始,而数组下标是从1开始,因此要加1;
    end
end

figure;                                   %结果显示
subplot(2, 3, 1); imshow(im_o); title('原图');
subplot(2, 3, 4); imhist(im_o); title('原图直方图');
subplot(2, 3, 2); imshow(im_s); title('标准');
subplot(2, 3, 5); imhist(im_s); title('标准图直方图');
out_im = uint8(out_im);          %matlab处理时,会将实际图像中的整型数据变成实数(大小不变,类型变化),直接显示会变成白色图像,
                                 %因此要强制转换数据类型为无符号 8位整型,这样显示的结果才正确
subplot(2, 3, 3); imshow(out_im); title('结果');
subplot(2, 3, 6); imhist(out_im); title('结果图直方图');


  • 6
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值