zoukankan      html  css  js  c++  java
  • FPGA实现图像的直方图均衡化

      直方图均衡化又称为灰度均衡化,是指通过某种灰度映射使输入图像转换为在每一灰度级上都有近似相同的输出图像(即输出的直方图是均匀的)。在经过均衡化处理后的图像中,像素将占有尽可能多的灰度级并且分布均匀。因此,这样的图像将具有较高的对比度和较大的动态范围。直方图均衡可以很好地解决相机过曝光或曝光不足的问题。

    一、MATLAB实现

    %--------------------------------------------------------------------------
    %                         直方图均衡化
    %--------------------------------------------------------------------------
    close all
    clear all;
    clc;
    
    I = rgb2gray(imread('car.bmp'));
    Ieq=histeq(I);
    
    subplot(221),imshow(I);title('原图');
    subplot(222),imhist(I);
    subplot(223),imshow(Ieq);title('直方图均衡化');
    subplot(224),imhist(Ieq);

      点击运行,得到如下结果:

      从结果可以看出:图片对比度显著提高,直方图变得更均匀。

    二、FPGA实现

    1、理论分析

      直方图均衡化的公式如下所示,H(i)为第 i 级灰度的像素个数,A0为图像的面积(即分辨率),Dmax为灰度最大值,即255。

    2、实现步骤

      和直方图拉伸的情况一样,直方图均衡化也分为真均衡化和伪均衡化。本次设计采用伪均衡化,即采用前一帧的图像进行统计、累计和、归一化,当前帧做均衡化的数据输出。

      统计工作至少要等到前一帧图像“流过”之后才能完成。此限制决定了我们难以在同一帧既统计又输出最终拉伸结果。必须对前期的统计结果进行缓存、累计和、归一化,这点是毋庸置疑的。在下一次统计前需要将缓存结果、累计和结果清零,而归一化的结果则留着给当前帧输出使用。我们可以按一下步骤来实现:

      (1)前一帧:计算图像的直方图 H(i)

      (2)前一帧:计算直方图累计和

      (3)前一帧到当前帧的空隙:归一化,即

      (4)当前帧:均衡化后的数据输出

    3、Verilog设计

      先说归一化,归一化就是 *255 / 分辨率,我此次的屏幕分辨率是 480x272,经过计算,归一化的参数为 255 / 480x272 = 2 ^(-9),即计算出累计和后,结果右移9位即可。

      书本《基于FPGA的数字图像处理原理及应用》中采用了 RAM 的方式来实现上述设计,该设计代码较复杂。OpenS Lee 前辈给出了一种新的实现方式:数组。使得整个设计变得异常的简洁,关键代码如下所示:

      1 //**************************************************************************
      2 // *** 名称 : Hist_equalization.v
      3 // *** 作者 : xianyu_FPGA
      4 // *** 博客 : https://www.cnblogs.com/xianyufpga/
      5 // *** 日期 : 2020年3月
      6 // *** 描述 : 直方图均衡化(伪),刚好右移9位即可
      7 //--------------------------------------------------------------------------
      8 //            Dmax        = 255                     255
      9 //            A0          = 480000(600x800)         130560(480x272)
     10 //            Dmax/A0     = 0.00053125              0.001953125 = 2^(-9)
     11 //            *2^20       = 557
     12 //**************************************************************************
     13 module Hist_equalization
     14 //========================< 端口 >==========================================
     15 (
     16 input   wire                clk                     ,
     17 input   wire                rst_n                   ,
     18 //---------------------------------------------------
     19 input   wire                Y_de                    ,
     20 input   wire                Y_hsync                 ,
     21 input   wire                Y_vsync                 ,
     22 input   wire    [ 7:0]      Y_data                  ,
     23 //---------------------------------------------------
     24 output  reg                 hist_de                 ,
     25 output  reg                 hist_hsync              ,
     26 output  reg                 hist_vsync              ,
     27 output  reg     [ 7:0]      hist_data                
     28 );
     29 //========================< 参数 >==========================================
     30 parameter IDLE              = 4'b0001               ; //空闲
     31 parameter STATISTICS        = 4'b0010               ; //统计
     32 parameter ACCUMULATION      = 4'b0100               ; //累计和
     33 parameter NORMALIZATION     = 4'b1000               ; //归一化
     34 //========================< 信号 >==========================================
     35 reg     [ 3:0]              state                   ;
     36 wire                        pos_vsync               ;
     37 wire                        neg_vsync               ;
     38 reg     [16:0]              statistics[0:255]       ; //480x272 = 17位
     39 reg     [16:0]              accumulation[0:255]     ;
     40 reg     [ 7:0]              normalization[0:255]    ;
     41 reg     [ 7:0]              i,j,k                   ;
     42 //==========================================================================
     43 //==    帧开始和结束标志
     44 //==========================================================================
     45 assign pos_vsync =  Y_vsync && ~hist_vsync;
     46 assign neg_vsync = ~Y_vsync &&  hist_vsync;
     47 //==========================================================================
     48 //==    前一帧:直方图统计、累计和、归一化
     49 //==========================================================================
     50 always @(posedge clk or negedge rst_n) begin
     51     if(!rst_n) begin
     52         i <= 0;
     53         j <= 0;
     54         k <= 0;
     55         state <= IDLE;
     56     end
     57     else begin
     58         case(state)
     59             IDLE:       begin
     60                             if(pos_vsync) begin
     61                                 i <= 0;
     62                                 j <= 0;
     63                                 k <= 0;
     64                                 state <= STATISTICS;
     65                             end
     66                             else begin
     67                                 i <= i + 1;
     68                                 statistics[i] <= 0;
     69                                 accumulation[i] <= 0;
     70                             end
     71                         end
     72             STATISTICS: begin
     73                             if(Y_de) begin
     74                                 statistics[Y_data] <= statistics[Y_data] + 1;
     75                             end
     76                             else if(neg_vsync)
     77                                 state <= ACCUMULATION;
     78                         end
     79             ACCUMULATION:begin
     80                             if(j == 0) begin 
     81                                 accumulation[j] <= statistics[j];
     82                                 j <= j + 1;
     83                             end
     84                             else if(j > 0 && j < 255) begin
     85                                 accumulation[j] <= statistics[j] + accumulation[j-1];
     86                                 j <= j + 1;
     87                             end
     88                             else if(j == 255) begin
     89                                 accumulation[j] <= statistics[j] + accumulation[j-1];
     90                                 state <= NORMALIZATION;
     91                             end
     92                         end
     93             NORMALIZATION:begin
     94                             if(k < 255) begin
     95                                 normalization[k] <= accumulation[k][16:9] + {7'b0,accumulation[k][8]};
     96                                 k <= k + 1;
     97                             end
     98                             else if(k == 255) begin
     99                                 normalization[k] <= accumulation[k][16:9] + {7'b0,accumulation[k][8]};
    100                                 state <= IDLE;
    101                             end
    102                         end
    103             default:;
    104         endcase
    105     end
    106 end
    107 //==========================================================================
    108 //==    当前帧:输出直方图均衡后的数据
    109 //==========================================================================
    110 always @(posedge clk or negedge rst_n) begin
    111     if(!rst_n) begin
    112         hist_data <= 8'd0;
    113     end
    114     else if(Y_de) begin
    115         hist_data <= normalization[Y_data];
    116     end
    117 end
    118 //==========================================================================
    119 //==    信号同步
    120 //==========================================================================
    121 always @(posedge clk) begin 
    122     hist_de <= Y_de;
    123     hist_hsync <= Y_hsync;
    124     hist_vsync <= Y_vsync;
    125 end
    126 
    127    
    128    
    129 endmodule

    三、上板验证

      失败......因为数组消耗资源过大,我的小梅哥AC620支持不了,不过理论上应该没问题,原作者 OpenS Lee 在 Xilinx 板卡中上板成功,感兴趣的朋友可以试试。

    参考资料:

    1] OpenS Lee:FPGA开源工作室(公众号)

    [2] 牟新刚、周晓、郑晓亮.基于FPGA的数字图像处理原理及应用[M]. 电子工业出版社,2017.

  • 相关阅读:
    testng
    RF相关命令
    批处理bat相关
    VIM常用快捷键
    JAVA异常处理
    cucumber+selenium
    webDriver各版本对应
    python源码
    python之logging模块
    pywinauto进阶练习
  • 原文地址:https://www.cnblogs.com/xianyufpga/p/12531577.html
Copyright © 2011-2022 走看看