用verilog实现直方图均衡(一)


首先,直方图均衡发展到现在,以及有许多版本,比如CLAHE,笔者在这里先只写自己如何实现最普通的HE。

实现直方图均衡前,需要先实现直方图统计。

直方图统计就是统计一副图像中各灰度级的像素数量,比如:

 

 FPGA实现:

首先,需要一个RAM来存储统计的数据,数据位宽视图像大小而定,比如一副1024x768的图,考虑最极端的情况,全部是同一个灰度级,那么数据位宽就是20位,地址位宽8位,因为灰度级是0到255。

其次,考虑如何统计,笔者参考《基于FPGA的数字图像处理原理及应用》,比较前后两个像素点,若相同则计数器加一;若不同则计数器重置为1,且此时写使能有效,写数据为读数据加计数器重置前的值。

可能有点绕,下面是时序图,de代表data_in有效,de1是de的一个延迟,de2是de的两个时延:

 

并且每行最后一个数据时,写使能也要有效,可以通过判断de的下降沿来实现。

每一行的计数都是这样,然后在计数完之后,还需要进行清零,以等待下一帧图像。清零的判断可以通过行计数器row_cnt来实现,每次在de的下降沿加一,假设图像的行数为IH,那么row_cnt计数到IH时表示清零开始,写使能有效,然后此时写地址从0加到255,写数据为0,当写地址加到255时,写使能无效。

完整代码如下:

  1 module he_top(
  2 input clk,
  3 input reset_n,
  4 input [7:0]data_in,
  5 input vs,
  6 input hs,
  7 input de,
  8 output [19:0]he_calculate,
  9 output o_he_de,
 10 output [7:0]o_he_addr
 11 
 12 );
 13 localparam IH='d768;
 14 reg de_r;
 15 reg de_r2;
 16 reg hs_r;
 17 reg vs_r;
 18 reg [9:0]CNT;
 19 wire CNT_en;
 20 reg [7:0]rd_addr;
 21 reg [7:0]wr_addr;
 22 wire wr_en;
 23 
 24 wire [19:0]rd_data;
 25 wire [19:0]wr_data;
 26 reg [19:0]rd_data_r;
 27 
 28 
 29 reg [9:0] row_cnt;
 30 wire row_cnt_en;
 31 reg [1:0] hs_reg;
 32 
 33 reg [7:0]po_cnt;
 34 reg calculate_end;
 35 reg [1:0]calculate_end_r;
 36 
 37 always@(posedge clk or negedge reset_n)begin
 38 if(!reset_n)begin
 39 de_r<=0;
 40 de_r2<=0;
 41 end
 42 else begin
 43 de_r<=de;
 44 de_r2<=de_r;
 45 end
 46 end
 47 
 48 always@(posedge clk or negedge reset_n)begin
 49 if(!reset_n)
 50 hs_r<=0;
 51 else
 52 hs_r<=hs;
 53 end
 54 
 55 always@(posedge clk or negedge reset_n)begin
 56 if(!reset_n)
 57 vs_r<=0;
 58 else
 59 vs_r<=vs;
 60 end
 61 
 62 always@(posedge clk or negedge reset_n)begin
 63 if(!reset_n)
 64 rd_addr<=0;
 65 else if(de==1'b1)
 66 rd_addr<=data_in;
 67 else if(calculate_end==1'b1)
 68 rd_addr<=po_cnt;
 69 end
 70 
 71 
 72 always@(posedge clk or negedge reset_n)begin
 73 if(!reset_n)
 74 wr_addr<=0;
 75 else
 76 wr_addr<=rd_addr;
 77 end
 78 
 79 assign CNT_en=(rd_addr==wr_addr)?de_r2:0;
 80 always@(posedge clk or negedge reset_n)begin
 81 if(!reset_n)
 82 CNT<=1'b1;
 83 else if(CNT_en==1'b1)
 84 CNT<=CNT+1'b1;
 85 else if(CNT_en==0)
 86 CNT<=1'b1;
 87 else
 88 CNT<=CNT;
 89 end
 90 
 91 always@(posedge clk or negedge reset_n)begin
 92 if(!reset_n)
 93 rd_data_r<=0;
 94 else
 95 rd_data_r<=rd_data;
 96 end
 97 
 98 assign wr_en=(rd_addr==wr_addr)?0:de_r2;
 99 assign wr_data=calculate_end_r[1]?0:(CNT+rd_data_r);
100 
101 always@(posedge clk or negedge reset_n)begin
102 if(!reset_n)begin
103 hs_reg[0]<=0;
104 hs_reg[1]<=0;
105 end
106 else begin
107 hs_reg[0]<=hs;
108 hs_reg[1]<=hs_reg[0];
109 end
110 end
111 
112 assign row_cnt_en=((!de_r)&&(de_r2))?1'b1:0;
113 
114 
115 always@(posedge clk or negedge reset_n)begin
116 if(!reset_n)
117 row_cnt<=0;
118 else if((row_cnt_en==1'b1)&&(row_cnt<=IH-1))
119 row_cnt<=row_cnt+1'b1;
120 else if(row_cnt==IH)
121 row_cnt<=0;
122 end
123 
124 
125 
126 always@(posedge clk or negedge reset_n)begin
127 if(!reset_n)
128 calculate_end<=0;
129 else if(row_cnt==IH)
130 calculate_end<=1'b1;
131 else if(po_cnt==8'd255)
132 calculate_end<=0;
133 else
134 calculate_end<=calculate_end;
135 end
136 
137 
138 always@(posedge clk or negedge reset_n)begin
139 if(!reset_n)
140 calculate_end_r<=0;
141 else
142 calculate_end_r<={calculate_end_r[0],calculate_end};
143 end
144 
145 
146 always@(posedge clk or negedge reset_n)begin
147 if(!reset_n)
148 po_cnt<=0;
149 else if(calculate_end==1'b1)
150 po_cnt<=po_cnt+1'b1;
151 end
152 
153 assign he_calculate=calculate_end_r[0]?rd_data:0;
154 wire he_wr_en;
155 assign he_wr_en=(wr_en)||(row_cnt_en)||(calculate_end_r[1]);
156 
157 assign o_he_de=calculate_end_r[0];
158 assign o_he_addr=calculate_end_r[0]?rd_addr:0;
159 
160 he_cal he_cal_t1 (
161 .wr_data(wr_data), // input [19:0]
162 .wr_addr(wr_addr), // input [7:0]
163 .rd_addr(rd_addr), // input [7:0]
164 .wr_clk(clk), // input
165 .rd_clk(clk), // input
166 .wr_en(he_wr_en), // input
167 .rst(!reset_n), // input
168 .rd_data(rd_data) // output [19:0]
169 );
170 
171 endmodule

 

也可以用状态机来写,笔者就不详述了。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM