用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