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,
- extract a smooth background image with a wide-radius lowpass filter
- sharper_image = image + c * (image - background), c ~ 10 % or so: highpass
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
Of course you'll have to experiment with
howfar for your data.
Calculate the smoothing filter (1d) outside the loop, then do
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 ?
how-does-an-unsharp-mask-work on SO
Haeberli and Voorhies,
Image Processing By Interp and Extrapolation, 1994, 3p.