直方图均衡化:
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('结果图直方图');