非线性空间滤波也基于领域操作,与使用m*n滤波器的中心点滑过一幅图像的机制一样。
非线性滤波基于领域像素内的非线性操作。模板的概念在非线性处理中不是那么普通。滤波的概念依然存在,但是滤波器应想象为领域像素操作的非线性函数,这些响应构成了 非线性操作的结果。
为了执行通常的非线性滤波操作,工具箱提供了两个函数:nlfilter和colfilt。 nlfilter直接执行二维操作 colfilt按列组织数据
虽然colfilt需要占用更多的内存,但是执行起来要比nlfilter快很多。在大多数的图像处理技术中,速度是最重要的因素。因此在执行非线性空间滤波时,更多采用的是colfilt。
给定一副大小为MN的输入图像f,邻域大小为mn,函数colfilt可产生矩阵A,最大尺寸为mn*MN,在这个矩阵中,每一列对应于图像中中被领域包围的像素。所有要进行的填充都用0填充,并由colfilt透明地处理。
函数colfilt的语法: g=colfilt(f,[m,n],‘sliding’,fun) m\n--------滤波区域的维数 sliding------------处理过程中m*n区域在输入图像f中逐像素进行滑动 fun-------函数句柄
由于习惯,组织了矩阵A,函数fun必须分别对每一列操作,并返回行向量v,v的第k个元素是对A中第k列进行fun操作后的结果。因为A可以有MN列,V的最大维数为1*MN。
在线性滤波方法中,存在空间滤波技术中用填充方法处理空间滤波固有的边缘问题。然而,在使用colfilt时,在进行滤波之前,输入图像必须被清除地进行填充。为此,我们使用函数padarray,对于二维函数,语法为: fp=padarray(f,[r,c],method,direction) f--------输入图像 fp------填充后的图像 [r,c]----用于填充f的行数和列数 method和direction的描述如下:
padarray选项描述方法symmetric通过镜像映射在图像边界的对面扩展图像尺寸replicate通过复制值在图像边界的外部扩展图像的尺寸circular通过将图像处理成2D周期函数的一个周期来扩展图像尺寸方向pre在每一维、第一个元素之前填充post在每一维、最后一个元素之后填充both在每一维、第一个元素之前和最后一个元素之后进行填充,这是默认值如果在参数中不包括direction,那么默认值为both,如果不包含method,将默认用0填充。 下面我们看看怎么用的 fp=padarray(f,[3,2],‘replicate’,‘post’) 再举一个例子: 使用函数colfilt实现非线性空间滤波
正像函数colfilt说明的那样,执行非线性滤波时,在任何点,响应都是以该点为中心点的邻域像素亮度值的几何平均。大小为m*n的邻域的几何平均数是领域内灰度值乘积的幂的1\mm.
首先,像匿名函数句柄那样执行非线性滤波函数 >> gmean=@(A) prod(A,1)^1/size(A,1) 为了降低边缘效应,我们用padaray函数中的选项replicate填充输入图像: f=padarray(f,[m,n],‘replicate’)
接下来,调用函数colfilt: >> g=colfilt(f,[m,n],‘sliding’,@gmean) (1)矩阵A由colfilt自动传递给函数句柄gmean (2)矩阵A总是mn行,但列数是可变的
在这种情况下,滤波的过程是计算领域内所有像素的乘积,并把结果提升至1/mn次幂。对于(x,y)的任意值,该点的滤波结果包含在V的适当列中。然后colfilt获得这些结果,并对他们重新排列以产生输出图像g。最后,我们移除先前的填充: >> [M,N]=size(f) g=g((1:M)+m,(1:N)+n); 所以g与f大小相同。
一些常见的非线性滤波器可以通过其他MATLAB和工具箱函数实现,例如imfliter和ordfilt2.函数spfilt,之前通过imfilter和matlab的log和exp函数实现几何平均滤波。
当这些是可能的时候,通常性能会高很多,内存的使用也是colfilt要求的一小部分。然而现在,函数colfilt仍然是进行非线性滤波操作最好的选择,还没有可以替代的函数。
