中值濾波
將 3*3 滑動塊中的灰度值進行排序,然后用排序的中間值取代 3*3 滑塊中心的值。示意圖如下圖所示。
實現原理(這是文獻中的,理解起來比較復雜,最近我又學到一種更加簡單快捷的方法,補充在最后)
通過如下圖所示的6級比較電路路輸出中值,其輸人數據為圖1所示的濾波掩膜所在的圖像數據。第一級比較電路由3個三輸入比較器C組成,每個比較器的輸出數據依序排列(參見圖示)。將3組比較結果中最小的3個數放在一起、中間的3個數放在一起、最大的3個數放在一起,參加第二級比較。第二級比較電路的原理與第一級類似,輸出out1和out9,分別是輸入數據中的最大值和最小值,這2個數據將被舍去不參加下一級比較。參加第三級比較的有7個數據,其原理類似於前兩級比較電路,輸出out2和out8分別是該7個數據的最大值和最小值,並且被舍去,僅留下5個數據參加第四級比較。剩下的幾級比較電路以類似於先前的原理進行比較。如此,經過6級比較后即可得到9個數據的標准中值濾波輸出值out5,而outl,out2,⋯,out9分別是這9個數據從最大到最小的順序排列值。此外。為了保證流水線操作過程中數據的同步性,在第三級和第五級比較電路中需要插入數據寄存器R緩存當前該級中不參與比較的數據。

說明:中值濾波也是基於3*3的像素矩陣,有關3*3矩陣的實現,在上一篇文章中詳細講過鏈接如下:http://www.cnblogs.com/aslmer/p/5779079.html。
此原理多次用到比較器,我將比較器分為兩類,第一類:三個數進行比較,輸出max、med、min。第二類:兩個數進行比較,輸出max、min。
第一類比較器的實現
module compare_1( data_a , data_b , data_c , data_max , data_min , data_med ); input [5:0] data_a ; input [5:0] data_b ; input [5:0] data_c ; output [5:0] data_max; output [5:0] data_min; output [5:0] data_med; wire [5:0] data_max; wire [5:0] data_min; wire [5:0] data_med; wire [5:0] a,b,c;//a,b,c代替三個輸入,方便代碼書寫 assign a=data_a; assign b=data_b; assign c=data_c; assign data_med = (a<b)?(b<c)?b:(a>c)?a:c : (b>c)?b:(a<c)?a:c; assign data_min = (a<b)?(a<c)?a:c : (b>c)?c:b ; assign data_max = (a>b)?(a>c)?a:c : (b>c)?b:c ; endmodule
第二類比較器就是比較兩個數大小,非常簡單。
module compare_2 ( dat_1 , dat_2 , dat_max , dat_min ); input [5:0] dat_1 ; input [5:0] dat_2 ; output [5:0] dat_max; output [5:0] dat_min; wire [5:0] dat_max; wire [5:0] dat_min; assign dat_max=(dat_1>dat_2)? dat_1:dat_2; assign dat_min=(dat_1>dat_2)? dat_2:dat_1; endmodule
然后不斷調用一類和二類比較器,實現六級比較電路
//---------------------------------------------------------------------- 第一階段 // 第一階段 max11 第一階段1 compare u11_compare( .data_a (p_11) , // 3*3矩陣第一行第一個數 .data_b (p_12) , // 第二個 .data_c (p_13), // 第三個 .data_max (max11), .data_min (min11), .data_med (med11) ); //求第二行的最大值,最小值,中間值 compare u12_compare( .data_a (p_21), //3*3矩陣第二行 .data_b (p_22),// .data_c (p_23),// .data_max(max12), .data_min(min12), .data_med(med12)); //求第三行的最大值,最小值,中間值 compare u13_compare( .data_a (p_31) , //3*3矩陣第三行 .data_b (p_32) ,// .data_c (p_33) ,// .data_max(max13) , .data_min(min13) , .data_med(med13) ); always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin max_p1_1<=0; //第一行的最大數 max_p1_2<=0; // 中間數 max_p1_3<=0; // 最小數 min_p1_1<=0; //第二行的最大數 min_p1_2<=0; // 中間數 min_p1_3<=0; // 最小數 med_p1_1<=0; //第三行 med_p1_2<=0; med_p1_3<=0; end else if(per_href_ff1==1&&flag_do==1)begin max_p1_1<=max11; max_p1_2<=max12; max_p1_3<=max13; min_p1_1<=min11; min_p1_2<=min12; min_p1_3<=min13; med_p1_1<=med11; med_p1_2<=med12; med_p1_3<=med13; end else begin max_p1_1<=0; max_p1_2<=0; max_p1_3<=0; min_p1_1<=0; min_p1_2<=0; min_p1_3<=0; med_p1_1<=0; med_p1_2<=0; med_p1_3<=0; end end //---------------------------------------------------------------------- 第二階段 //最大值的大中小 compare u14_compare( .data_a (max_p1_1) , .data_b (max_p1_2) , .data_c (max_p1_3) , .data_max(max_2_max) , .data_min(max_2_min) , .data_med(max_2_med) ); //最小值中的大中小 compare u15_compare( .data_a (min_p1_1) , .data_b (min_p1_2) , .data_c (min_p1_3) , .data_max(min_2_max) , .data_min(min_2_min) , .data_med(min_2_med) ); //中的大中小 compare u16_compare( .data_a (med_p1_1) , .data_b (med_p1_2) , .data_c (med_p1_3) , .data_max(med_2_max) , .data_min(med_2_min) , .data_med(med_2_med) ); always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin //max_p2_max<=0; max_p2_min<=0; max_p2_med<=0; min_p2_max<=0; // min_p2_min<=0; min_p2_med<=0; med_p2_max<=0; med_p2_min<=0; med_p2_med<=0; end else if(per_href_ff2==1&&flag_do==1) begin // max_p2_max<= max_2_max; //舍棄最大值 max_p2_min<= max_2_min; max_p2_med<= max_2_med; min_p2_max<= min_2_max; // min_p2_min<= min_2_min;//舍棄的最小值 min_p2_med<= min_2_med; med_p2_max<= med_2_max ; med_p2_min<= med_2_min ; med_p2_med<= med_2_med ; end else begin // max_p2_max<=0; max_p2_min<=0; max_p2_med<=0; min_p2_max<=0; // min_p2_min<=0; min_p2_med<=0; med_p2_max<=0; med_p2_min<=0; med_p2_med<=0; end end //----------------------------------------------------------------------第三階段ff4 //最大 compare u17_compare( . data_a (max_p2_med), . data_b (min_p2_max), . data_c (med_p2_max), . data_max(), . data_min(max_3_min), . data_med(max_3_med) ); //最小 compare u18_compare( . data_a (max_p2_min), . data_b (med_p2_min), . data_c (min_p2_med), . data_max(min_3_max), . data_min(), . data_med(min_3_med) ); always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin max_p3_med <=0 ; max_p3_min <=0 ; med_p3 <=0 ; min_p3_max <=0 ; min_p3_med <=0 ; end else if(per_href_ff3==1&&flag_do==1)begin max_p3_med <= max_3_med ; max_p3_min <= max_3_min ; med_p3 <= med_p2_med; min_p3_max <= min_3_max ; min_p3_med <= min_3_med ; end else begin max_p3_med <=0 ; max_p3_min <=0 ; med_p3 <=0 ; min_p3_max <=0 ; min_p3_med <=0 ; end end //----------------------------------------------------------------------第4階段 compare_2 u1_compare_2( .dat_1 (max_p3_med) , .dat_2 (max_p3_min), .dat_max (max_4_max), .dat_min (max_4_min) ); compare u19_compare( . data_a (med_p3), . data_b (min_p3_max), . data_c (min_p3_med), . data_max(min_4_max), . data_min(min_4_med), . data_med(min_4_min) ); always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin max_p4_max <=0 ; max_p4_min <=0 ; min_p4_max <=0 ; min_p4_med <=0 ; min_p4_min <=0 ; end else if(per_href_ff4&&flag_do==1)begin max_p4_max <=max_4_max ; max_p4_min <=max_4_min ; min_p4_max <=min_4_max ; min_p4_med <=min_4_med ; min_p4_min <=min_4_min ; end else begin max_p4_max <=0 ; max_p4_min <=0 ; min_p4_max <=0 ; min_p4_med <=0 ; min_p4_min <=0 ; end end //----------------------------------------------------------------------第5階段 compare_2 u2_compare_2( .dat_1 ( max_p4_max), .dat_2 ( min_p4_max), .dat_max (), .dat_min (max_5_min) ); // compare_2 u3_compare_2( .dat_1 ( min_p4_min), .dat_2 ( max_p4_min), .dat_max (min_5_max), .dat_min () ); always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin max_p5_min<=0; min_p5_max<=0; med_p5 <=0; end else if(per_href_ff5==1&&flag_do) begin max_p5_min<= max_5_min; min_p5_max<= min_5_max; med_p5 <= min_p4_med; end end //----------------------------------------------------------------------第6階段。 // compare u10_compare( .data_a (max_p5_min), .data_b (min_p5_max), .data_c (med_p5 ), .data_max(max_6_max), .data_min(max_6_min), .data_med(max_6_med) );
處理后的結果
補充 :
快速排序法實現中值濾波
第一步:將每一行按最大值、中間值、最小值排列
第二步:提取出最大值的最小值,中間值的中間值,最小值的最大值
第三步:將第二步提取出來的三個數進行排序,中間值即我們要求的中間值。
代碼很簡單,就不寫了。
轉載請注明出處:http://www.cnblogs.com/aslmer/p/5786978.html