lemonHe

主要关注FPGA信号处理和数字图像处理技术,欢迎交流 邮箱:heliminlemon@163.com

直方图均衡的改进-平台直方图及其实现

0
阅读(7604)

 

    之前写过一篇关于直方图均衡及其FPGA实现的博文,该算法通过一个变换函数对输入直方图进行修正,使得修正后的图像直方图趋于均匀,从而增大图像灰度级的动态范围。实质上这种算法是有选择地对占有较多像素的灰度进行了增强,扩展了这些灰度的动态范围,对占有较少像素的灰度进行了抑制,导致实际工程中往往不直接使用直方图均衡,我在实际工程中用的是平台直方图均衡算法,加入了高低两个平台。

    下面结合传统直方图均衡来说说平台直方图。

    传统直方图增强步骤大体可以分为3步:

1) 统计直方图信息

    即统计每个灰度级的像素点个数blob.pngblob.png是第K级灰度值

    统计部分matlab代码如下:

%%实现统计
for i = 1:1:height
    for j = 1:1:width           
        s(I(i,j)+1)=s(I(i,j)+1)+1;
    end
end


2) 累计直方图信息

将统计得到的灰度级信息累计,累计公式如下:

clip_image006

    仔细观察会发现,上式使得灰度值高的像素点映射后会比灰度值低的像素点亮,这是图像增强的基本准则。

    前面说过,传统直方图增强算法是有选择地对占有较多像素的灰度进行了增强,扩展了这些灰度的动态范围,对占有较少像素的灰度进行了抑制,从上式可以看出,占有较多像素点的灰度,均衡后会比前一级出现的灰度亮许多,而占有较少像素点的灰度,均衡后可能和前一级出现的灰度相差很小甚至可能被合并。这也是传统直方图均衡的缺点。

    累计部分matlab代码如下:

p = zeros(1,2^8);
%%得到累积分布
p(1) = s(1);
for i = 2:1:2^8
    p(i) = p(i-1)+s(i);
end


3) 映射

    针对输入的每一个灰度值blob.png,输出:

        blob.png ,其中MN为像素总数。

    映射部分matlab代码如下:

%%实现映射
for i = 1:1:height
    for j=1:1:width
        I(i,j)=c(I(i,j)+1);
    end
end


    下面来说说平台直方图,相较于传统直方图均衡算法,平台直方图算法统计完成后需对直方图信息作修正,我们设定两个阈值—高平台值和低平台值。高平台对背景和噪声进行抑制,下平台对小目标和细节进行放大,高平台值越小,图像越暗;低平台值越大,图像越亮(高平台值大于像素总数,低平台值为0时,该算法就变成了传统直方图均衡算法)。

    直方图值大于高平台值时,令其等于高平台值;小于高平台值时,令其等于低平台值。公式如下:

clip_image012

    平台判断部分matlab代码如下:

%加入高低平台,也就是对直方图值作一个判断,大于高平台值时,令其等于高平台值
%小于高平台值时,令其等于低平台值
for i = 1:1:2^8
    if(s(i)>=highPlateau)
        s(i) = highPlateau;
    else if(s(i)<=lowPlateau)
            s(i) = lowPlateau;
        end
    end
end


    需要说明的是,在实际工程中,加入低平台后,会使得直方图累计和增大,可能超过像素总数,超过像素总数会数据会出现溢出,为了这种现象产生,需对直方图累计和作阈值判断,即如果

            blob.png,则

            blob.png

    该部分matlab代码如下:

%对直方图进行判断,防止出现溢出
%如果不加平台,加入低平台后可能出现p(i)>height*width的情况
for i = 1:1:2^8
    if(p(i)>=height*width)
        p(i) = height*width;
    end
end


    整个工程Matlab代码如下:

function imOut = phistogram_8bit_gray(imPri,highPlateau,lowPlateau)
%imPri为8bit灰度图像
%highPlateau为PHE的高平台值
%lowPlateau为PHE的低平台值
%imOut为校正后输出的8bit图像

I = imPri;
[height,width] = size(I);
s = zeros(1,2^8);
figure;
subplot(2,2,1);
imshow(I);      %显示原图像
title('原图像');
subplot(2,2,2);
imhist(I);      %显示原图像hist
title('原图像hist');

%%实现统计
for i = 1:1:height
    for j = 1:1:width           
        s(I(i,j)+1)=s(I(i,j)+1)+1;
    end
end

%加入高低平台,也就是对直方图值作一个判断,大于高平台值时,令其等于高平台值
%小于高平台值时,令其等于低平台值
for i = 1:1:2^8
    if(s(i)>=highPlateau)
        s(i) = highPlateau;
    else if(s(i)<=lowPlateau)
            s(i) = lowPlateau;
        end
    end
end

p = zeros(1,2^8);
%%得到累积分布
p(1) = s(1);
for i = 2:1:2^8
    p(i) = p(i-1)+s(i);
end

%对直方图进行判断,防止出现溢出
%如果不加平台,加入低平台后可能出现p(i)>height*width的情况
for i = 1:1:2^8
    if(p(i)>=height*width)
        p(i) = height*width;
    end
end

%%得到累积分布概率
c = p / (height*width);
c = uint8((2^8-1).*c+0.5);
%%实现映射
for i = 1:1:height
    for j=1:1:width
        I(i,j)=c(I(i,j)+1);
    end
end
subplot(2,2,3);
imshow(I);  %显示均衡后图像
title('均衡后图像');
subplot(2,2,4);
imhist(I);  %显示均衡后图像hist
title('均衡后图像hist');
imOut = I;


    函数调用:

clear;
close all;
imIn = imread('Fig0309(a)(washed_out_aerial_image).tif');
imOut_PHE = phistogram_8bit_gray(imIn,6000,300);
imout_HE = histogram_8bit(imIn);
figure;
imshow(imIn);
figure;
subplot(1,2,1);
imshow(imOut_PHE);
title('平台直方图均衡后图像');
subplot(1,2,2);
imshow(imout_HE);
title('直方图均衡后图像');


    下面给出处理结果图

clip_image018

上图为输入图像,下图为平台直方图均衡与传统直方图均衡后的输出图像。

clip_image020



clip_image024

    结合上面这张图和前面的分析,可以知道,直方图均衡后图像中较亮部分在均衡前占有较多像素点,而平台直方图较好的抑制了这种现象。

    当然,平台直方图在FPGA上的实现相较于传统直方图来说,也只是多增加几条判断语句,难度不算大!!


    自己都觉得写的很哆嗦,各位看官,将就将就咯。



参考资料:

1. Plateau equalization algorithm for real-time display of high-quality infrared imagery-optical engineering-1996

2. 基于双平台直方图的红外图像增强算法