1.背景知识
中值滤波法是一种非线性平滑技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值.
中值滤波是基于排序统计理论的一种能有效抑制噪声的非线性信号处理技术,中值滤波的基本原理是把数字图像或数字序列中一点的值用该点的一个邻域中各点值的中值代替,让周围的像素值接近的真实值,从而消除孤立的噪声点。方法是用某种结构的二维滑动模板,将板内像素按照像素值的大小进行排序,生成单调上升(或下降)的为二维数据序列。二维中值滤波输出为g(x,y)=med{f(x-k,y-l),(k,l∈W)} ,其中,f(x,y),g(x,y)分别为原始图像和处理后图像。W为二维模板,通常为3*3,5*5区域,也可以是不同的的形状,如线状,圆形,十字形,圆环形等。
中值滤波法对消除椒盐噪声非常有效,在光学测量条纹图象的相位分析处理方法中有特殊作用,但在条纹中心分析方法中作用不大.
中值滤波在图像处理中,常用于保护边缘信息,是经典的平滑噪声的方法。
2.中值滤波理论
中值滤波是一种非线性滤波,在数字图像处理中,对于 N X N (N 为奇数) 中值滤波器,可以滤除小于或等于邻域中(N 2- 1)/2 个像素的噪声并且较好地保持图像的边缘[3]。对图像进行中值滤波处理首先要确定一个模板 N ×N ,一般选取 3X 3 或 5 ×5。中问位置的图像数据的表达式为
f (x ,y ) = med{f (x ± k,Y ± Z) , (K≤ (N -1) /2,Z≤ (N-1) /2) }
要得到模板中数据的中间值,首先要将数据按大小排序,然后根据有序的数字序列来找中问值。中值滤波排序的过程有很多成熟的算法,如冒泡排序、二分排序等,大多是基于微机平台的软件算法,而适合硬件平台的排序算法则比较少。
3.FPGA硬件实现方法
L(1,1) L(1,2) L(1,3)
L(2,1) L(2,2) L(2,3)
L(3,1) L(3,2) L(3,3)
如上所示,为一个3x3的图像模板,
第一步:
分别对三行像素进行排序(例:由L11,L12,L13得到L1max,L1mid,L1min);
第二步:
分别对三行像素中的最大,中间和最小分别进行排序(例:由L1max,L2max,L3max得到Lmax_max,Lmax_mid,Lmax_min);
第三步:对最大的最小,中间的中间以及最小的最大进行排序(例:由Lmax_min,Lmid_mid,Lmin_max得到midian);
FPGA的算法实现步骤基本如此。
4.MATLAB的中值滤波演示
源码:
- <p>
- </p><p>clear all;</p><p>clc;</p><p>img = imread('flower.bmp'); %读入原始图像</p><p>figure,imshow(img); %显示原始图像</p><p>title('original');</p><p>gray_rgb = rgb2gray(img);</p><p>figure,imshow(gray_rgb); %显示原始图像转化成gray图像</p><p>title('gray original');</p><p>salt_img = imnoise(img,'salt & pepper',0.02); %对原始图像加入椒盐噪声</p><p>figure,imshow(salt_img); %显示加入椒盐噪声后的图像</p><p>title('salt & pepper noise');</p><p>gray = rgb2gray(salt_img);</p><p>figure,imshow(gray); %显示加入椒盐噪声的灰度图像</p><p>title('gray');</p><p>median_filting_img = medfilt2(gray); %对加入椒盐噪声的灰度图像进行中值滤波</p><p>figure,imshow(median_filting_img);</p><p>title('medfilter salt & pepper noise');</p>
复制代码实验结果:
原始图像
直接由RGB转换过来的Gray图像
加入椒盐噪声的彩色图像
加入椒盐噪声后的gray图像
中值滤波后的结果
结果分析:中值滤波后的灰度图像明显去除了所有的椒盐噪声,与原始灰度图像相比图像本身被轻微模糊化。
5.FPGA的中值滤波实现
部分源码:
- <p>//-------------------------------------</p><p>//pipeline data</p><p>//-------------------------------------</p><p>reg [15:0] line0_data0;</p><p>reg [15:0] line0_data1;</p><p>reg [15:0] line0_data2;</p><p>
- </p><p>reg [15:0] line1_data0;</p><p>reg [15:0] line1_data1;</p><p>reg [15:0] line1_data2;</p><p>
- </p><p>reg [15:0] line2_data0;</p><p>reg [15:0] line2_data1;</p><p>reg [15:0] line2_data2;</p><p>
- </p><p>//--------------------------------------------------------------------------</p><p>// Form an image matrix of three multiplied by three</p><p>//--------------------------------------------------------------------------</p><p>always @(posedgeclk or negedgerst_n) begin</p><p> if(!rst_n) begin</p><p> line0_data0 <= 16'b0;</p><p><span class="Apple-tab-span" style="white-space:pre"> </span> line0_data1 <= 16'b0;</p><p><span class="Apple-tab-span" style="white-space:pre"> </span> line0_data2 <= 16'b0;</p><p><span class="Apple-tab-span" style="white-space:pre"> </span></p><p><span class="Apple-tab-span" style="white-space:pre"> </span> line1_data0 <= 16'b0;</p><p><span class="Apple-tab-span" style="white-space:pre"> </span> line1_data1 <= 16'b0;</p><p><span class="Apple-tab-span" style="white-space:pre"> </span> line1_data2 <= 16'b0;</p><p><span class="Apple-tab-span" style="white-space:pre"> </span></p><p><span class="Apple-tab-span" style="white-space:pre"> </span> line2_data0 <= 16'b0;</p><p><span class="Apple-tab-span" style="white-space:pre"> </span> line2_data1 <= 16'b0;</p><p><span class="Apple-tab-span" style="white-space:pre"> </span> line2_data2 <= 16'b0;</p><p> end</p><p> else if(data_in_en) begin</p><p> line0_data0 <= line0;</p><p><span class="Apple-tab-span" style="white-space:pre"> </span> line0_data1 <= line0_data0;</p><p><span class="Apple-tab-span" style="white-space:pre"> </span> line0_data2 <= line0_data1;</p><p><span class="Apple-tab-span" style="white-space:pre"> </span></p><p><span class="Apple-tab-span" style="white-space:pre"> </span> line1_data0 <= line1;</p><p><span class="Apple-tab-span" style="white-space:pre"> </span> line1_data1 <= line1_data0;</p><p><span class="Apple-tab-span" style="white-space:pre"> </span> line1_data2 <= line1_data1;</p><p><span class="Apple-tab-span" style="white-space:pre"> </span></p><p><span class="Apple-tab-span" style="white-space:pre"> </span> line2_data0 <= line2;</p><p><span class="Apple-tab-span" style="white-space:pre"> </span> line2_data1 <= line2_data0;</p><p><span class="Apple-tab-span" style="white-space:pre"> </span> line2_data2 <= line2_data1;<span class="Apple-tab-span" style="white-space:pre"> </span></p><p> end</p><p>else ;</p><p>end</p><p>
- </p><p>//------------------------------------------------------------------------------</p><p>// middle</p><p>//------------------------------------------------------------------------------</p><p>always @(posedgeclk or negedgerst_n) begin</p><p> if(!rst_n)</p><p> mid <= 16'd0;</p><p> else if(data_in_en) begin</p><p>if(((max_mid>= mid_mid) && (max_mid<min_mid)) || ((max_mid>= min_mid) && (max_mid<mid_mid)))</p><p><span class="Apple-tab-span" style="white-space:pre"> </span> mid <= max_mid;</p><p><span class="Apple-tab-span" style="white-space:pre"> </span> else if(((mid_mid>max_mid) && (mid_mid<min_mid)) || ((min_mid>= min_mid) && (mid_mid<max_mid)))</p><p><span class="Apple-tab-span" style="white-space:pre"> </span> mid <= mid_mid;</p><p><span class="Apple-tab-span" style="white-space:pre"> </span> else if(((min_mid>max_mid) && (min_mid<mid_mid)) || ((min_mid>mid_mid) && (mid_min<max_mid)))</p><p><span class="Apple-tab-span" style="white-space:pre"> </span> mid <= min_mid;</p><p> end</p><p>else ;</p><p>end</p><p></p>
复制代码modelsim仿真
仿真结果分析:
有modelsim仿真波形来看,三个时钟后得到九个像素点的中间值,源码仿真成功。
实验结果:
RGB图像加入椒盐噪声
中值滤波后
Gray图像加入椒盐噪声
中值滤波后
结果分析:
从RGB图像和灰度图像来看,去除了大部分椒盐噪声噪点,部分没有去除的原因在于部分噪点过大,或者相邻太近,被当作中间值显示出来。大家可以试验增加到两次中值滤波的实验结果。
作者:lee神
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。