verilog 實現中值濾波


圖像信號在形成、傳輸和記錄的過程中,由於成像系統、 傳輸介質、工作環境和記錄設備等的固有缺陷,不可避免地產 生各種類型的噪聲,降低了圖像的質量,進而影響后續處理( 如邊緣檢測、圖像分割、特征提取、模式識別等)的效果或 准確性。因此,對噪聲圖像進行濾波是必要預處理過程。但濾 波算法在去除噪聲的同時難免對圖像造成一定程度的模糊,造 成細節信息的丟失。
中值濾波是對一個滑動窗口內的諸像素灰度值排序,用其中值代替窗口中心象素的原來灰度值,它是一種非線性的圖像平滑法,它對脈沖干擾級椒鹽噪聲的抑制效果好,在抑制隨機噪聲的同時能有效保護邊緣少受模糊。

中值濾波

將 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

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM