码迷,mamicode.com
首页 > 其他好文 > 详细

verilog实现中值滤波

时间:2016-06-13 15:18:08      阅读:350      评论:0      收藏:0      [点我收藏+]

标签:

前言

  项目需要,想要实现算法中的其中一步即中值滤波,同时,因为图像处理部分中值滤波相对来说还是比较简单的,将中值滤波的硬件实现作为进入FPGA领域的第一次尝试。虽然说网上有较多关于中值滤波的文档,可是说实话,其一没有详细地讲解实现方法及原因,其二没有关于完整过程的叙述,其三有些网站上有代码但是下载下来几乎没有用,因为你根本看不明白,俗话说得好,吃别人嚼过的馍真tm的没味儿还会难受。所以,还是需要自己静下心来分析原理、设计模块、编写实现以及仿真调试。对于FPGA新手来说,前三部分还能自己慢慢摸索,最后一步真的完全无措,这真的需要经验积累呀,那是你没办法搞定的,你觉得明明正确的语句可是在这里就是不行,就是不能这样来实现,只能先向大神求救,在这里真的要谢谢项目组的zjl,在他那里也学到很多FPGA的实现方法和注意事项。

 其实刚学习FPGA那会儿,先看的语法知识,感觉很简单,后来用的时候发现还是需要查找翻书,所以只有能够在实践过程中熟练应用才说明真正地掌握,宝宝还差得远呢!那些简单的数电的组合逻辑模块看得很明白,也很简单,毕竟本渣大学的数电也不是白学的!可是,一涉及到项目特别是搞图像算法的,感觉就晕头转向,茫然无措。其实宝宝还是很想在图像处理这个方向好好努力呢。偶然看到http://www.heijin.org/forum.php,网站上有很多学习资料,而且很适合软件转到FPGA的进行学习,宝宝就是看了他们的一些书之后慢慢会进行一些编程实现,真的要谢谢他们,非常非常期待他们的图像处理书籍的完成。

实现步骤

1.查看了中值滤波实现相关的网站和paper;

2.按照某篇paper的设计思想进行编程实现;

3.对各个模块进行语法检查、波形仿真、时序设计、调试验证;

4.与matlab的中值滤波结果进行比较。

 

实现过程:

1.查看了中值滤波实现相关的网站和paper;

在网上看了很多中值滤波的设计,也有一些代码可以下载,也有一片讲解的,只是感觉讲解的比较模糊而且不完整,最后看了几篇硕士论文,论文竟然主要做了中值滤波的工作,发现了一些设计思路,然后就按照自己的想法进行设计。

2.按照某篇paper的设计思想进行编程实现;

整个中值滤波模块分为几个小的模块:3*3窗口生成模块、计数器控制模块、3*3中值滤波模块、顶层模块以及最后的测试模块testbench的编写。

整个框架的设计如下图所示(使用visio画的框架图):

技术分享

 

各个模块的设计:

1)ROM IP核的生成,用于存储原始灰度图像的数据。

可以参考http://www.cnblogs.com/happyamyhope/p/5498745.html

使用matlab生成.coe图像数据文件,然后使用Xilinx ISE工具将.coe文件添加到ROM核进行数据初始化,按步骤得到ROM模块,参考生成的.v文件在顶层模块直接调用即可。

技术分享
  rom_512by512 rom_512by512_inst
  (
    .clka(CLK),          //input clka;
    .addra(rom_addr),   //input-from 
    .douta(rom_data)     //output-to 
  );
View Code

注意ROM的存储空间的大小;

 

2)3*3窗口生成模块,用于生成滤波的滑动窗口,得到窗口内的所有元素数据。

功能:

(1)根据中心像素点得到所在其所在的行、列位置;

(2)根据该模块的开始信号设计得到获取数据的有效时间序列;

(3)在读取数据的有效时序内,得到窗口内的所有元素数据;

(4)窗口数据的获取按照一定的时序顺序来获得,类似于黑金推荐的“仿顺序操作”,这个比较适合my style;不过后来发现调试的过程中被项目组的硬件人员改动了一些,甚至说不好,感觉可能是本人还没有理解掌握吃透“仿顺序操作”的精髓吧。

(5)根据中心像素点的行、列位置信息得到每个窗口元素的ROM地址,根据某一时刻ROM地址,下一时刻调用ROM模块得到对应的元素数据,下一时刻将数据锁存,然后再读取该地址的数据;所以要注意地址和数据的获取不是在同一时刻,而是需要延迟两个时刻;

(6)还需要注意的是图像的边界问题的特殊化处理;一般图像处理都会遇到边界问题,这个需要谨慎;

(7)对matlab的中值滤波函数medfilt2原理的深入掌握对我们编写这一模块非常重要。matlab并没有主要过程的代码,看注释默认情况下边界元素设置为0,这也可以通过结果反推回去发现的。

技术分享
  1 `timescale 1ns / 1ps
  2 //////////////////////////////////////////////////////////////////////////////////
  3 // Company: 
  4 // Engineer: 
  5 // 
  6 // Create Date:    09:27:48 05/18/2016 
  7 // Design Name: 
  8 // Module Name:    win3by3_gen 
  9 // Project Name: 
 10 // Target Devices: 
 11 // Tool versions: 
 12 // Description: 
 13 //
 14 // Dependencies: 
 15 //
 16 // Revision: 
 17 // Revision 0.01 - File Created
 18 // Additional Comments: 
 19 //
 20 //////////////////////////////////////////////////////////////////////////////////
 21 module win3by3_gen(
 22   CLK, 
 23   RSTn,
 24   center_pix_sig,
 25   cols,   // the column numbers of the input image
 26   rows,
 27   rom_data_win,   //input-from U1; 
 28   column_addr_sig,    //input-from U3; //output [9 : 0] addra; 
 29   row_addr_sig,         //input-from U3; //output [9 : 0] addra;
 30   rom_addr_sig,            //output-to U1; 
 31   data_out0,           //output-to U4;
 32   data_out1,
 33   data_out2,
 34   data_out3,
 35   data_out4,
 36   data_out5,
 37   data_out6,
 38   data_out7,
 39   data_out8,
 40   win_data_done_sig            //output-to U4/U3;complete the win data;
 41     );
 42 
 43   input CLK; 
 44   input RSTn;
 45   input [7:0] rom_data_win;
 46   input [9:0] cols;
 47   input [9:0] rows;
 48   input center_pix_sig;  // 
 49   input [9:0] column_addr_sig;
 50   input [9:0] row_addr_sig;
 51   
 52   output [7:0] data_out0;           //output-to U4;
 53   output [7:0] data_out1;
 54   output [7:0] data_out2;
 55   output [7:0] data_out3;
 56   output [7:0] data_out4;
 57   output [7:0] data_out5;
 58   output [7:0] data_out6;
 59   output [7:0] data_out7;
 60   output [7:0] data_out8;
 61   output [17:0] rom_addr_sig;
 62   output win_data_done_sig;
 63   
 64 /******************************************************************************************************************************/ 
 65   
 66   reg [9:0] m;
 67   
 68   always @ ( posedge CLK or negedge RSTn )
 69     if ( !RSTn )
 70        m <= 10d1;
 71      else if (  center_pix_sig )
 72        m <= row_addr_sig[9:0];  
 73        
 74   /******************************************************************************************************************************/ 
 75   
 76   reg [9:0] n;
 77   
 78   always @ ( posedge CLK or negedge RSTn )
 79     if ( !RSTn )
 80        n <= 10d1;
 81      else if (  center_pix_sig )
 82        n <= column_addr_sig[9:0];    
 83         
 84   /*****************************************************************************************************************************/ 
 85   
 86   reg [3:0] i; 
 87   reg isWinDone;
 88   reg [17:0] rom_addr;
 89   reg [7:0] a11;
 90   reg [7:0] a12;
 91   reg [7:0] a13;
 92   reg [7:0] a21;
 93   reg [7:0] a22;
 94   reg [7:0] a23;
 95   reg [7:0] a31;
 96   reg [7:0] a32;
 97   reg [7:0] a33;
 98      
 99 /*****************************************************************************************************************************/ 
100 
101 reg get_9point_vld;
102 
103 always @ ( posedge CLK or negedge RSTn )
104     if (!RSTn)
105            get_9point_vld <= 1b0;
106      else if ( center_pix_sig )  
107             get_9point_vld <= 1b1;
108      else if ( i==4d10 ) 
109             get_9point_vld <= 1b0;
110 
111 
112 always @ ( posedge CLK or negedge RSTn )
113     if ( !RSTn )
114            isWinDone <= 1b0;
115      else if ( i==4d10 )  
116             isWinDone <= 1b1;
117      else 
118             isWinDone <= 1b0;
119 
120 
121 
122 always @ ( posedge CLK or negedge RSTn )
123     if ( !RSTn )
124            i <= 4d0;
125      else if (i == 4d10)  
126             i <= 4d0;
127      else if ( get_9point_vld ) 
128             i <= i + 1b1;
129 
130 
131 
132         
133 always @ ( posedge CLK or negedge RSTn )
134     if (!RSTn) 
135             rom_addr <= 0;
136      else if ( get_9point_vld)
137        case (i)
138           4d0:
139             if(!(m==1 || n==1)) rom_addr <= (m-2)*cols + (n-1) -1;   
140           
141           4d1:
142           if(!(m==1 )) rom_addr <= (m-2)*cols + n -1; 
143            
144           4d2:
145             if(!(m==1 || n==cols)) rom_addr <= (m-2)*cols + (n+1) -1; 
146           
147           4d3:
148             if(!(n==1)) rom_addr <= (m-1)*cols + (n-1) -1; 
149           
150           4d4:
151             rom_addr <= (m-1)*cols + n -1; 
152           
153           4d5:
154             if(!(n==cols)) rom_addr <= (m-1)*cols + (n+1) -1; 
155           
156           4d6:
157             if(!(m==cols || n==1)) rom_addr <= m*cols + (n-1) -1; 
158           
159           4d7:
160             if(!(m==cols)) rom_addr <= m*cols + n -1; 
161           
162           4d8:
163             if(!(m==cols || n==cols)) rom_addr <= m*cols + (n+1) -1; 
164              
165           default:;
166 
167         endcase
168         
169 always @ ( posedge CLK or negedge RSTn )
170     if (!RSTn)
171        begin
172           a11 <= 0; 
173           a12 <= 0; 
174           a13 <= 0; 
175           a21 <= 0; 
176           a22 <= 0; 
177           a23 <= 0; 
178           a31 <= 0; 
179           a32 <= 0;
180           a33 <= 0;
181         end
182      else if ( get_9point_vld )
183      
184        case (i)
185   
186           4d2:
187           if ( m==1 || n==1 ) 
188                 a11 <= 0;     
189           else 
190                 a11 <= rom_data_win;      
191           
192           4d3:
193           if ( m==1 )  a12 <= 0; 
194           else a12 <= rom_data_win;       
195           
196           4d4:
197           if ( m==1 || n==cols ) a13 <= 0; 
198           else a13 <= rom_data_win; 
199           
200           4d5:
201           if ( n==1 ) a21 <= 0; 
202           else  a21 <= rom_data_win; 
203           
204           4d6:
205           a22 <= rom_data_win; 
206                     
207           4d7:
208           if ( n==cols ) a23 <= 0; 
209           else a23 <= rom_data_win;
210           
211           4d8:
212           if ( m==cols || n==1 ) a31 <= 0;
213           else a31 <= rom_data_win;  
214           
215           4d9:
216           if ( m==cols ) a32 <= 0;
217           else a32 <= rom_data_win;
218           
219           4d10:
220           if ( m==cols || n==cols ) a33 <= 0; 
221           else a33 <= rom_data_win;  
222           
223           default:;
224           
225       endcase
226   
227 /**********************************************************************************************/
228   
229   assign win_data_done_sig = isWinDone;
230   assign rom_addr_sig = rom_addr;
231   
232   assign data_out0 = a11;
233   assign data_out1 = a12;
234   assign data_out2 = a13;
235   assign data_out3 = a21;
236   assign data_out4 = a22;
237   assign data_out5 = a23;
238   assign data_out6 = a31;
239   assign data_out7 = a32;
240   assign data_out8 = a33;
241   
242 /**********************************************************************************************/ 
243  
244 endmodule
View Code

3)计数器控制模块,主要用于获得中心像素点的地址信息。

 

 

 

 3.对各个模块进行语法检查、波形仿真、时序设计、调试验证;

 

 

 

verilog实现中值滤波

标签:

原文地址:http://www.cnblogs.com/happyamyhope/p/5577898.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!