直方图均衡化能够得到具有均匀直方图的图像,对于某些应用,采用均匀直方图的基本增强并不是最好的方法。我们往往需要将直方图变换为某种特定的形状,以实现对原图像进行有目的地增强。
进行直方图规定化,需要指定规定化处理后的图像的直方图。在本算法中,使用一幅标准图像的直方图作为规定的直方图。理想情况下,规定化处理后的图像的直方图应当与标准图像的直方图相同,但实际上这两者并不完全相同,只是比较接近。
(1)对原图像,计算用于直方图均衡化的变换函数,对 s k s_k sk进行四舍五入
(2)对标准图像,计算用于直方图均衡化的变换函数,对 z q z_q zq进行四舍五入
(3)对每一个值 s k s_k sk (k=0,1,2,…, 2 n 2^n 2n-1),寻找与它最接近的 z q z_q zq,并存储这些从k到q的映射,将原图像中灰度级为k的像素点的值更改为q,即可得到直方图规定化后的图像。要注意的是,当从k到q的映射不唯一时,选择最小的q值。
(1)原图像、标准图像和规定化图像;
(2)原图像、标准图像和规定化图像的归一化直方图;
%% 直方图规定化
clear,close all
srcImg = imread('直方图规定化用原图像.tif');
h = figure(1);
size = get(0,'ScreenSize');
set(h,'position',size)
subplot(331);imshow(srcImg);title('原图像','fontsize',18);
stdImg = imread('直方图规定化用标准图像.tif');
subplot(334);imshow(stdImg);title('标准图像','fontsize',18);
src_p = histogram(srcImg);% 计算原图像的归一化直方图
subplot(332);bar(0:255,src_p);axis([0,255,0,max(src_p)*1.2]);title('原图像的归一化直方图','fontsize',18);
src_s = cum(src_p);% 计算原图像的累积归一化直方图
subplot(333);bar(0:255,src_s);axis([0,255,0,max(src_s)*1.2]);title('原图像的累积归一化直方图','fontsize',18);
src_s = uint8(src_s*255);
std_p = histogram(stdImg);% 计算标准图像的归一化直方图
subplot(335);bar(0:255,std_p);axis([0,255,0,max(std_p)*1.2]);title('标准图像的归一化直方图','fontsize',18);
std_s = cum(std_p);% 计算标准图像的累积归一化直方图
subplot(336);bar(0:255,std_s);axis([0,255,0,max(std_s)*1.2]);title('标准图像的累积归一化直方图','fontsize',18);
std_s = uint8(std_s*255);
q = zeros(1,256);
for k = 0:255
temp = src_s(k+1)-std_s;
temp = abs(temp);
[~,q(k+1)] = min(temp);
end
dstImg = transform(srcImg,q);
dstImg = uint8(dstImg);
subplot(337);imshow(dstImg);title('规定化图像','fontsize',18);
dst_p = histogram(dstImg);% 计算规定化图像的归一化直方图
subplot(338);bar(0:255,dst_p);axis([0,255,0,max(dst_p)*1.2]);title('规定化图像的归一化直方图','fontsize',18);
dst_s = cum(dst_p);% 计算规定化图像的累积归一化直方图
subplot(339);bar(0:255,dst_s);axis([0,255,0,max(dst_s)*1.2]);title('规定化图像的累积归一化直方图','fontsize',18);
%% 函数定义:计算图像的归一化直方图
function p = histogram(srcImg)
[rows,cols] = size(srcImg);
h = zeros(1,256);
for k = 0:255
bw = (srcImg==k);
h(k+1) = sum(bw(:));
end
p = h/(rows*cols);
end
%% 函数定义:计算图像的累积归一化直方图
function s = cum(p)
s = zeros(1,256);
for i = 1:256
if (1==i)
s(i)=p(1);
continue;
end
s(i) = s(i-1)+p(i);
end
end
%% 函数定义:灰度级映射
function dstImg = transform(srcImg,s)
[rows,cols] = size(srcImg);
dstImg = zeros(rows,cols);
for k = 0:255
bw = (srcImg==k);
dstImg(bw) = s(k+1);
end
end