Viewing contents of file '../idllib/astron/contrib/varosi/vlib/allpro/correl_optimize.pro'
;+
; NAME:
; correl_optimize
; PURPOSE:
; Assuming the images are two detections of the same scene,
; find the optimal (x,y) pixel offset of image_B relative to image_A,
; by means of maximizing the cross-correlation function.
; Note that bad pixels or extremely noisy data will bias the
; cross-correlation function and give possibly erroneous results.
; Small amount of noise is no problem, pre-filtering is recommended,
; returned variable max_correl can be used to decide validity.
; Cross-correlation is computed directly by default, but if
; keyword /FFT is set it will be computed using FFTs of images.
; CALLING:
; correl_optimize, image_A, image_B, xoffset_optimum, yoffset_optimum
; INPUTS:
; image_A, image_B = the two images to be analyzed, the offset of
; image_B relative to image_A is determined.
; KEYWORDS:
; XOFF_INIT = initial X pixel offset of image_B relative to image_A,
; YOFF_INIT = Y pixel offset, (default offsets are 0 and 0).
; MAX_REDUCTION = maximum reduction factor allowed, otherwise
; the first reduction rebins image into about 8 x 8 pixels.
; MAGNIFICATION = option to determine offsets up to fractional pixels,
; (example: MAG=2 means 1/2 pixel accuracy, default=1).
; /NUMPIX : (# overlap pixels)^(1/4) used as correlation weighting factor.
; /MONITOR causes the progress of computation to be briefly printed.
; /PRINT causes the results of analysis to be printed to standard output.
; /FFT : use FFT to compute correlation of images, usually faster,
; but may not be always accurate because periodic nature of FT
; may cause confusion (in this case /NUMPIX has no effect).
; But if data is well inside image boundaries it is accurate.
; OUTPUTS:
; xoffset_optimum = optimal X pixel offset of image_B relative to image_A.
; yoffset_optimum = optimal Y pixel offset.
; max_correl = the maximal correlation corresponding to optimal offset.
; edge = 1 if maximum is at edge of correlation domain, otherwise=0.
; plateau = 1 if maximum is in a plateau of correlation function, else=0.
; EXTERNAL CALLS:
; function correl_images( image_A, image_B )
; function convolve( image_A, image_B,/CORREL ) if /FFT is set.
; pro corrmat_analyze
; IDL system variable !DEBUG should be defined.
; PROCEDURE:
; The combination of function correl_images( image_A, image_B ) and
; pro corrmat_analyze is used to obtain the (x,y) offset
; yielding maximal correlation. The combination is first executed at
; large REDUCTION factor (to speed up computation) and with
; all possible shifts to find the approximate optimal (x,y) offsets.
; The reduction factor is then decreased by factors of 2 and
; the x & y shifts are kept small, thus zooming into the optimal offsets.
; Finally, the MAGNIFICATION option (if specified)
; is executed to determine the (x,y) offset up to fractional pixels.
; If /FFT is set then just use function convolve( image_A,image_B,/CORR )
; and pro corrmat_analyze to obtain the optimal (x,y) offset,
; rebinning the images first if magnification is greater than one.
; NOTES:
; Recommend that the images be normalized so that maximim=1,
; and thresholded at some uniform percent of max=1.
; See for example function modify_image.
; HISTORY:
; Written: Frank Varosi, NASA/GSFC, 1991.
;-
pro correl_optimize, image_A, image_B, xoffset_optimum, yoffset_optimum, $
max_correl, edge, plateau, $
XOFF_INIT = xoff_init, $
YOFF_INIT = yoff_init, $
PRINT=print, MONITOR=monitor, $
NUMPIX=numpix, MAGNIFICATION=Magf, $
MAX_REDUCTION = maxreducf, FFT=use_FFT
simA = size( image_A )
simB = size( image_B )
if (simA(0) LT 2) OR (simB(0) LT 2) then begin
message,"first two arguments must be images",/INFO
return
endif
if N_elements( xoff_init ) NE 1 then xoff_init=0
if N_elements( yoff_init ) NE 1 then yoff_init=0
xoff = xoff_init
yoff = yoff_init
if N_elements( Magf ) NE 1 then Magf=1
;This is option to use FFT and then return:
if keyword_set( use_FFT ) then begin
xoff = ( simA(1) - simB(1) )/2.
yoff = ( simA(2) - simB(2) )/2.
simA = Magf * simA
simB = Magf * simB
norm = 1/( Magf^2 * sqrt( total( image_A^2 ) * total( image_B^2 ) ) )
if N_elements( image_B ) GT N_elements( image_A ) then begin
corrmat_analyze, convolve( rebin( image_B, simB(1), simB(2) ), $
rebin( image_A, simA(1), simA(2) ), $
/CORREL ) * norm, MAG=Magf, $
xoffset_optimum, yoffset_optimum, $
max_correl, edge, plateau, PR=print, $
XOFF=-xoff, YOFF=-yoff
xoffset_optimum = -xoffset_optimum
yoffset_optimum = -yoffset_optimum
endif else begin
corrmat_analyze, convolve( rebin( image_A, simA(1), simA(2) ), $
rebin( image_B, simB(1), simB(2) ), $
/CORREL ) * norm, MAG=Magf, $
xoffset_optimum, yoffset_optimum, $
max_correl, edge, plateau, PR=print, $
XOFF=xoff, YOFF=yoff
endelse
return
endif
;This is normal method of direct correlations:
reducf = min( [simA(1:2),simB(1:2)] ) / 8 ;Bin average to about
; 8 by 8 pixel image.
reducf = 2^round_off( aLog( reducf )/aLog(2) ) ; make it power of 2.
if N_elements( maxreducf ) EQ 1 then reducf = reducf < maxreducf
xsiz = simA(1) > simB(1)
ysiz = simA(2) > simB(2)
xshift = xsiz
yshift = ysiz ;shift over the whole images first correlation.
while (reducf GT 1) do begin
corrmat_analyze, correl_images( image_A, image_B, NUM=numpix, $
XOFF=xoff, YOFF=yoff, $
XS=xshift, YS=yshift, $
REDUC=reducf, MONIT=monitor ), $
xoff, yoff, XOFF=xoff, YOFF=yoff, PR=print, REDUC=reducf
xshift = 2*reducf
yshift = 2*reducf ;shift over coarse pixel grid to refine
reducf = reducf/2 ; correlations at increasing resolution.
endwhile
if keyword_set( monitor ) then print,"Magnification = 1"
corrmat_analyze, correl_images( image_A, image_B, XSHIFT=3, YSHIFT=3, $
XOFF=xoff,YOFF=yoff, MON=monitor,NUM=numpix ),$
xoffset_optimum, yoffset_optimum, max_correl, $
edge, plateau, XOFF=xoff, YOFF=yoff, PR=print
if (Magf GE 2) then begin
xoff = xoffset_optimum ;refine offsets to
yoff = yoffset_optimum ; fractional pixels.
corrmat_analyze, correl_images( image_A, image_B, XOFF=xoff, $
YOFF=yoff, MAG=Magf, MON=monitor ), $
xoffset_optimum, yoffset_optimum, $
max_correl, edge, plateau, $
XOFF=xoff,YOFF=yoff,PR=print, MAG=Magf
endif
end