直方图匹配原理及MALAB实现

在学习直方图匹配之前,最好先看一下直方图均衡的原理,这样对于直方图匹配的理解就不是问题。

参考:直方图均衡原理及MATLAB实现

直方图匹配

对于某些应用,采用均匀直方图的直方图匹配法并不是最好的处理方法,如果希望得到具有规定形状的直方图,就需要用到一种特殊的处理方法:直方图匹配 (直方图规定化)。

1. 数学表示

首先考虑灰度值连续的情况:

令连续灰度值 r r r z z z 分别表示输入图像和输出图像的灰度级,用 p r ( r ) p_r(r) pr(r) p z ( z ) p_z(z) pz(z) 分别表示它们对应的连续概率密度函数。

我们现在的目标是:由给定的输入图像估计出 p r ( r ) p_r(r) pr(r),由 p r ( r ) p_r(r) pr(r) 得到 p z ( z ) p_z(z) pz(z),即得到我们希望输出的图像所具有的指定概率密度函数

首先,我们已经知道在直方图均衡中, s s s r r r 经过均衡后的图像灰度级,转换 (映射) 的表达式为:
s = T ( r ) = ( L − 1 ) ∫ 0 r p r ( w ) d w (1) s = T(r) = (L-1)\int_0^rp_r(w){\rm d}w \tag{1} s=T(r)=(L1)0rpr(w)dw(1)
这里表达的是 r r r 经过变换函数 T T T,映射到了 s s s

在这个基础上,再定义一个随机变量 z z z
G ( z ) = ( L − 1 ) ∫ 0 z p z ( t ) d t = s (2) G(z) = (L-1)\int_0^zp_z(t){\rm d}t = s \tag{2} G(z)=(L1)0zpz(t)dt=s(2)
这里表达的是 z z z 经过变换函数 G G G,映射到了 s s s

那么就可以得出: G ( z ) = T ( r ) G(z) = T(r) G(z)=T(r),所以 z z z 必须满足条件:
z = G − 1 [ T ( r ) ] = G − 1 ( s ) z = G^{-1}[T(r)] = G^{-1}(s) z=G1[T(r)]=G1(s)

对于灰度值离散的情况:

(1) 式的离散形式为:
s k = T ( r k ) = ( L − 1 ) ∑ j = 0 k p r ( r j ) = ( L − 1 ) M N ∑ j = 0 k n j ,    k = 0 , 1 , 2 , . . . , L − 1 (3) s_k = T(r_k) = (L-1)\sum^k_{j=0}p_r(r_j) = \frac{(L-1)}{MN}\sum^k_{j=0} n_j,\ \ k = 0,1,2,...,L-1 \tag{3} sk=T(rk)=(L1)j=0kpr(rj)=MN(L1)j=0knj,  k=0,1,2,...,L1(3)
(2) 式的离散形式为:
G ( z q ) = ( L − 1 ) ∑ i = 0 q p z ( z i ) = s k (4) G(z_q) = (L-1)\sum^q_{i=0}p_z(z_i) = s_k \tag{4} G(zq)=(L1)i=0qpz(zi)=sk(4)
其中 p z ( z i ) p_z(z_i) pz(zi) 是规定直方图的第 i i i 个值。

最后利用反变换找到期望的 z q z_q zq
z q = G − 1 ( s k ) z_q = G^{-1}(s_k) zq=G1(sk)
在实际情况中,由于图像灰度值是离散的,所以并不需要计算 G G G 的反变换。

2. 处理步骤

由一幅给定的图像,想要得到一幅其灰度级具有指定概率密度函数的图像,可以按照如下步骤:

  1. 由输入图像得到其概率密度函数 P r ( r ) P_r(r) Pr(r),然后可根据 (3) 式求得直方图均衡 s = T ( r ) s = T(r) s=T(r) 的值,并将 s k s_k sk 四舍五入到 [ 0 , L − 1 ] [0,L-1] [0,L1] 内;
  2. 因为已知了目标图像的规定直方图的值 P z ( z i ) P_z(z_i) Pz(zi),所以可由 (4) 式求得变换函数 $G(z),并将 G G G 的值四舍五入到 [ 0 , L − 1 ] [0,L-1] [0,L1] 内,存储在表中;
  3. 求解反变换函数 z = G − 1 ( s ) z = G^{-1}(s) z=G1(s),因为 z z z 是由 s s s 得到的,所以这一步是 s s s z z z 的映射,而 z z z 正是我们期望得到的值;
  4. 由于从 r r r s s s 也有映射,所以可以用 r r r 替换 s s s,将第三步得到的表达式替换为从 r r r z z z 的映射;

为了表述方便,下面把具有 r r r 值像素的图像直接叫做图像 r r r s s s z z z 同理。

所以整个处理过程就是:
对输入图像 r r r 进行直方图均衡得到输出图像 s s s,对均衡后的图像 s s s 进行反映射 z = G − 1 ( s ) z = G^{-1}(s) z=G1(s),对每个像素都进行处理后,输出图像的概率密度函数 PDF 就等于我们指定的 PDF。

MATLAB实现

clear all;
close all;
clc;

r=127;                              
x=-r:r+1;
sigma=20;
y1=exp(-((x-80).^2)/(2*sigma^2));
y2=exp(-((x+80).^2)/(2*sigma^2));
y=y1+y2;                        %双峰高斯函数,任意函数都可以

%im=imread('bg.bmp');  %匹配一个图像的直方图
%y=imhist(im);
y=y/sum(y);         %归一化,使函数符合概率分布的sum(y)==1这样一个规律
plot(y);            %待匹配的直方图

G=[];               %函数的累积直方图
for i=1:256
   G=[G sum(y(1:i))]; 
end

img=imread('lena.jpg');
[m n]=size(img);
hist=imhist(img);       %待处理图像的直方图
p=hist/(m*n);           
figure;plot(p)          %原图直方图

s=[];                   %待处理图像的累积直方图
for i=1:256
    s=[s sum(p(1:i))];
end

for i=1:256
    tmp{i}=G-s(i);
    tmp{i}=abs(tmp{i});         %因为要找距离最近的点,所以取绝对值
    [a index(i)]=min(tmp{i});   %找到两个累积直方图距离最近的点
end

imgn=zeros(m,n);
for i=1:m
   for j=1:n
      imgn(i,j)=index(img(i,j)+1)-1;    %由原图的灰度通过索引映射到新的灰度
   end
end

imgn=uint8(imgn);
figure;imshow(imgn)
figure;plot(imhist(imgn))       %新图的直方图

你可能感兴趣的:(图像处理)