CrazyBingo

直方图均衡化算法Matlba测试与FPGA改进方案

0
阅读(8409)

直方图均衡化算法Matlba测试与FPGA改进方案

—CrazyBingo

—20141027

直方图均衡化在数字图像处理中,有很广泛的应用。比如低照度算法,透雾等,就可以用最基本的直方图均衡算法来实现。当然仅对于这两种算法优化而言,还是远远不够的。只不过对于理解图像而言,已经有很大的意义。

直方图均衡算法在很多书中都有详细的描述,典型的有冈萨雷斯《数字图像处理Matlab版》和《数字图像处理C语言版》,当然网上有too many的论人可查阅,以及很多和我一样乐于与大家分享,勤劳的写博客的朋友们。典型的看了几个人的博客,网址如下:

http://www.cnblogs.com/WilsonPan/archive/2009/10/23/2533266.html

http://blog.csdn.net/zrongh/article/details/7302816

http://blog.chinaunix.net/uid-24517893-id-2870515.html

直方图均衡算法,说白了,就是将一副低动态的图像,拉伸为宽动态。

何为低动态,就是图像像素值集中在某一区域,没有在【0,255】内均匀分布,这使得我们看着图像很压抑,施展不开的感觉。而我们的目的,就是为了将一副低动态的图像,拉伸至宽动态,在一定程度上来增强图像的效果。在此只考虑256级的灰度图像,进行最基本的直方图均衡算法讲解。

实现我们要知道每一级灰度的概率(PDF),继而计算[0,255]灰阶出现的累积概率,最后将初始值映射回去,得到最终的像素点。实现方式如下:

(1) 首先,我随便找了一副效果较差的晚上的图,如下所示:

clip_image002

(2) 计算[0,255]的概率分布,如下所示:

image

其中nk为当前灰阶在图像中出现的个数,而n=h*w为图像的总像素,其概率分布Matlab代码如下:

%------------------------------------------------
%【2】计算每个灰阶出现的个数
Num = zeros(1,256); 
for i = 1 : h
    for j = 1 : w
            Num(IMG1(i,j)+1) =  Num(IMG1(i,j)+1) + 1;
    end
end

%------------------------------------------------
%【3】计算每个灰阶出现的概率,并绘制直方图(归一化后)
P = zeros(1,256);
for i = 1:256
    P(i) = Num(i)/(h*w);
end
subplot(2,3,2);  
bar(0:255,P,'b');       %绘制直方图
xlim([0 255]);          %将横坐标限定在0~255
title('归一化直方图');
xlabel('灰阶');
ylabel('概率 ');
为了更明显的表示这幅图像的辍,以上画出了直方图,如下所示,课件图像基本徘徊在暗处:

clip_image006

(3) 继而计算累计概率分布,即计算0~n阶概率出现的几率,公式如下:

image

这里给出Matlab代码,如下所示:

%------------------------------------------------ 
%【4】在P后计算累计的归一化直方图
S = zeros(1,256);
for i = 1 : 256
    for j = 1 : i
            S(i) =  S(i) + P(j);
    end
end
subplot(2,3,3);  
bar(0:255,S,'k');       %绘制直方图
xlim([0 255]);
title('累计后的归一化直方图 ');
xlabel('灰阶');
ylabel('概率 ');


如上也绘制了直方图,其变化基本在暗处,如下图所示:

clip_image010

(4) 直方图的均衡化,是为了将灰阶的变换,拉升到整个区域,即0~255均衡的变换,这里我们采用像素的映射,将图像改变到另一个空间域,典型的公式有如下:

image

从公式可见,映射后的值即当前像素的累积概率 * 255,而乘以255的原因,就是因为前面是归一化的值,这里Matlab的实现如下所示:

%【5】直方图均衡化
IMG2 = zeros(h,w);
for i = 1 : h
    for j = 1 : w
            IMG2(i,j) = floor(S(IMG1(i,j)+1)*255);
    end
end
subplot(2,3,4);
imshow(uint8(IMG2));    %显示最终的图像
title('均衡后图像 ');


给出均衡化后的图像,如下所示,课件图像明显的可以看得清楚了(当然后续还需要进行降噪处理)。

clip_image014

(5) 再看下算法改进后图像直方图与累计概率的直方图,如下图所示,课件图像在整个区域平均铺开,变化均匀,一直协调,不再那么压抑!

clip_image016

为了更充分的说明算法的可靠性,再找几幅图像给你们对比一下,如下几个例子:

clip_image018clip_image020

clip_image022clip_image024

算法如此简单,总结如下:

 

image

 

试问,这样的算法适合移植到FPGA中吗??

从第一步到第三步,每一步都涉及了浮点运算,FPGA还不崩溃啊!!下面对公式进行改变,我们不进行归一化的计算,直接在整形计算运算,如下:

观察改进后的公式,分为如下三个不走:

(1) 计算每个灰阶出现的个数:这用FPGA统计很容易

(2) 计算灰度的累积出现个数:FPGA中来个256的状态机就完事了

(3) 进行像素的映射:结果必然在[0,255],而且分母远大于分子,不会出现浮点

这样做,就可以轻松的移植到FPGA中去了,至于怎么实现,小伙伴们自己努力吧!!!


继续秀: