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 [:] data_a ;
input [:] data_b ;
input [:] data_c ; output [:] data_max;
output [:] data_min;
output [:] data_med; wire [:] data_max;
wire [:] data_min;
wire [:] data_med; wire [:] 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 [:] dat_1 ;
input [:] dat_2 ;
output [:] dat_max;
output [:] dat_min; wire [:] dat_max;
wire [:] 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=='b0)begin
max_p1_1<=; //第一行的最大数
max_p1_2<=; // 中间数
max_p1_3<=; // 最小数
min_p1_1<=; //第二行的最大数
min_p1_2<=; // 中间数
min_p1_3<=; // 最小数
med_p1_1<=; //第三行
med_p1_2<=;
med_p1_3<=;
end
else if(per_href_ff1==&&flag_do==)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<=;
max_p1_2<=;
max_p1_3<=;
min_p1_1<=;
min_p1_2<=;
min_p1_3<=;
med_p1_1<=;
med_p1_2<=;
med_p1_3<=;
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=='b0)begin
//max_p2_max<=0;
max_p2_min<=;
max_p2_med<=;
min_p2_max<=;
// min_p2_min<=0;
min_p2_med<=;
med_p2_max<=;
med_p2_min<=;
med_p2_med<=;
end
else if(per_href_ff2==&&flag_do==) 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<=;
max_p2_med<=;
min_p2_max<=;
// min_p2_min<=0;
min_p2_med<=;
med_p2_max<=;
med_p2_min<=;
med_p2_med<=;
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=='b0)begin
max_p3_med <= ;
max_p3_min <= ;
med_p3 <= ;
min_p3_max <= ;
min_p3_med <= ;
end
else if(per_href_ff3==&&flag_do==)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 <= ;
max_p3_min <= ;
med_p3 <= ;
min_p3_max <= ;
min_p3_med <= ;
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=='b0)begin
max_p4_max <= ;
max_p4_min <= ;
min_p4_max <= ;
min_p4_med <= ;
min_p4_min <= ;
end
else if(per_href_ff4&&flag_do==)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 <= ;
max_p4_min <= ;
min_p4_max <= ;
min_p4_med <= ;
min_p4_min <= ;
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=='b0)begin
max_p5_min<=;
min_p5_max<=;
med_p5 <=; end
else if(per_href_ff5==&&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) );
处理后的结果

补充 :
快速排序法实现中值滤波

