在直方图的基础上,也就出现了直方图的均衡化。
直方图均衡化的处理过程中就是在寻找一个变换函数(经常用累积分布函数(CDF)来当作变换函数),为什么呢?这在matlab冈萨雷斯书里面有严格证明,详见72-77页(第三版,注意是讲理论那个版本,冈萨雷斯有两个版本的书,一本介绍理论,一本matlab版本),我就不码出来了。下面重点介绍直方图均衡化的具体实现过程。
主要分以下四步:
1、进行原始图像的像素灰度个数统计;
2、计算灰度分布密度 (理解成归一化也可以吧,实现起来是一样,但思路并不是想进行归一化吧)
3、计算累计直方图分布, 可得到我们的映射函数 (直方图均衡化)
4、对原始图像灰度值通过第三步得到的映射函数进行映射(图像均衡化)
% 实现灰度图像均衡化
% 直方图均衡化处理的“中心思想”是把原始图像的灰度直方图从比较集中的某个灰度区间变成在全部灰度范围内的均匀分布。
% 直方图均衡化就是对图像进行非线性拉伸,重新分配图像像素值,使一定灰度范围内的像素数量大致相同。
% 直方图均衡化就是把给定图像的直方图分布改变成“均匀”分布直方图分布。
% 缺点:
% 1)变换后图像的灰度级减少,某些细节消失;
% 2)某些图像,如直方图有高峰,经处理后对比度不自然的过分增强。
% 经常用累积分布函数(CDF)当作我们变换的映射函数
%
close all;clear all;clc;
img = imread('4.bmp');
[height,width] = size(img);
sumPix = zeros(size(img));
%% 第一步:进行像素灰度个数统计;
NumPixel = zeros(1, 256);
for i = 0 : 255
NumPixel (i + 1) = sum( img(:) == i );
end
%绘制直方图
figure,bar(0: 255, NumPixel, 0, 'g')
ylim('auto');
title('原图像直方图')
xlabel('灰度值')
ylabel('出现次数')
%% 第二步:计算灰度分布密度
ProbPixel = zeros(1,256);
for i = 0 : 255
ProbPixel(i + 1) = NumPixel(i + 1) / (height * width * 1.0);
end
%% 第三步:计算累计直方图分布, 可得到我们的映射函数 (直方图均衡化)
CumuPixel = zeros(1,256);
for i = 1:256
if i == 1
CumuPixel(i) = ProbPixel(i);
else
CumuPixel(i) = CumuPixel(i - 1) + ProbPixel(i);
end
end
% 并对累计直方图分布求整
CumuPixel = round(255 * CumuPixel); %这样就形成了一个原灰度值到目标图像灰度值的一个映射 (相当于是我们最终要找到的变换函数)
%% 对灰度值进行映射(图像均衡化)
sumPix = img;
for i = 0: 255
sumPix( find( img == i ) ) = CumuPixel( i + 1 ); %将原图像img像素 通过 CumuPixel数组 映射到 sumPix中像素
end
%显示均衡化后的图像
figure,imshow(sumPix)
title('均衡化后图像')
%% 统计现有图像每个灰度级出现的次数
GPeq = zeros(1, 256);
for i = 0 : 255
GPeq (i + 1) = sum( sumPix(:) == i );
end
% 显示均衡化后的直方图
figure,bar(0: 255,GPeq,0, 'b');title('均衡化后的直方图')
ylim('auto');
xlabel('灰度值')
ylabel('出现次数')
运行结果图:
原始图像:
从运行结果可以明显的看出前后不同的效果!!!!
直方图分布得到拉伸,图像的对比度提高。