第 5 章 空间域滤波器 ..5.1滤波器的概念 在数字图像处理中,某些邻域处理工作是操作邻域的图像像素值以及相应 的与邻域有相同维数的子图像的值,这些子图像称为滤波器(Filter)、掩模 (Mask)、核(Kernal)、模板(Template)或窗口(Window), 其中前三者普遍使用, 有时候又称为卷积核(ConvolutionKernel)。 ..5.2 平滑空间滤波器 平滑空间滤波器用于模糊处理和降低噪声。模糊处理经常用于图像的预 处理任务,例如,在大目标提取之前去除图像中的一些琐碎细节、连接直线或曲 线的缝隙,通过线性滤波器和非线性滤波器的模糊处理可以降低噪声。平滑滤 波器又叫低通滤波器,它能减弱或消除傅里叶空间的高频分量,但不影响低频 分量。 在图像中,高频分量是指像素的灰度值变化很快的部分,即图像从某个区 域到另一个区域,其明暗程度起伏较大。也就是说,从“暗”到“亮”或从“亮”到 “暗”过渡得非常快,而且交替进行,它往往对应图像中的某个区域的边缘等灰 度值具有较大、较快变化的部分;而低频分量则相反,是指灰度值起伏较小的区 域。滤波器将高频分量滤去,可使图像平滑,即降低图像的明暗起伏程度。平 滑空间滤波器包括线性滤波器和非线性滤波器,其中,线性滤波器包括均值滤 波器和高斯滤波器,非线性滤波器包括中值滤波器、最大值滤波器以及最小值 滤波器。 2.均值滤波器 5.1 均值滤波器可以归为平滑滤波器,它是一种线性的空间滤波器,其输出为 邻域模板内的像素的简单平均值,主要用于图像的模糊和降噪。均值滤波器的 概念非常直观,使用滤波器窗口内的像素的平均灰度值代替图像中的像素值, 这样的结果就是降低图像中的“尖锐”变化,这就造成在均值滤波器可以降低噪 声的同时,也会模糊图像的边缘。均值滤波器的处理结果是过滤掉图像中的 1 38 数字图像处理系列教程———基础知识篇 “不相关”细节,其中,“不相关”细节指的是与滤波器模板大小相比其尺寸较小的像素区 域。均值滤波本身存在着固有的缺陷,即它不能很好地保护图像细节,在图像去噪的同时 也破坏了图像的细节部分,从而使图像变得模糊,不能很好地去除噪声点。均值滤波对高 斯噪声表现较好,对椒盐噪声表现较差。 图5-1显示了常用的3×3均值滤波器,其计算公式如式(5-1)所示,该滤波器产生掩 图5-1 3×3均值滤波器 模下标准的像素平均值R,zi 表示与滤波器对应的3×3子图 中的第i 个像素值。 R =19 Σ9 i=1 zi (5-1) 一幅M ×N 的图像经过一个m ×n(m 和n 是奇数)加权 均值滤波器滤波的过程可由式(5-2)给出。 g(x,y)= ΣΣ s∈[-a,a],t∈[-b,b][w (s,t)f(x +s,y +t)] ΣΣw (s,t) s∈[-a,a],t∈[-b,b] (5-2) 其中,x=0,1,…,M -1,y=0,1,…,N -1,a=(m -1)/2,b=(n-1)/2,w (s,t)对 应m ×n 加权均值滤波器中第s 行第t 列的元素的权重值,又称为模板系数;f(x+s,y+ t)表示图像f 中第x+s 行第y+t 列的像素的灰度值;g(x,y)表示滤波后得到的新图像 g 的第x 行第y 列的像素的灰度值。在图5-1的滤波器示例中,其元素的权重值w (s,t) 均为1,且a=1,b=1。 例如,大小为5×5像素的图像f(x,y),其像素值如式(5-3)所示,在进行滤波之前 对其边缘像素进行扩充,扩充后得到的像素值如式(5-4)所示。利用图5-1所示的3×3 的均值滤波器对其滤波后的结果如式(5-5)所示,滤波后得到的g(x,y)的第一个像素值 g(0,0)的计算步骤如式(5-6)所示。然后,滤波器以1(1个像素)为步长向右移动,再计 算得到g(0,1),如式(5-6)所示,以此类推,从左到右、从上到下移动,每次移动1个像 素,则计算一次,得到最终的滤波结果。 f(x,y)= 1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9 . è ...... . . ÷÷÷÷÷÷ (5-3) f'(x,y)= 0 0 0 0 0 0 0 0 1 2 3 4 5 0 0 16 17 18 19 6 0 0 15 24 25 20 7 0 0 14 23 22 21 8 0 0 13 12 11 10 9 0 0 0 0 0 0 0 0 . è ......... . . ÷÷÷÷÷÷÷÷÷ (5-4) 第5章 空间域滤波器1 39 g(x,y)= 4 6 7 6 4 8 13 14 12 8 12 19 21 16 9 11 18 19 15 8 7 10 11 9 5 . è ...... . . ÷÷÷÷÷÷ (5-5) g(0,0)=(1×0+1×0+1×0+1×0+1×1+1×2+ 1×0+1×16+1×17)÷9=4 g(0,1)=(1×0+1×0+1×0+1×1+1×2+1×3+ 1×16+1×17+1×18)÷9≈6 ì . í ... .. . (5-6) 图5-2给出了尺寸为3×3的滤波器对同一图像的处理效果,可见处理后的效果 图5-2(b)较原图5-2(a)变得模糊,而且均值滤波器的尺寸越大,其模糊程度越高。 图5-2 3×3均值滤波器的处理效果 均值滤波的一个重要应用是为了对感兴趣的物体得到一个粗略的描述,模糊一幅图 像。这样,那些较小物体的灰度与背景融合在一起,较大物体会变得像“斑点”而易于检 测。以3×3的均值滤波器为例,在对图像进行滤波之前,可以选择是否对图像边缘进行 扩充。边缘扩充即利用边界最邻近像素进行填充(外边界填充0也可以),以M ×N 图像 为例,进行边缘扩充之后图像的大小为(M +2)×(N +2),在滤波完成后,其大小又变为 M ×N 。如果不进行边缘扩充,则滤波完成后,边缘像素信息并未发生改变(如均值滤波 代码第5行和第6行所示,行和列的起始位置均为1,结束位置均为倒数第二个位置,因 此,图像最外围一圈的像素并未发生改变,而且影响很小,我们几乎感觉不到)。后面章节 介绍的其他滤波器对图像进行滤波处理时同样适用。 C++示例代码5-1:均值滤波 void averageFilter ( BYTE * pSrcBuffer, int width, int height, BYTE * pDstBuffer){ int widthStep = (width * 24 / 8 + 3) / 4 * 4; 1 40 数字图像处理系列教程———基础知识篇 int w[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }; //均值滤波器 BYTE* p[9]; for (int row = 1; row < height-1; row++){ for (int col = 1; col < width-1; col++){ //首先确定模板中心像素的位置 p[4] = pSrcBuffer + row*(width * 3) + col * 3; p[3] = p[4] - 3; p[5] = p[4] + 3; p[1] = p[4] - width * 3; p[0] = p[1] - 3; p[2] = p[1] + 3; p[7] = p[4] + width * 3; p[6] = p[7] - 3; p[8] = p[7] + 3; BYTE* pDst = pDstBuffer + row*(width * 3) + col * 3; int sum[3] = {0,0,0}; for (int k = 0; k < 9; k++){ sum[0] += (int)(*p[k])*w[k]; sum[1] += (int)(*(p[k] + 1))*w[k]; sum[2] += (int)(*(p[k] + 2))*w[k]; } *pDst = (BYTE)(sum[0] / 9); *(pDst + 1) = (BYTE)(sum[1] / 9); *(pDst + 2) = (BYTE)(sum[2] / 9); } } } 5.2.2 高斯滤波器 高斯滤波器是一种线性的空间滤波器,能够有效地抑制噪声,平滑图像。其作用原理 和均值滤波器类似,都是取滤波器窗口内的像素的均值作为输出。与均值滤波器不同之 处在于,均值滤波器的模板系数都相同且为1,而高斯滤波器的模板系数则随着离模板中 心的距离增大而减小。所以,高斯滤波器较均值滤波器对图像的模糊程度小。 图5-3所示是常用的两种高斯模板,图5-3(a)是3×3高斯模板,图5-3(b)是5×5高 斯模板。 那么,上述高斯模板中的参数是怎么得到的呢? 它们是通过高斯函数计算出来的,所 以,高斯模板又称为高斯滤波器。二维的高斯函数如式(5-7)所示,σ 表示标准差。 h(x,y)= 1 2πσ2e-x2+y2 2σ2 (5-7) 若要产生一个3×3的高斯模板,则需要以模板的中心位置为坐标原点进行取样。模板 在各个位置的坐标(x 轴水平向右,y 轴竖直向上),如图5-4所示。对于大小为(2k+1)× 第5章空间域滤波器141 图5-3常用的两种高斯模板 图5- 4 3×3 的高斯滤波器模板各个位置的坐标 (2k+1)的窗口模板,模板中各个元素值的计算公式如式(5-8)所示。在得到模板中各个 元素的值后,一幅图像经高斯滤波器处理的过程,和前面提到的采用加权均值滤波器进行 滤波的过程一样。 -2+(k)2 wij = 12e-(ik) 2σ2j-(5-8) 2πσ 其中,wij 对应高斯滤波器的模板系数。对图5-4的示例而言,若模板大小(2k+1)× 2k+1)=3×3, wij -i-j-= (则k=1,对应图54中(k,k)位置的系数,若i0,1,2,而j= 0,1,2,则w00 、w01 和w02 分别对应图5-4中(-1,-1)、(-1,0)和(-1,1)位置处的模 板系数,其余的以此类推。 -0. 下面是图53(a)所示3×3 高斯滤波器模板系数的计算示例,其中σ=8。 1 (0-1)2+(0-1)2 w00= 2π×0.2e820. -2×0.=0521261 8 2 82 2×0. w01= 2π×10. (0-1)2+(1-1)=1138538 82e-0. 82 w11= 2π×10.2e-(1-1)2+(1-1)2 =0.2486796 82×0. 经过上述计算,可得到如图5-5(a)所示原始的3×3 高斯滤波器模板,然后将所有元 素除以w00,则可以得到图5-5(b)所示的高斯滤波器模板,考虑最终的高斯滤波器模板9 142数字图像处理系列教程———基础知识篇 个值加起来要求为1(这是高斯模板的特性), 而图5-5(b)中元素取整(直接去除小数部 分)的总和为16,因此,将图5-5(b)的元素分别除以16,即最终的3×3 高斯滤波器模板 (σ=0.8时), 如图5-3(a)所示。 图5-5高斯滤波器模板计算结果 图5-6(a)经3×3 的高斯滤波器处理后的效果如图5-6(b)所示。 图5- 6 高斯滤波器处理结果图 高斯滤波器模板的生成过程中,最重要的参数是高斯分布的标准差σ。标准差代表 着数据的离散程度,如果 σ 较小,那么生成的模板的中心系数较大,而周围的系数较小,这 样对图像的平滑效果就不够明显;反之,则生成的模板的各个系数相差就不是很 σ 较大, 大,比较类似于均值模板,对图像的平滑效果比较明显。如图5-7所示,标准差 σ 取不同 值时,图像具有不同的平滑效果。 图5- 7 标准差 σ 取不同值时的图像平滑效果 第5章 空间域滤波器1 43 C++示例代码5-2:高斯滤波 void gaussianFilter ( unsigned char * pSrcBuffer, int width, int height, unsigned char* pDstBuffer){ int widthStep = (width * 24 / 8 + 3) / 4 * 4; int w[] = { 1, 2, 1, 2, 4, 2, 1, 2, 1 }; //高斯滤波器 BYTE* p[9]; for (int row = 1; row < height - 1; row++){ for (int col = 1; col < width - 1; col++){ //首先确定模板中心像素的位置 p[4] = pSrcBuffer + row*(width * 3) + col * 3; p[3] = p[4] - 3; p[5] = p[4] + 3; p[1] = p[4] - width * 3; p[0] = p[1] - 3; p[2] = p[1] + 3; p[7] = p[4] + width * 3; p[6] = p[7] - 3; p[8] = p[7] + 3; BYTE* pDst = pDstBuffer + row*(width * 3) + col * 3; int sum[3] = { 0, 0, 0 }; for (int k = 0; k < 9; k++){ sum[0] += (int)(*p[k])*w[k]; sum[1] += (int)(*(p[k] + 1))*w[k]; sum[2] += (int)(*(p[k] + 2))*w[k]; } *pDst = (BYTE)(sum[0] / 9); *(pDst + 1) = (BYTE)(sum[1] / 9); *(pDst + 2) = (BYTE)(sum[2] / 9); } } } 5.2.3 统计排序滤波器 统计排序滤波器是一种非线性空间滤波器,它的响应基于图像滤波器包围的图像区 域中像素的排序,然后由统计排序结果决定的值代替中心像素的值,主要包括中值、最大 值、最小值3种滤波器。 1.中值滤波器 中值滤波器是最著名的统计排序滤波器,它将每个像素的灰度值设置为该点某邻域窗 口内的所有像素点灰度值的中值。所谓中值,是指按照某种方法排序后的一组数据中处于 1 44 数字图像处理系列教程———基础知识篇 中间位置的数。中值滤波器的使用非常广泛,因为对于一定类型的随机噪声,它提供了一种 优秀的去噪能力,比小尺寸的线性平滑滤波器的模糊程度明显要低,它对处理脉冲噪声(也 称为椒盐噪声)非常有效,同时也可以保护图像尖锐的边缘,但对高斯噪声的处理效果较差。 对于一个3×3的邻域,其中值是第5个值,而在一个5×5的邻域中,中值就是第13 个值。例如,在一个3×3的邻域内有一系列像素值(10,20,20,20,15,20,20,25,100),对 这些值排序后为(10,15,20,20,20,20,20,25,100),那么其中值就是20。这样,中值滤波 器的主要功能是使拥有不同灰度的点看起来更接近它的临近值。 按照上述流程,以5.2.1节中的图像f(x,y)为例,其经中值滤波器处理后(经像素扩 充)的像素值如式(5-9)所示。 f(x,y)= 0 2 3 4 0 2 16 18 7 5 15 18 21 19 7 14 15 21 11 8 0 12 11 9 0 . è ...... . . ÷÷÷÷÷÷ (5-9) 中值滤波器对椒盐噪声的处理如图5-8所示,其与均值滤波的处理效果对比如图5-9 所示,图5-9(b)为中值滤波的处理结果,图5-9(c)为均值滤波的处理结果。可以看出, 中值滤波对椒盐噪声的处理有很好的效果。 图5-8 中值滤波器对椒盐噪声的处理效果 2.最大值滤波器 中值滤波器是目前为止图像处理中最常用的一种统计排序滤波器,根据基本统计学 可知,排序也适用于其他不同的情况,例如,可以取第100%个值,还可以取第0%个值。 当取第100%个值时,即最大值滤波器(也叫作膨胀),与中值滤波器类似,它将每一像素 点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的最大值,这种滤波器在搜寻 一幅图中的最亮点时非常有用。例如,一个3×3的邻域内有一系列像素值(10,20,20, 20,15,20,20,25,100),对这些值排序后为(10,15,20,20,20,20,20,25,100),那么其最大 第5章空间域滤波器145 图5- 9 中值滤波和均值滤波对椒盐噪声的处理效果对比 值就是100 。 3. 最小值滤波器 同理,当取第0% 个值时,即最小值滤波器(也叫作腐蚀), 它将每一像素点的灰度值设 置为该点某邻域窗口内的所有像素点灰度值的最小值,与最大值滤波器的目的相反,该滤波 器用于发现图像中的最暗点。例如,一个3×3 的邻域内有一系列像素值(10,20,15, 20,20,20,25,10,20,20,20,100), 20,100), 对这些值排序后为(15,20,20,25,那么其最小值就是10 。 最大值滤波和最小值滤波的处理效果分别如图5-10(b)和图5-10(c)所示,从图中可 以很直观地看到,最大值滤波器用于搜寻一幅图中的最亮点,而最小值滤波器在搜寻一幅 图中的最暗点时非常有用。 图5-10 最大值滤波和最小值滤波效果对比 1 46 数字图像处理系列教程———基础知识篇 C++示例代码5-3:中值滤波 void medianFilter ( BYTE * pSrcBuffer, int width, int height, BYTE * pDstBuffer){ //中值滤波 int widthStep = (width * 24 / 8 + 3) / 4 * 4; BYTE* p[9]; int p1[9], p2[9], p3[9]; for (int row = 1; row < height - 1; row++){ for (int col = 1; col < width - 1; col++){ //首先确定模板中心像素的位置 p[4] = pSrcBuffer + row*(width * 3) + col * 3; p[3] = p[4] - 3; p[5] = p[4] + 3; p[1] = p[4] - width * 3; p[0] = p[1] - 3; p[2] = p[1] + 3; p[7] = p[4] + width * 3; p[6] = p[7] - 3; p[8] = p[7] + 3; BYTE* pDst = pDstBuffer + row*(width * 3) + col * 3; for (int k = 0; k < 9; k++){ p1[k] = (int)(*p[k]); p2[k] = (int)(*(p[k] + 1)); p3[k] = (int)(*(p[k] + 2)); } sort(p1, p1+9); sort(p2, p2 + 9); sort(p3, p3 + 9); *pDst = (BYTE)p1[4]; *(pDst + 1) = (BYTE)p2[4]; *(pDst + 2) = (BYTE)p3[4]; } } } C++示例代码5-4:最大值滤波 void maximumFilter(unsigned char* pSrcBuffer, int width, int height, unsigned char* pDstBuffer) { //最大值滤波 int widthStep = (width * 24 / 8 + 3) / 4 * 4; BYTE* p[9]; int p1[9], p2[9], p3[9];