Home > SuperSegger > Internal > dftregistration.m

dftregistration

PURPOSE ^

dftregistration : Efficient subpixel image registration by crosscorrelation.

SYNOPSIS ^

function [output, Greg] = dftregistration(buf1ft,buf2ft,usfac)

DESCRIPTION ^

 dftregistration : Efficient subpixel image registration by crosscorrelation. 
 This code gives the same precision as the FFT upsampled cross correlation in a
 small fraction of the computation time and with reduced memory 
 requirements. It obtains an initial estimate of the crosscorrelation peak
 by an FFT and then refines the shift estimation by upsampling the DFT
 only in a small neighborhood of that estimate by means of a 
 matrix-multiply DFT. With this procedure all the image points are used to
 compute the upsampled crosscorrelation.
 Manuel Guizar - Dec 13, 2007

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function [output, Greg] = dftregistration(buf1ft,buf2ft,usfac)
0002 % dftregistration : Efficient subpixel image registration by crosscorrelation.
0003 % This code gives the same precision as the FFT upsampled cross correlation in a
0004 % small fraction of the computation time and with reduced memory
0005 % requirements. It obtains an initial estimate of the crosscorrelation peak
0006 % by an FFT and then refines the shift estimation by upsampling the DFT
0007 % only in a small neighborhood of that estimate by means of a
0008 % matrix-multiply DFT. With this procedure all the image points are used to
0009 % compute the upsampled crosscorrelation.
0010 % Manuel Guizar - Dec 13, 2007
0011 
0012 % Portions of this code were taken from code written by Ann M. Kowalczyk
0013 % and James R. Fienup.
0014 % J.R. Fienup and A.M. Kowalczyk, "Phase retrieval for a complex-valued
0015 % object by using a low-resolution image," J. Opt. Soc. Am. A 7, 450-458
0016 % (1990).
0017 
0018 % Citation for this algorithm:
0019 % Manuel Guizar-Sicairos, Samuel T. Thurman, and James R. Fienup,
0020 % "Efficient subpixel image registration algorithms," Opt. Lett. 33,
0021 % 156-158 (2008).
0022 
0023 % Inputs
0024 % buf1ft    Fourier transform of reference image,
0025 %           DC in (1,1)   [DO NOT FFTSHIFT]
0026 % buf2ft    Fourier transform of image to register,
0027 %           DC in (1,1) [DO NOT FFTSHIFT]
0028 % usfac     Upsampling factor (integer). Images will be registered to
0029 %           within 1/usfac of a pixel. For example usfac = 20 means the
0030 %           images will be registered within 1/20 of a pixel. (default = 1)
0031 
0032 % Outputs
0033 % output =  [error,diffphase,net_row_shift,net_col_shift]
0034 % error     Translation invariant normalized RMS error between f and g
0035 % diffphase     Global phase difference between the two images (should be
0036 %               zero if images are non-negative).
0037 % net_row_shift net_col_shift   Pixel shifts between images
0038 % Greg      (Optional) Fourier transform of registered version of buf2ft,
0039 %           the global phase difference is compensated for.
0040 
0041 % Default usfac to 1
0042 if exist('usfac')~=1, usfac=1; end
0043 
0044 % Compute error for no pixel shift
0045 if usfac == 0,
0046     CCmax = sum(sum(buf1ft.*conj(buf2ft))); 
0047     rfzero = sum(abs(buf1ft(:)).^2);
0048     rgzero = sum(abs(buf2ft(:)).^2); 
0049     error = 1.0 - CCmax.*conj(CCmax)/(rgzero*rfzero); 
0050     error = sqrt(abs(error));
0051     diffphase=atan2(imag(CCmax),real(CCmax)); 
0052     output=[error,diffphase];
0053         
0054 % Whole-pixel shift - Compute crosscorrelation by an IFFT and locate the
0055 % peak
0056 elseif usfac == 1,
0057     [m,n]=size(buf1ft);
0058     CC = ifft2(buf1ft.*conj(buf2ft));
0059     [max1,loc1] = max(CC);
0060     [max2,loc2] = max(max1);
0061     rloc=loc1(loc2);
0062     cloc=loc2;
0063     CCmax=CC(rloc,cloc); 
0064     rfzero = sum(abs(buf1ft(:)).^2)/(m*n);
0065     rgzero = sum(abs(buf2ft(:)).^2)/(m*n); 
0066     error = 1.0 - CCmax.*conj(CCmax)/(rgzero(1,1)*rfzero(1,1));
0067     error = sqrt(abs(error));
0068     diffphase=atan2(imag(CCmax),real(CCmax)); 
0069     md2 = fix(m/2); 
0070     nd2 = fix(n/2);
0071     if rloc > md2
0072         row_shift = rloc - m - 1;
0073     else
0074         row_shift = rloc - 1;
0075     end
0076 
0077     if cloc > nd2
0078         col_shift = cloc - n - 1;
0079     else
0080         col_shift = cloc - 1;
0081     end
0082     output=[error,diffphase,row_shift,col_shift];
0083     
0084 % Partial-pixel shift
0085 else
0086     
0087     % First upsample by a factor of 2 to obtain initial estimate
0088     % Embed Fourier data in a 2x larger array
0089     [m,n]=size(buf1ft);
0090     mlarge=m*2;
0091     nlarge=n*2;
0092     CC=zeros(mlarge,nlarge);
0093     CC(m+1-fix(m/2):m+1+fix((m-1)/2),n+1-fix(n/2):n+1+fix((n-1)/2)) = ...
0094         fftshift(buf1ft).*conj(fftshift(buf2ft));
0095   
0096     % Compute crosscorrelation and locate the peak
0097     CC = ifft2(ifftshift(CC)); % Calculate cross-correlation
0098     [max1,loc1] = max(CC);
0099     [max2,loc2] = max(max1);
0100     rloc=loc1(loc2);cloc=loc2;
0101     CCmax=CC(rloc,cloc);
0102     
0103     % Obtain shift in original pixel grid from the position of the
0104     % crosscorrelation peak
0105     [m,n] = size(CC); md2 = fix(m/2); nd2 = fix(n/2);
0106     if rloc > md2 
0107         row_shift = rloc - m - 1;
0108     else
0109         row_shift = rloc - 1;
0110     end
0111     if cloc > nd2
0112         col_shift = cloc - n - 1;
0113     else
0114         col_shift = cloc - 1;
0115     end
0116     row_shift=row_shift/2;
0117     col_shift=col_shift/2;
0118 
0119     % If upsampling > 2, then refine estimate with matrix multiply DFT
0120     if usfac > 2,
0121         %%% DFT computation %%%
0122         % Initial shift estimate in upsampled grid
0123         row_shift = round(row_shift*usfac)/usfac; 
0124         col_shift = round(col_shift*usfac)/usfac;     
0125         dftshift = fix(ceil(usfac*1.5)/2); %% Center of output array at dftshift+1
0126         % Matrix multiply DFT around the current shift estimate
0127         CC = conj(dftups(buf2ft.*conj(buf1ft),ceil(usfac*1.5),ceil(usfac*1.5),usfac,...
0128             dftshift-row_shift*usfac,dftshift-col_shift*usfac))/(md2*nd2*usfac^2);
0129         % Locate maximum and map back to original pixel grid
0130         [max1,loc1] = max(CC);   
0131         [max2,loc2] = max(max1); 
0132         rloc = loc1(loc2); cloc = loc2;
0133         CCmax = CC(rloc,cloc);
0134         rg00 = dftups(buf1ft.*conj(buf1ft),1,1,usfac)/(md2*nd2*usfac^2);
0135         rf00 = dftups(buf2ft.*conj(buf2ft),1,1,usfac)/(md2*nd2*usfac^2);  
0136         rloc = rloc - dftshift - 1;
0137         cloc = cloc - dftshift - 1;
0138         row_shift = row_shift + rloc/usfac;
0139         col_shift = col_shift + cloc/usfac;    
0140 
0141     % If upsampling = 2, no additional pixel shift refinement
0142     else    
0143         rg00 = sum(sum( buf1ft.*conj(buf1ft) ))/m/n;
0144         rf00 = sum(sum( buf2ft.*conj(buf2ft) ))/m/n;
0145     end
0146     error = 1.0 - CCmax.*conj(CCmax)/(rg00*rf00);
0147     error = sqrt(abs(error));
0148     diffphase=atan2(imag(CCmax),real(CCmax));
0149     % If its only one row or column the shift along that dimension has no
0150     % effect. We set to zero.
0151     if md2 == 1,
0152         row_shift = 0;
0153     end
0154     if nd2 == 1,
0155         col_shift = 0;
0156     end
0157     output=[error,diffphase,row_shift,col_shift];
0158 end  
0159 
0160 % Compute registered version of buf2ft
0161 if (nargout > 1)&&(usfac > 0),
0162     [nr,nc]=size(buf2ft);
0163     Nr = ifftshift([-fix(nr/2):ceil(nr/2)-1]);
0164     Nc = ifftshift([-fix(nc/2):ceil(nc/2)-1]);
0165     [Nc,Nr] = meshgrid(Nc,Nr);
0166     Greg = buf2ft.*exp(i*2*pi*(-row_shift*Nr/nr-col_shift*Nc/nc));
0167     Greg = Greg*exp(i*diffphase);
0168 elseif (nargout > 1)&&(usfac == 0)
0169     Greg = buf2ft*exp(i*diffphase);
0170 end
0171 return
0172 
0173 function out=dftups(in,nor,noc,usfac,roff,coff)
0174 % function out=dftups(in,nor,noc,usfac,roff,coff);
0175 % Upsampled DFT by matrix multiplies, can compute an upsampled DFT in just
0176 % a small region.
0177 % usfac         Upsampling factor (default usfac = 1)
0178 % [nor,noc]     Number of pixels in the output upsampled DFT, in
0179 %               units of upsampled pixels (default = size(in))
0180 % roff, coff    Row and column offsets, allow to shift the output array to
0181 %               a region of interest on the DFT (default = 0)
0182 % Recieves DC in upper left corner, image center must be in (1,1)
0183 % Manuel Guizar - Dec 13, 2007
0184 % Modified from dftus, by J.R. Fienup 7/31/06
0185 
0186 % This code is intended to provide the same result as if the following
0187 % operations were performed
0188 %   - Embed the array "in" in an array that is usfac times larger in each
0189 %     dimension. ifftshift to bring the center of the image to (1,1).
0190 %   - Take the FFT of the larger array
0191 %   - Extract an [nor, noc] region of the result. Starting with the
0192 %     [roff+1 coff+1] element.
0193 
0194 % It achieves this result by computing the DFT in the output array without
0195 % the need to zeropad. Much faster and memory efficient than the
0196 % zero-padded FFT approach if [nor noc] are much smaller than [nr*usfac nc*usfac]
0197 
0198 [nr,nc]=size(in);
0199 % Set defaults
0200 if exist('roff')~=1, roff=0; end
0201 if exist('coff')~=1, coff=0; end
0202 if exist('usfac')~=1, usfac=1; end
0203 if exist('noc')~=1, noc=nc; end
0204 if exist('nor')~=1, nor=nr; end
0205 % Compute kernels and obtain DFT by matrix products
0206 kernc=exp((-i*2*pi/(nc*usfac))*( ifftshift([0:nc-1]).' - floor(nc/2) )*( [0:noc-1] - coff ));
0207 kernr=exp((-i*2*pi/(nr*usfac))*( [0:nor-1].' - roff )*( ifftshift([0:nr-1]) - floor(nr/2)  ));
0208 out=kernr*in*kernc;
0209 return

Generated on Thu 19-Jan-2017 13:55:21 by m2html © 2005