# 2D adaptive filters

Does anyone know about different adaptive filtering implementations (LMS, RLS ...) in 2D or even 3D ? I have sequences of 2D images and 3D volumes with repeating patterns but small differences. I was thinking of using one as my reference input and extract differences between the pair (A simple subtraction doesn't work as every little random difference is magnfied in the result). I cannot find any Matlab implementation and using 1D on columns or rows of the images doesn't seem to work. Thought perhaps a 2D version using a 2D neighbourhood would do a better job. The noise I am trying to remove is not white noise but rather coherent noise. New images are produced every second. The differences between two successive ones are small but gets larger over time.

• To remove noice you can try 2D and/or 3D adaptive median filtering. It's hard to say more without knowing about nature of your noise. Aug 26, 2013 at 6:51
• Thanks. I used 2D median filtering but it introduces spurious noise. I have added an example. The noise regions are marked around. Aug 26, 2013 at 7:12
• Did you try Fourier-based filtering? Aug 26, 2013 at 16:05
• Picture shows snapshot at one particular time from energy distribution in a sub-sea monitoring system for a depth profile. Measuring equipments are distributed around the observation field. By back-propagating energy in time along equidistant curves and adding up the back-propagation from all involved instruments a 2D (3D) subsea picture is constructed. The marked areas are concentrated energy due to coherent noise (originated outside the field) and are repeated (to some degree) from snapshot to the next, since the noise source(s) can be considered stationary for short periods of time. Aug 28, 2013 at 11:37
• Sorry, it's still not clear to me how to use LMS to track such big regions. Fwiw, X in LMS( X, y ) can be anything at all, e.g. pixels at various times; see how-to-apply-an-adaptive-filter-in-python on Stackoverflow for a simple derivation and simple code. Aug 29, 2013 at 13:46

Local contrast enhancement a.k.a. Unsharp masking is a simple, fast method for modeling, then removing, smooth (low-frequency) background noise. In a nutshell,

1. extract a smooth background image with a wide-radius lowpass filter
2. sharper_image = image + c * (image - background), c ~ 10 % or so: highpass

Using scipy.ndimage, this is :

def sharpen( image, radius, howfar, background ):
""" in: greyscale image, a 2d, 3d ...  numpy array
out = extrapolated highpass
background: lowpass the image, in time ~ Npixel * (2 radius + 1) * ndim
then highpass: background ---> image ---> sharpened image, in time ~ Npixel
howfar     -1              0          .5 ...
"""
sigma = int( radius / 4. + .5 )  # r = int( 4 * sigma + .5 )
ndimage.gaussian_filter( image, output=background, sigma=sigma, mode="nearest" )
return image + howfar * (image - background)  # clip


Some notes:

Of course you'll have to experiment with radius and howfar for your data.

Calculate the smoothing filter (1d) outside the loop, then do convolve or convolve_1d for each frame. If the background changes slowly, update only 1/2 or 1/10 of it on each frame. For example, alternate convolve_1d ( horizontal lines, vertical lines, horizontal ... )
or ( every 5 th H line, every 5 th V line, next 5 th H ... ).

Experts may know of smarter ways of tracking background only where it's changing.
(As I undersand it, that's your original question, but LMS seems to me, non-expert, overkill for that; here we have a fast simple inner loop.)

Color: you don't want to interpolate colors in RGB space, much less extrapolate, because "between" gets screwy colors.

(Some follow-up questions, maybe enough for a wiki:
What C++ image libraries have fast 2d / 3d gaussian_filter / fast extrpolation
and reasonable doc, clean, small, opensource, bindings for Python ... ?
Is there a constant-time 2d / 3d gaussian filter, independent of radius ?
Color: RGB -> Lab or YIQ -> sharpen luma only, leave color asis ?