直方图均衡化算法Matlba测试与FPGA改进方案
0赞直方图均衡化算法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) 首先,我随便找了一副效果较差的晚上的图,如下所示:
(2) 计算[0,255]的概率分布,如下所示:
其中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('概率 ');为了更明显的表示这幅图像的辍,以上画出了直方图,如下所示,课件图像基本徘徊在暗处:
(3) 继而计算累计概率分布,即计算0~n阶概率出现的几率,公式如下:
这里给出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('概率 ');
如上也绘制了直方图,其变化基本在暗处,如下图所示:
(4) 直方图的均衡化,是为了将灰阶的变换,拉升到整个区域,即0~255均衡的变换,这里我们采用像素的映射,将图像改变到另一个空间域,典型的公式有如下:
从公式可见,映射后的值即当前像素的累积概率 * 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('均衡后图像 ');
给出均衡化后的图像,如下所示,课件图像明显的可以看得清楚了(当然后续还需要进行降噪处理)。
(5) 再看下算法改进后图像直方图与累计概率的直方图,如下图所示,课件图像在整个区域平均铺开,变化均匀,一直协调,不再那么压抑!
为了更充分的说明算法的可靠性,再找几幅图像给你们对比一下,如下几个例子:
算法如此简单,总结如下:
试问,这样的算法适合移植到FPGA中吗??
从第一步到第三步,每一步都涉及了浮点运算,FPGA还不崩溃啊!!下面对公式进行改变,我们不进行归一化的计算,直接在整形计算运算,如下:
观察改进后的公式,分为如下三个不走:
(1) 计算每个灰阶出现的个数:这用FPGA统计很容易
(2) 计算灰度的累积出现个数:FPGA中来个256的状态机就完事了
(3) 进行像素的映射:结果必然在[0,255],而且分母远大于分子,不会出现浮点
这样做,就可以轻松的移植到FPGA中去了,至于怎么实现,小伙伴们自己努力吧!!!
继续秀: