Viewing contents of file '../idllib/astron/contrib/varosi/vlib/allpro/filter_image.pro'
;+
; NAME:
; filter_image
;
; PURPOSE:
; Computes the average and/or median of pixels in moving box,
; replacing center pixel with the computed average and/or median,
; (using the IDL smooth or median functions).
; The main reason for using this function is the options to
; also process the pixels at edges and corners of image, and,
; to apply iterative smoothing simulating convolution with Gaussian,
; and/or to convolve image with a Gaussian kernel.
;
; CALLING:
; Result = filter_image( image, SMOOTH=box_width, /MEDIAN, /ALL )
;
; INPUT:
; image = 2-D array (matrix)
;
; KEYWORDS:
; SMOOTH = width of square box for moving average, in # pixels.
; /SMOOTH means use box width = 3 pixels for smoothing.
;
; MEDIAN = width of square moving box for median filter, in # pixels.
; /MEDIAN means use box width = 3 pixels for median filter.
;
; /ALL_PIXELS causes the edges of image to be filtered as well,
; accomplished by reflecting pixels adjacent to edges outward.
;
; /ITERATE : apply smooth(image,3) iteratively for a count of
; [ (box_width-1)/2 = radius ] times, when box_width >= 5.
; This is equivalent to convolution with a Gaussian PSF
; of FWHM = 2 * sqrt( radius ) as radius gets large.
; Note that /ALL_PIXELS is automatically applied,
; giving better results in the iteration limit.
; (also, MEDIAN keyword is ignored when /ITER is specified).
; Can also specify FWHM = # pixels when using /ITER.
;
; FWHM_GAUSSIAN = Full-width half-max of Gaussian to convolve with image.
; FWHM can be a single number (circular beam),
; or 2 numbers giving axes of elliptical beam.
; However, if /ITERATE is set then convolution with a Gaussian
; is approximated by iteration of smooth( image, 3 ).
;
; /NO_FT_CONVOL causes the convolution to be computed directly,
; with IDL function convol.
; The default is to use FFT when factors of size are all LE 13.
; (note that external function convolve handles both cases)
;
; RESULT:
; Function returns the smoothed, median filtered, or convolved image.
; If both SMOOTH and MEDIAN are specified, median filter is applied first.
;
; EXAMPLES:
; To apply 3x3 moving median filter and
; then 3x3 moving average, both applied to all pixels:
;
; Result = filter_image( image, /SMOOTH, /MEDIAN, /ALL )
;
; To iteratively apply 3x3 moving average filter for 4 = (9-1)/2 times,
; thus approximating convolution with Gaussian of FWHM = 2*sqrt(4) = 4 :
;
; Result = filter_image( image, SMOOTH=9, /ITER )
;
; To convolve all pixels with Gaussian of FWHM = 3.7 x 5.2 pixels:
;
; Result = filter_image( image, FWHM=[3.7,5.2], /ALL )
;
; EXTERNAL CALLS:
; function psf_gaussian
; function convolve
; pro factor
; function prime ;all these called only if FWHM is specified.
;
; PROCEDURE:
; If /ALL_PIXELS or /ITERATE keywords are set then
; create a larger image by reflecting the edges outward,
; then call the IDL median and/or smooth function on the larger image,
; and just return the central part (the orginal size image).
; HISTORY:
; Written, 1991, Frank Varosi, NASA/GSFC.
; FV, 1992, added /ITERATE option.
; FV, 1993, added FWHM_GAUSSIAN= option.
; FV, 1999, option FWHM_GAUSSIAN=#pixels can be used with /ITER approx.
;-
function filter_image, image, SMOOTH=width_smooth, ITERATE_SMOOTH=iterate, $
MEDIAN=width_median, ALL_PIXELS=all_pixels, $
FWHM_GAUSSIAN=fwhm, NO_FT_CONVOL=no_ft
sim = size( image )
Lx = sim(1)-1
Ly = sim(2)-1
if (sim(0) NE 2) OR (sim(4) LE 4) then begin
message,"input must be an image (a matrix)",/INFO
return,image
endif
if keyword_set( iterate ) then begin
nit = 0
if keyword_set( width_smooth ) then nit = fix( width_smooth/2 )
if keyword_set( fwhm ) then nit = round( (fwhm/2.)^2 )
if nit LT 1 then return, image
imf = image
for i=1,nit do imf = filter_image( imf, /SMOOTH, /ALL )
return,imf
endif
box_wid = 0
if keyword_set( width_smooth ) then box_wid = width_smooth > 3
if keyword_set( width_median ) then box_wid = (width_median > box_wid)>3
if keyword_set( fwhm ) then begin
npix = ( 3 * fwhm( 0: ( (N_elements( fwhm )-1) < 1 ) ) ) > 3
npix = 2 * fix( npix/2 ) + 1 ;make # pixels odd.
box_wid = box_wid > max( [npix] )
endif
if (box_wid LT 3) then return, image
if keyword_set( all_pixels ) then begin
box_wid = fix( box_wid )
radius = (box_wid/2) > 1
Lxr = Lx+radius
Lyr = Ly+radius
rr = 2*radius
imf = fltarr( sim(1)+rr, sim(2)+rr )
imf(radius,radius) = image ; reflect edges outward
; to make larger image.
imf( 0,0) = rotate( imf(radius:rr,*), 5 ) ;Left
imf(Lxr,0) = rotate( imf(Lx:Lxr,*), 5 ) ;right
imf(0, 0) = rotate( imf(*,radius:rr), 7 ) ;bottom
imf(0,Lyr) = rotate( imf(*,Ly:Lyr), 7 ) ;top
endif else begin
radius=0
imf = image
endelse
if keyword_set( width_median ) then imf = median( imf, width_median>3 )
if keyword_set( width_smooth ) then imf = smooth( imf, width_smooth>3 )
if keyword_set( fwhm ) then begin
if N_elements( no_ft ) NE 1 then begin
sim = size( imf )
factor,sim(1),pfx,nfx
factor,sim(2),pfy,nfy
no_ft = max( [pfx,pfy] ) GT 13
endif
imf = convolve( imf, NO_FT=no_ft, $
psf_gaussian( NP=npix,FWHM=fwhm,/NORM ) )
endif
return, imf( radius : Lx+radius, radius : Ly+radius )
end