直接从图像直方图得到的统计量信息可用于增强图像。令r是一个离散随机变量,它表示区间[0,L-1]之间的灰度值;令是对应于灰度值的归一化直方图分量,即可视为在图像中出现灰度值为的概率。对于灰度值在[0,L-1]内的图像,其均值和方差定义为:
令(x,y)是给定图像中任意一个像素的坐标,令是已(x,y)为中心的一个规定大小的领域,这个邻域中像素的均值为:
其中是中像素的直方图。类似地,邻域内像素地方差为:
均值是是某一区域中平均灰度地测度,方差是某一区域内灰度对比度的测度。对图像进行局部增强时,就要利用到图像的全局均、方差和局部邻域均值和方差,具体方法如下:
首先令图像的全局均值和标准差为:、,图像内某一点(x,y)的邻域内的均值和方差为:、,图像在点(x,y)处的像素值为,增强后的图像在该点的像素值为。
增强方法的第一个要素是:
若(和都是非负常数,且),则将(x,y)点处的像素作为待处理的一个候选像素。
增强方法的第二个要素是:
若(和都是非负常数,且),则将(x,y)点处的像素作为待处理的一个候选像素。
对于候选像素的具体操作如下:
否则,。其中参数C是自定义的正常数。
matlab代码:
图像局部增强函数的定义模块:
function img_out=part_hist_enha(img,k0,k1,k2,k3,C,Size)
%定义部分直方图增强函数,参数img为输入图像;k0和k1为非负常数,且k0<k1,其作用为
%k0*全局均值<=邻域均值<=k1*全局均值,作为像素是否增强的判断部分;k2,k3与k0,k1
%类似,k2<k3,其作用为k2*全局标准差<=邻域标准差<=k3*全局标准差,作为像素是否增强
%的判断部分;C为要增强的像素点的像素值乘以的一个系数,不能为负,决定像素值是变暗,
%还是变亮;Size为正方形邻域处理的大小,为奇正整数;img_out为输出图像
h=imhist(img)/numel(img);%直方图数据归一化
mu=0;%全局像素均值
derta=0;%全局像素标准差
for i=1:256
mu=mu+(i-1)*h(i); %计算均值
end
for i=1:256
derta=derta+power(i-1-mu,2)*h(i); %计算方差
end
derta=power(derta,0.5); %计算标准差
[m,n,k]=size(img);
if k==1 %如果为灰度图
img_out=img;
img_fill=[zeros((Size-1)/2,n+(Size-1));zeros(m,(Size-1)/2),img,zeros(m,(Size-1)/2);zeros((Size-1)/2,n+(Size-1))];%0填充
for i=1:m
for j=1:n
[mu_sxy,derta_sxy]=field_compu(img_fill,i,j,Size);%调用下面的field_compu函数
if (mu_sxy>=k0*mu && mu_sxy<=k1*mu) && (derta_sxy>=k2*derta && derta_sxy<=k3*derta)
img_out(i,j)=C*img(i,j);%局部像素变换,增强对比(变暗或变亮)
end
end
end
end
if k==3
img_R=img(:,:,1);
img_out_R=img_R;
img_G=img(:,:,2);
img_out_G=img_G;
img_B=img(:,:,3);
img_out_B=img_B;
img_fill_R=[zeros((Size-1)/2,n+(Size-1));zeros(m,(Size-1)/2),img_R,zeros(m,(Size-1)/2);zeros((Size-1)/2,n+(Size-1))];%0填充
img_fill_G=[zeros((Size-1)/2,n+(Size-1));zeros(m,(Size-1)/2),img_G,zeros(m,(Size-1)/2);zeros((Size-1)/2,n+(Size-1))];%0填充
img_fill_B=[zeros((Size-1)/2,n+(Size-1));zeros(m,(Size-1)/2),img_B,zeros(m,(Size-1)/2);zeros((Size-1)/2,n+(Size-1))];%0填充
for i=1:m
for j=1:n
[mu_sxy_R,derta_sxy_R]=field_compu(img_fill_R,i,j,Size);%调用下面的field_compu函数
if (mu_sxy_R>=k0*mu && mu_sxy_R<=k1*mu) && (derta_sxy_R>=k2*derta && derta_sxy_R<=k3*derta)
img_out_R(i,j)=C*img_R(i,j);%局部像素变换,增强对比(变暗或变亮)
end
[mu_sxy_G,derta_sxy_G]=field_compu(img_fill_G,i,j,Size);%调用下面的field_compu函数
if (mu_sxy_G>=k0*mu && mu_sxy_G<=k1*mu) && (derta_sxy_G>=k2*derta && derta_sxy_G<=k3*derta)
img_out_G(i,j)=C*img_G(i,j);%局部像素变换,增强对比(变暗或变亮)
end
[mu_sxy_B,derta_sxy_B]=field_compu(img_fill_B,i,j,Size);%调用下面的field_compu函数
if (mu_sxy_B>=k0*mu && mu_sxy_B<=k1*mu) && (derta_sxy_B>=k2*derta && derta_sxy_B<=k3*derta)
img_out_B(i,j)=C*img_B(i,j);%局部像素变换,增强对比(变暗或变亮)
end
end
end
img_out=cat(3,img_out_R,img_out_G,img_out_B);%矩阵拼接函数(这里是拼接为三维RGB)
end
end
function [mu_sxy,derta_sxy]=field_compu(img_fill,x,y,Size)
%定义邻域计算函数,计算原始图像(上面函数的参数img)的某一点(坐标为——x,y)的邻域
%(边长大小为Size)内的局部像素均值(mu_sxy)和方差(derta_sxy)
field_img=img_fill(x:x+Size-1,y:y+Size-1);%点(x,y)的邻域矩阵
h_sxy=imhist(field_img)/numel(field_img);%邻域直方图数据归一化
mu_sxy=0;%邻域像素均值
derta_sxy=0;%邻域像素标准差
for i=1:256
mu_sxy=mu_sxy+(i-1)*h_sxy(i);
end
for i=1:256
derta_sxy=derta_sxy+power(i-1-mu_sxy,2)*h_sxy(i);
end
derta_sxy=power(derta_sxy,0.5);
end
函数功能测试运行模块:
img=imread('cats.jpg');
img=rgb2gray(img);%rgb图像转为灰度图
img_out=part_hist_enha(img,0,0.3,0,0.4,10,5);%调用局部直方图增强函数
figure
subplot(121)
imshow(img)
title('原始图像')
subplot(122)
imshow(img_out)
title('局部直方图增强后的图像')
这里就是对图像中灰度值较小,且邻域内灰度对比度较小(即邻域内灰度值的变化不大,可能造成人眼的分辨不清)的像素点进行操作,把该像素点对应的像素值扩大10倍(如果像素值超过了最大像素值就等于最大像素值),结果如下:
灰度图效果:
彩色图效果 :
可以看见,图像中灰度值较小(颜色偏暗偏黑)且周围一固定大小邻域内像素值变化不大的的像素点的像素值确实变大(增白)了。