• 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

      

  • 相关阅读:
    Android:RelativeLayout相对布局(转)
    Android:LayoutInflater作用及使用(转)
    keepalive安装配置
    nginx 多级7层代理安装配置
    k8s使用cephfs
    haproxy安装及配置
    通过nodeSelector配置项实现pod部署至指定node
    SFTP使用key文件登录
    k8s使用ceph存储
    nginx开启gzip压缩后导致apk包下载不能正常安装
  • 原文地址:https://www.cnblogs.com/aslmer/p/5786978.html
Copyright © 2020-2023  润新知