主要内容

滑动邻域运算

滑动邻域操作是一种一次执行一个像素的操作,输出图像中任何给定像素的值由对应输入像素的值的算法应用决定社区。像素的邻域是一组像素,由它们相对于该像素的位置定义,称为邻域中心像素.邻域是一个矩形块,当您在图像矩阵中从一个元素移动到下一个元素时,邻域块将沿同一方向滑动。(要对图像一次操作一个块,而不是一次操作一个像素,请使用不同的块处理函数。看到不同块处理更多信息。)

下图显示了带有2 × 3滑动块的6 × 5矩阵中某些元素的邻域块。每个邻域的中心像素用一个点标记。有关如何确定中心像素的信息,请参见确定中心像素

6 × 5矩阵中的邻域块

确定中心像素

中心像素是正在被操作处理的输入图像中的实际像素。如果邻域的行数和列数为奇数,中心像素实际上位于邻域的中心。如果其中一个维度长度相等,则中心像素刚好在中心的左侧或正上方。例如,在2 × 2的邻域中,中心像素是左上方的像素。

对于任何——- - - - - -n邻域,中心像素为

(((mn) + 1) / 2)

在上图所示的2 × 3块中,中心像素为(1,2),或邻域顶部行第二列的像素。

滑动邻域运算的一般算法

要执行滑动邻域操作,

  1. 选择单个像素。

  2. 确定像素的邻域。

  3. 对邻域像素的值应用一个函数。这个函数必须返回一个标量。

  4. 找出输出图像中与输入图像中中心像素位置对应的像素。将这个输出像素设置为函数返回的值。

  5. 对输入图像中的每个像素重复步骤1到4。

例如,该函数可能是一个平均操作,将邻域像素的值相加,然后将结果除以邻域像素的数量。这个计算的结果就是输出像素的值。

滑动邻域操作中的边界填充行为

当邻域块在图像上滑动时,邻域中的一些像素可能会丢失,特别是如果中心像素位于图像的边界上。例如,如果中心像素是图像左上角的像素,则邻域包括不属于图像的像素。

为了处理这些邻域,滑动邻域操作图像的边界,通常是0。换句话说,这些函数通过假设图像周围有额外的0的行和列来处理边界像素。这些行和列不会成为输出图像的一部分,只用作图像中实际像素的邻域的一部分。

实现线性和非线性滤波滑动邻域操作

您可以使用滑动邻域操作来实现多种过滤操作。滑动邻居操作的一个例子是卷积,它被用来实现线性滤波。MATLAB®提供了conv而且filter2函数用于执行卷积,工具箱提供imfilter函数。看到什么是空间域图像滤波?有关这些函数的更多信息。

除了卷积,还有许多其他的过滤操作可以通过滑动邻域实现。其中许多操作本质上是非线性的。例如,您可以实现一个滑动邻域操作,其中输出像素的值等于输入像素邻域中像素值的标准差。

要实现各种滑动邻域操作,请使用nlfilter函数。nlfilter将图像、邻域大小和返回标量的函数作为输入参数,并返回与输入图像大小相同的图像。nlfilter通过将相应的输入像素的邻域传递给函数,计算输出图像中每个像素的值。

请注意

很多操作nlfilter如果在矩阵列上执行计算,而不是在矩形邻域上执行,则可以实现运行得更快。有关此方法的信息,请参见使用列处理来加速滑动邻域或不同块操作

例如,这段代码通过对输入像素的3 × 3邻域(即像素本身及其八个相邻邻域)的值取标准差来计算每个输出像素。

I = imread(“tire.tif”);I2 = nlfilter(I,[3 3],“std2”);

也可以编写代码实现特定的函数,然后使用此函数与之配合nlfilter.例如,这个命令处理矩阵在2乘3的邻域中,函数叫做myfun.m.的语法@myfun是函数句柄的示例。

I2 = nlfilter(I,[2 3],@myfun);

如果您不愿意编写代码来实现特定的函数,则可以使用匿名函数。这个示例将图像转换为类因为平方根函数没有定义uint8数据类型。

I = im2double(imread)“tire.tif”));F = @(x)√(min(x(:)));I2 = nlfilter(I,[2 2],f);

(有关函数句柄的更多信息,请参见创建函数句柄.有关匿名函数的详细信息,请参见匿名函数.)

下面的示例使用nlfilter将每个像素设置为其3 × 3邻域的最大值。

请注意

的用法,本例只是为了说明nlfilter.若要更快地执行此局部最大值操作,请使用imdilate

I = imread(“tire.tif”);F = @(x) max(x(:));I2 = nlfilter(I,[3 3],f);imshow(我);图中,imshow (I2);

每个输出像素设置为最大输入邻域值