转: http://xiongwei.site/
在实时图像采集中,不可避免的会引入噪声,尤其是干扰噪声和椒盐噪声,噪声的存在严重影响边缘检测的效果,中值滤波是一种基于排序统计理论的非线性平滑计数,能有效平滑噪声,且能有效保护图像的边缘信息,所以被广泛用于数字图像处理的边缘提取,其基本原理是把数字图像或数字序列中的一点的值用该点邻域内所有点的中值来代替。
中值滤波对脉冲噪声有良好的滤除作用,特别是在滤除噪声的同时,能够保护信号的边缘,使之不被模糊。这些优良特性是线性滤波方法所不具有的。此外,中值滤波的算法比较简单,也易于用硬件实现。所以,中值滤波方法一经提出后,便在数字信号处理领得到重要的应用。
中值滤波方法是,对待处理的当前像素,选择一个模板,该模板为其邻近的若干个像素组成,对模板的像素由小到大进行排序,再用模板的中值来替代原像素的值的方法。
当我们使用3x3窗口后获取领域中的9个像素,就需要对9个像素值进行排序,为了提高排序效率,排序算法思想如图3-18所示
(1) 对窗内的每行像素按降序排序,得到最大值、中间值和最小值;
(2) 把三行的最小值相比较,取其中的最大值;
(3) 把三行的最大值相比较,取其中的最小值;
(4) 把三行的中间值相比较,再取一次中间值;
(5) 把前面的到的三个值再做一次排序,获得的中值即该窗口的中值。
中值滤波的3x3矩阵的生成和均值滤波是完全类似的。我们求中值的方法是,先对3x3矩阵的每行按从大到小进行排序,然后利用排序法求出最大值那一列的最小值,求出之间数那一列的中间值,求出最小值按一列的最大值,最后将求出的三个值再排序,这三个值的中间值就是这个3x3矩阵的中间值。
这里我们开始想一个问题,用3x3矩阵排序来替代中间值,那么图像的边缘区域怎么办?这是一个问题,在这里我的做法是对齐置之不理。怎么生成3x3的移动窗口,而且图像的像素有比较大,那么我们需要对其进行行缓存。一般做法是ram和fifo,还有就是altera公司的shift_ram(貌似专门为图像处理而生),因为我是基于Xilinx平台的ise,所以这里我自己设计了一个类似shift_ram的ip,基于两个fifo,深度为512. 下面就是行缓存的代码:
module shift_line_buffer(
input wire line_clk ,
input wire s_rst_n ,
input wire in_line_vaild ,//在有效数据提前一个周期
input wire [7:0] din ,
input wire vsync ,//帧同步
output wire [7:0] taps0x ,
output wire [7:0] taps1x ,
output wire [7:0] taps2x ,
output wire done
);
`ifndef SIM
localparam IMAGE_WIDTH = 480 ;//
`else
localparam IMAGE_WIDTH = 8 ;//480X272
`endif
wire empty1,empty2,pop1_en,pop2_en;
reg rd1_en,rd2_en;
wire prog_full1,prog_full2;
assign pop1_en=(prog_full1==1)?1'b1:vsync;//0?
always @(posedge line_clk or negedge s_rst_n)begin
if(s_rst_n == 0)
rd1_en=0;
else if(pop1_en== 1 && in_line_vaild== 1)
rd1_en=1;
else if(empty1==1)
rd1_en=0;
end
fifo_512x8 fifo_512x8_inst1(
.clk