IMFILTER Example
From MATLAB Techniques for Image Processing by Steve Eddins.
Some nonlinear image processing operations can be expressed in terms of linear filtering. When this is true, it often provides a recipe for a speedy MATLAB implementation.
The local std operator is often used as a measure of "busy-ness" throughout the image. For each pixel, the standard deviation of that pixel's neighbors is computed:
sqrt( sum ( (x - xbar).^2 ) )
(Scale factors omitted.)
Mathematically, the summation can be rewritten as:
sum(x.^2) - sum(x).^2/N
Both of these local sums can be computed by using imfilter with an all-ones filter.
I = im2double(imread('cameraman.tif')); imshow(I) xlabel('Image courtesy of MIT')

h = ones(5,5); term1 = imfilter(I.^2,h); imshow(term1,[])

Notice the dark band around the edge. This is because imfilter zero-pads by default. We might want to use the 'replicate' option instead.
term1 = imfilter(I.^2,h,'replicate');
imshow(term1,[])

term2 = imfilter(I, h, 'replicate').^2 / numel(h);
imshow(term2,[])

local_std = sqrt(term1 - term2); % scale factor omitted
imshow(local_std,[])

Two cautionary notes
- The procedure shown here is not always a numerically sound way to compute the standard deviation, because it can suffer from both overflow (squared terms) and underflow (cancellation in the subtraction of large numbers). For typical image pixel values and window sizes, though, it works reasonably well.
- Round-off error in the computation of term1 and term2 can sometimes make (term1 - term2) go slightly negative, resulting in complex outputs from square root operator. Avoid this problem by:
local_std = sqrt(max(term1 - term2,0));
Note that the example above is intended only to illustrate a useful technique. The Image Processing Toolbox already has a local standard deviation function included, called stdfilt.
local_std2 = stdfilt(I,ones(5,5)); imshow(local_std2,[])

The geometric mean filter multiplies together all the pixel values in the neighborhood and then takes the N-th root, where N is the number of pixels in the neighborhood. The geometric mean filter is said to be slightly better than the arithmetic mean at preserving image detail.
Use the old logarithm trick to express the geometric mean in terms of a summation.
geo_mean = imfilter(log(I),h,'replicate');
geo_mean = exp(geo_mean);
geo_mean = geo_mean .^ (1/numel(h));
imshow(geo_mean,[])
