靖harry

Talk is cheap,show me the code!

直方图规定化(匹配)

1
阅读(2470)

直方图规定化(匹配)

(1)基本原理

        上一篇博文中讲到的直方图均衡技术,可以自动地确定变换函数,而产生具有均匀直方图的输出图像。对于需要自动增强时,该算法仅需简单的操作就能扩展灰度级,且结果可以预知,因此是一种好方法。但是,不同图像出现的问题不尽相同,有时我们需要根据图像的某种缺陷,得出处理后的图像需要具有某种形状的直方图。因此,均衡化这样单一的方法显然不能成为万能钥匙。这时,就轮到直方图规定化技术登场了。规定化,顾名思义,就是规定好输出图像应该具有什么样形状的直方图。那么,这个“形状”该怎么规定呢?通常,我们指定一个规定的概率函数来表示所需的直方图,常用的有均匀分布函数、指数分布函数、双曲分布函数、高斯分布函数……

        接着讨论如何实现直方图的规定化,以下是书中的推导(由于仍存在不理解的部分,暂且放弃自己推导)。注意,r和z分别表示输入图像和输出(已处理)图像的灰度级。

令s为一个具有如下特性的随记变量:

不难发现,这个式子就是前面推导的直方图均衡化的连续形式。

        接着,我们定义一个有如下特性的随记变量z:

(重点来了,画圈圈的地方我不是很懂,为什么令s等于G(z),推出来的结果就能使z的pdf等于r的pdf?)为了继续下去,我只有先假装认同这个任何书上都一笔带过的步骤(可能是我太笨了)。

         由这两个等式可得G(z)=T(r),因此就可以求出z:

        总结来说,按照下列步骤,就可由一幅给定图像得到一幅灰度级具有指定概率密度函数的图像:

            1.由输入图像得到p(r),并求出s.

            2.由指定的概率密度函数求出G(z).

            3.求得反变换函数,并对所有输入像素应用第三个公式,即可求出输出图像.

       实现的时候,需要利用上述公式的离散形式。重写如下:

其中符号与直方图均衡化中相同。

    对一个q值,有:

与前面一样,利用反变换找到期望的z值:

实现上述公式的重点在于:该操作对每一个s值给出一个z值。这样,就形成了从s到z的一个映射。因此,实际中,我们并不需要计算G的反变换。计算q=0,1,2,…,L-1时的所有可能的G值是一件简单的事情。标定这些值,并取整。将这些值存储在一个表中,然后,给定一个特殊的Sk值后,我们可以查找存储在表中的最匹配值(离散情况下,不一定能找到相等的值,此时就要找最接近的值,即最匹配!)。重复该过程,我们将找到所有s值到z值的映射(当满足给定s值的z值多于一个时,即映射不唯一时,按惯例选择最小的值),他们就是最接近的解。

(2)编码实现

        目前来说,在上述说到的查找最匹配的映射过程中,存在两种映射方法:单映射规则(SML)和组映射规则(GML)。具体区别很值得琢磨,以后另写一篇博文再研究,下面先用单映射规则编码实现。

% ***************************Copyright 2016[c]**************************
% ************************Declaration************************************
% File name:        histogram_specification
% Author:           靖Harry                                        
% Date:             22-Jul-2016 22:10:28                                  
% Version Number:   1.0
% Abstract:  
%   Transforms the original intensity image so that the histogram
%   of the output image with length bins approximately matches 
%   the specified histogram.            
% *********************************end*********************************
clear
clc
I1=imread('0.tif');
[m,n]=size(I1);
L=256;  % 灰度级

%对输入图像均衡化
nk=zeros(1,256);
for i1=1:m
    for j1=1:n
        nk(I1(i1,j1)+1)=nk(I1(i1,j1)+1) + 1 ;
    end
end
pk=nk/(m*n); 
sk=zeros(1,256);
for i2=1:L
    for j2=1:i2
        sk(i2)=sk(i2)+pk(j2);
    end
end
sk=fix((L-1)*sk);  % 取整数部分.

%规定化直方图
counts=[zeros(1,49),0.1,zeros(1,49),0.2,zeros(1,49),0.3,zeros(1,49),0.1,zeros(1,49),0.2,zeros(1,49),0.1]; 

%对规定直方图进行均衡化
gk=zeros(1,256);
     for i3=1:256
       for j3=1:i3
          gk(i3)=counts(j3)+gk(i3);                 
       end
     end     
 gk=fix((L-1)*gk);   % 取整数部分.

 %SML映射规则
for i=1:256
   minvalue=abs(sk(i)-gk(1)); %先假设与第一个G值为最小间距
   T(i)=0;
   for j=2:256
      if abs(sk(i)-gk(j))<minvalue
         minvalue= abs(sk(i)-gk(j)); %求出最小距离值,即最匹配值
         T(i)=j-1;     %建立映射关系
      end
   end
end

%将映射的结果组合成输出图像
I2=I1;
for i5=1:m
   for j5=1:n
      I2(i5,j5)=T(I2(i5,j5)+1); 
   end
end

subplot(2,2,1),imshow(I1),title('原图像');
subplot(2,2,2),bar(1:300,counts,'r'),title('规定直方图');
subplot(2,2,3),histeq(I1,counts),title('histeq函数处理结果');
subplot(2,2,4),imshow(I2),title('我的函数处理结果');

untitled.jpg

         很明显可以看到,我写的函数处理的结果与matlab自带函数处理的结果仍有区别,我没看histeq函数内部的实现(其实是看不懂),在此做一个猜想:由于histeq函数采用的是组映射(GML)规则,而我的函数采用的是单映射(SML)规则。从前人的经验来看,采用SML映射方式,所得结果与规定直方图差距较大,而GML映射的结果,基本与规定直方图一致。两者相比较,GML映射规则的优势十分明显。具体映射规则的内容及差异下回再好好研究,在此先不做讨论。

Baidu
map