verilog实现中值滤波

前言

项目需要,想要实现算法中的其中一步即中值滤波,同时,因为图像处理部分中值滤波相对来说还是比较简单的,将中值滤波的硬件实现作为进入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
  );

注意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 <= 10‘d1;
 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 <= 10‘d1;
 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 <= 1‘b0;
106      else if ( center_pix_sig )
107             get_9point_vld <= 1‘b1;
108      else if ( i==4‘d10 )
109             get_9point_vld <= 1‘b0;
110
111
112 always @ ( posedge CLK or negedge RSTn )
113     if ( !RSTn )
114            isWinDone <= 1‘b0;
115      else if ( i==4‘d10 )
116             isWinDone <= 1‘b1;
117      else
118             isWinDone <= 1‘b0;
119
120
121
122 always @ ( posedge CLK or negedge RSTn )
123     if ( !RSTn )
124            i <= 4‘d0;
125      else if (i == 4‘d10)
126             i <= 4‘d0;
127      else if ( get_9point_vld )
128             i <= i + 1‘b1;
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           4‘d0:
139             if(!(m==1 || n==1)) rom_addr <= (m-2)*cols + (n-1) -1;
140
141           4‘d1:
142           if(!(m==1 )) rom_addr <= (m-2)*cols + n -1;
143
144           4‘d2:
145             if(!(m==1 || n==cols)) rom_addr <= (m-2)*cols + (n+1) -1;
146
147           4‘d3:
148             if(!(n==1)) rom_addr <= (m-1)*cols + (n-1) -1;
149
150           4‘d4:
151             rom_addr <= (m-1)*cols + n -1;
152
153           4‘d5:
154             if(!(n==cols)) rom_addr <= (m-1)*cols + (n+1) -1;
155
156           4‘d6:
157             if(!(m==cols || n==1)) rom_addr <= m*cols + (n-1) -1;
158
159           4‘d7:
160             if(!(m==cols)) rom_addr <= m*cols + n -1;
161
162           4‘d8:
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           4‘d2:
187           if ( m==1 || n==1 )
188                 a11 <= 0;
189           else
190                 a11 <= rom_data_win;
191
192           4‘d3:
193           if ( m==1 )  a12 <= 0;
194           else a12 <= rom_data_win;
195
196           4‘d4:
197           if ( m==1 || n==cols ) a13 <= 0;
198           else a13 <= rom_data_win;
199
200           4‘d5:
201           if ( n==1 ) a21 <= 0;
202           else  a21 <= rom_data_win;
203
204           4‘d6:
205           a22 <= rom_data_win;
206
207           4‘d7:
208           if ( n==cols ) a23 <= 0;
209           else a23 <= rom_data_win;
210
211           4‘d8:
212           if ( m==cols || n==1 ) a31 <= 0;
213           else a31 <= rom_data_win;
214
215           4‘d9:
216           if ( m==cols ) a32 <= 0;
217           else a32 <= rom_data_win;
218
219           4‘d10:
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

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

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

 

时间: 2024-10-09 14:00:58

verilog实现中值滤波的相关文章

实时高速实现改进型中值滤波算法_爱学术_免费下载

[摘要]在图像采集和处理过程中会引入噪声,必须先对图像进行预处理.本文介绍一种快速中值滤波算法,该算法在硬件平台上实现实时处理功能.综合考虑,选择现场可编程门阵列(FPGA)作为硬件平台,采用硬件描述语言Verilog实现改进型中值滤波算法.经Modelsim仿真结果表明:基于FPGA硬件平台实现改进型中值滤波算法不仅速度快,而且实时处理效果佳,提高了图像处理的效率. [作者] 杨晶  王元庆 转载至爱学术:https://www.ixueshu.com/document/29bcda14996

基于Opencv的自适应中值滤波函数selfAdaptiveMedianBlur()

终于搞出来了:) #include <iostream> #include <opencv2/opencv.hpp> #include <vector> #include <algorithm> using namespace cv; using namespace std; //下面的宏,定义了在矩阵src的第m行.n列,ks*ks覆盖的矩形区域内的像素,并将像素压到矢量v中 //该覆盖区域的左上角坐标为(m,n),宽为ks,高为ks,要求src必须是单通

中值滤波讲解-Matlab

一.原理: 1:通过从序列中取出奇数个数(偶数也可)据进行排序 2:用排序后的中值,(若取数为偶数,则求中间两数的均值)来取代要处理的数据即可 二.除去高频波动分量和奇异点(即离基本分布点很远的噪点) 三.实例说明 图1-整体效果图 图2-局部效果图 四.代码说明 %中值滤波-Lab10 file='Datanog7'; x=importdata([file,'/A_x.txt']); subplot(2,1,1); plot(x); b=medfilt1(x,1000); subplot(2,

opencv中值滤波和低通滤波器对椒盐噪声处理的效果比较

opencv中值滤波和低通滤波器对椒盐噪声处理的效果比较 效果: 通过比较我们可以看出,中值滤波器有很好的保留了图像的边界信息 代码: void showimage(const std::string &str,const cv::Mat &image){ namedWindow(str,CV_WINDOW_AUTOSIZE); imshow(str,image); } Mat salt(const cv::Mat &image,int n){ Mat result = image

中值滤波与图像锐化

本文主要包括以下内容 中值滤波及其改进算法 图像锐化, 包括梯度算子.拉普拉斯算子.高提升滤波和高斯-拉普拉斯变换 本章的典型囊例分析 对椒盐噪声的平滑效果比较 Laplacian与LoG算子的锐化效果比较 中值滤波 中值滤波本质上是一种统计排序滤波器. 对于原图像中某点(i,j), 中值滤波以该点为中 心的邻域内的所有像素的统计排序中值作为(i, j) 点的响应. 中值不同于均值, 是指排序队列中位于中间位置的元素的值,例如=采用3x3 中值滤披 器, 某点.(i,j) 的8 个邻域的一系列像

高效中值滤波的方法及实现

中值滤波的原理很简单:就是用滑动窗口中灰度中值代替窗口中心像素的灰度值 高效中值滤波: 代码实现: //中值滤波 //窗口大小为width_Aperture*width_Aperture的正方形 void MedianBlur(const Mat &image_Src, Mat &image_Dst, int width_Aperture) { /////////////重新分配图像(如果需要)///////////////////// int width_Dst=image_Src.co

图像的中值滤波处理

#include<iostream>using namespace std;int main(){ int n,m,i,j,k,o,u,p,a[100][100],x[100][100],max[100][100][20],b[100][100]; cout<<"输入矩阵行列数:"<<endl; cin>>n>>m; cout<<"输入原图像的亮度矩阵:"<<endl; for(i=

数字图像处理之快速中值滤波算法

快速中值滤波算法 中值滤波算法: 在图像处理中,在进行如边缘检测这样的进一步处理之前,通常需要首先进行一定程度的降噪.中值滤波是一种非线性数字滤波器技术,经常用于去除图像或者其它信号中的噪声.这个设计思想就是检查输入信号中的采样并判断它是否代表了信号,使用奇数个采样组成的观察窗实现这项功能.观察窗口中的数值进行排序,位于观察窗中间的中值作为输出.然后,丢弃最早的值,取得新的采样,重复上面的计算过程.中值滤波是图像处理中的一个常用步骤,它对于斑点噪声和椒盐噪声来说尤其有用.保存边缘的特性使它在不希

高效中值滤波(采用copyMakeBorder处理边界像素)

修改了之前滤波中的中值滤波算法,采用copyMakeBorder处理边界像素 void MedianBlur(const Mat &image_Src, Mat &image_Dst, int width_Aperture) { /////////////////////////////重新分配图像(如果需要)///////////////////////////////////////////// int width_Dst=image_Src.cols; int height_Dst=