A sliding neighborhood operation is an operation that is performed a pixel at a time, with the value of any given pixel in the output image being determined by the application of an algorithm to the values of the corresponding input pixel's neighborhood. A pixel's neighborhood is some set of pixels, defined by their locations relative to that pixel, which is called the center pixel. The neighborhood is a rectangular block, and as you move from one element to the next in an image matrix, the neighborhood block slides in the same direction. (To operate on an image a block at a time, rather than a pixel at a time, use the distinct block processing function. See Distinct Block Processing for more information.)
The following figure shows the neighborhood blocks for some of the elements in a 6-by-5 matrix with 2-by-3 sliding blocks. The center pixel for each neighborhood is marked with a dot. For information about how the center pixel is determined, see Determine the Center Pixel.
Neighborhood Blocks in a 6-by-5 Matrix
The center pixel is the actual pixel in the input image being processed by the operation. If the neighborhood has an odd number of rows and columns, the center pixel is actually in the center of the neighborhood. If one of the dimensions has even length, the center pixel is just to the left of center or just above center. For example, in a 2-by-2 neighborhood, the center pixel is the upper left one.
For any m
-by-n
neighborhood,
the center pixel is
floor(([m n]+1)/2)
In the 2-by-3 block shown in the preceding figure, the center pixel is (1,2), or the pixel in the second column of the top row of the neighborhood.
To perform a sliding neighborhood operation,
Select a single pixel.
Determine the pixel's neighborhood.
Apply a function to the values of the pixels in the neighborhood. This function must return a scalar.
Find the pixel in the output image whose position corresponds to that of the center pixel in the input image. Set this output pixel to the value returned by the function.
Repeat steps 1 through 4 for each pixel in the input image.
For example, the function might be an averaging operation that sums the values of the neighborhood pixels and then divides the result by the number of pixels in the neighborhood. The result of this calculation is the value of the output pixel.
As the neighborhood block slides over the image, some of the pixels in a neighborhood might be missing, especially if the center pixel is on the border of the image. For example, if the center pixel is the pixel in the upper left corner of the image, the neighborhoods include pixels that are not part of the image.
To process these neighborhoods, sliding neighborhood operations pad the borders of the image, usually with 0's. In other words, these functions process the border pixels by assuming that the image is surrounded by additional rows and columns of 0's. These rows and columns do not become part of the output image and are used only as parts of the neighborhoods of the actual pixels in the image.
You can use sliding neighborhood operations to implement many
kinds of filtering operations. One example of a sliding neighbor operation
is convolution, which is used to implement linear filtering. MATLAB^{®} provides
the conv
and filter2
functions
for performing convolution, and the toolbox provides the imfilter
function.
See What Is Image Filtering in the Spatial Domain? for
more information about these functions.
In addition to convolution, there are many other filtering operations you can implement through sliding neighborhoods. Many of these operations are nonlinear in nature. For example, you can implement a sliding neighborhood operation where the value of an output pixel is equal to the standard deviation of the values of the pixels in the input pixel's neighborhood.
To implement a variety of sliding neighborhood operations, use
the nlfilter
function. nlfilter
takes
as input arguments an image, a neighborhood size, and a function that
returns a scalar, and returns an image of the same size as the input
image. nlfilter
calculates the value of each pixel
in the output image by passing the corresponding input pixel's neighborhood
to the function.
Note:
Many operations that |
For example, this code computes each output pixel by taking the standard deviation of the values of the input pixel's 3-by-3 neighborhood (that is, the pixel itself and its eight contiguous neighbors).
I = imread('tire.tif'); I2 = nlfilter(I,[3 3],'std2');
You can also write code to implement a specific function, and
then use this function with nlfilter
. For example,
this command processes the matrix I
in 2-by-3 neighborhoods
with a function called myfun.m
. The syntax @myfun
is
an example of a function handle.
I2 = nlfilter(I,[2 3],@myfun);
If you prefer not to write code to implement a
specific function, you can use an anonymous function instead. This
example converts the image to class double
because
the square root function is not defined for the uint8
datatype.
I = im2double(imread('tire.tif')); f = @(x) sqrt(min(x(:))); I2 = nlfilter(I,[2 2],f);
(For more information on function handles, see Create Function Handle. For more information about anonymous functions, see Anonymous Functions.)
The following example uses nlfilter
to set
each pixel to the maximum value in its 3-by-3 neighborhood.
Note
This example is only intended to illustrate the use of |
I = imread('tire.tif'); f = @(x) max(x(:)); I2 = nlfilter(I,[3 3],f); imshow(I); figure, imshow(I2);
Each Output Pixel Set to Maximum Input Neighborhood Value