第一步:将每一行按最大值、中间值、最小值排列
第二步:提取出最大值的最小值,中间值的中间值,最小值的最大值
第三步:将第二步提取出来的三个数进行排序,中间值即我们要求的中间值。
代码很简单,就不写了。
verilog 实现中值滤波的更多相关文章
- verilog实现中值滤波
前言 项目需要,想要实现算法中的其中一步即中值滤波,同时,因为图像处理部分中值滤波相对来说还是比较简单的,将中值滤波的硬件实现作为进入FPGA领域的第一次尝试.虽然说网上有较多关于中值滤波的文档,可是 ...
- 基于MATLAB的中值滤波算法实现
在实时图像采集中,不可避免的会引入噪声,尤其是干扰噪声和椒盐噪声,噪声的存在严重影响边缘检测的效果,中值滤波是一种基于排序统计理论的非线性平滑计数,能有效平滑噪声,且能有效保护图像的边缘信息,所以被广 ...
- 学习 opencv---(8)非线性滤波:中值滤波,双边滤波
正如我们上一篇文章中讲到的,线性滤波可以实现很多种不同的图像变换.然而非线性滤波,如中值滤波器和双边滤波器,有时可以达到更好的实现效果. 邻域算子的其他一些例子还有对 二值图像进行操作的形态学算子,用 ...
- Atitit 图像处理 平滑 也称 模糊, 归一化块滤波、高斯滤波、中值滤波、双边滤波)
Atitit 图像处理 平滑 也称 模糊, 归一化块滤波.高斯滤波.中值滤波.双边滤波) 是一项简单且使用频率很高的图像处理方法 用途 去噪 去雾 各种线性滤波器对图像进行平滑处理,相关OpenC ...
- opencv实现图像邻域均值滤波、中值滤波、高斯滤波
void CCVMFCView::OnBlurSmooth()//邻域均值滤波 { IplImage* in; in = workImg; IplImage* out = cvCreateImage( ...
- MATLAB灰度图、中值滤波图
x=imread(‘x.jpg’); x=rbg2gray(x); %转成灰度图像 k=medfilt2(x); %中值滤波,默认为3X3矩阵 figure, imshow(k); medfil ...
- 关于中值滤波算法,以及C语言实现(转)
源:关于中值滤波算法,以及C语言实现 1.什么是中值滤波? 中值滤波是对一个滑动窗口内的诸像素灰度值排序,用其中值代替窗口中心象素的原来灰度值,它是一种非线性的图像平滑法,它对脉冲干扰级椒盐噪声的抑制 ...
- 基于FPGA的中值滤波算法实现
在这一篇开篇之前,我需要解决一个问题,上一篇我们实现了基于FPGA的均值滤波算法的实现,最后的显示效果图上发现有一些黑白色的斑点,我以为是椒盐噪声,然后在做基于FPGA的中值滤波算法的实验时,我发现黑 ...
- 基于MATLAB的中值滤波均值滤波以及高斯滤波的实现
基于MATLAB的中值滤波均值滤波以及高斯滤波的实现 作者:lee神 1. 背景知识 中值滤波法是一种非线性平滑技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值. 中值滤 ...
随机推荐
- IDEA的第一个JavaEE项目&集成Tomcat、Jrebel、Git插件
创建第一个JavaEE项目 Next之后选择项目存储位置之后点击Finish即可. 新建的项目需要新建两个文件夹classes和lib 集成Tomcat Tomcat自行到官网下载 JRebel集成 ...
- COGS 1215. [Tyvj Aug11] 冗余电网
★ 输入文件:ugrid.in 输出文件:ugrid.out 简单对比时间限制:1 s 内存限制:128 MB TYVJ八月月赛提高组第2题 测试点数目:5 测试点分值:20 --内存 ...
- PHP生成类似类似优酷、腾讯视频等其他视频链的ID
不知道你注意了没有,类似优酷.腾讯视频等其他视频链接似乎类似这样的 http://v.youku.com/v_show/id_XNjA5MjE5OTM2.html 注意id_xxx那段,是不是看不懂了 ...
- [神经网络]一步一步使用Mobile-Net完成视觉识别(五)
1.环境配置 2.数据集获取 3.训练集获取 4.训练 5.调用测试训练结果 6.代码讲解 本文是第五篇,讲解如何调用测试训练结果. 上一篇中我们输出了训练的模型,这一篇中我们通过调用训练好的模型来完 ...
- MFC多文档无法显示可停靠窗格
当我们使用MFC多文档创建项目时,我们可停靠窗格关闭之后就无法显示了.即使重新编译项目也无法再次显示它们. 原因:因为MFC多文档把这些设置存储在注册表 “HKEY_CURRENT_USER \ SO ...
- WINDOWS-API:关于线程CreateThread,_beginthead(_beginthreadex),AfxBeginThread
[转]windows多线程编程CreateThread,_beginthead(_beginthreadex)和AfxBeginThread的区别 在Windows的多线程编程中,创建线程的函数主要有 ...
- 用Windows Native API枚举所有句柄及查找文件句柄对应文件名的方法
枚举所有句柄的方法 由于windows并没有给出枚举所有句柄所用到的API,和进程所拥有的句柄相关的只有GetProcessHandleCount这个函数,然而这个函数只能获取到和进程相关的句柄数,不 ...
- mysql 定时任务job
mysql 定时任务job 1.通过show EVENTS显示当前定义的事件 2.检查event_scheduler状态:SHOW VARIABLES LIKE 'event_scheduler' 3 ...
- 约束Constraints
1.setNeedsUpdateConstraints:当想要调整子视图布局时,在主线程调用该方法标记constraint需要在未来的某个点更新(该方法不会立刻强制刷新constraint,而是等待下 ...
- datatable css not work
样式不显示问题 无论是放内联样式文件还是直接放HTML文件都不显示 后来发现是因为datatable是放在后面初始化,它自带的样式覆盖了我们自定义的样式 所以要注意写code时,很多时候不是code不 ...