00001
00002
00003
00004
00005
00006
00007 #include "mrilib.h"
00008
00009
00010
00011
00012
00013
00014
00015 #define DFILT_SIGMA (4.0*0.42466090)
00016 #define MAX_ITER 5
00017 #define DXY_THRESH 0.15
00018 #define PHI_THRESH 0.45
00019 #define DFAC (PI/180.0)
00020
00021 #define FINE_FIT
00022
00023 #define FINE_SIGMA (1.0*0.42466090)
00024 #define FINE_DXY_THRESH 0.07
00025 #define FINE_PHI_THRESH 0.21
00026
00027
00028
00029
00030
00031
00032 static float dfilt_sigma = DFILT_SIGMA ,
00033 dxy_thresh = DXY_THRESH ,
00034 phi_thresh = PHI_THRESH ,
00035 fine_sigma = FINE_SIGMA ,
00036 fine_dxy_thresh = FINE_DXY_THRESH ,
00037 fine_phi_thresh = FINE_PHI_THRESH ;
00038
00039 static int max_iter = MAX_ITER ;
00040
00041 void mri_2dalign_params( int maxite,
00042 float sig , float dxy , float dph ,
00043 float fsig, float fdxy, float fdph )
00044 {
00045 if( maxite > 0 ) max_iter = maxite ; else max_iter = MAX_ITER ;
00046 if( sig > 0.0 ) dfilt_sigma = sig ; else dfilt_sigma = DFILT_SIGMA ;
00047 if( dxy > 0.0 ) dxy_thresh = dxy ; else dxy_thresh = DXY_THRESH ;
00048 if( dph > 0.0 ) phi_thresh = dph ; else phi_thresh = PHI_THRESH ;
00049
00050 fine_sigma = fsig ;
00051 if( fdxy > 0.0 ) fine_dxy_thresh = fdxy ; else fine_dxy_thresh = FINE_DXY_THRESH ;
00052 if( fdph > 0.0 ) fine_phi_thresh = fdph ; else fine_phi_thresh = FINE_PHI_THRESH ;
00053
00054 return ;
00055 }
00056
00057
00058 static int almode_coarse = MRI_BICUBIC ;
00059 static int almode_fine = MRI_BICUBIC ;
00060 static int almode_reg = MRI_BICUBIC ;
00061
00062 #define MRI_ROTA_COARSE(a,b,c,d) mri_rota_variable(almode_coarse,(a),(b),(c),(d))
00063 #define MRI_ROTA_FINE(a,b,c,d) mri_rota_variable(almode_fine ,(a),(b),(c),(d))
00064 #define MRI_ROTA_REG(a,b,c,d) mri_rota_variable(almode_reg ,(a),(b),(c),(d))
00065
00066 void mri_2dalign_method( int coarse , int fine , int reg )
00067 {
00068 if( coarse > 0 ) almode_coarse = coarse ;
00069 if( fine > 0 ) almode_fine = fine ;
00070 if( reg > 0 ) almode_reg = reg ;
00071 return ;
00072 }
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 MRI_2dalign_basis * mri_2dalign_setup( MRI_IMAGE * imbase , MRI_IMAGE * imwt )
00086 {
00087 MRI_IMAGE * im1 , *bim,*xim,*yim,*tim , *bim2 , * im2 , *imww ;
00088 float *tar,*xar,*yar ;
00089 int nx,ny , ii,jj , joff ;
00090 int use_fine_fit = (fine_sigma > 0.0) ;
00091 float hnx,hny ;
00092
00093 MRI_IMARR * fitim =NULL;
00094 double * chol_fitim=NULL ;
00095 MRI_IMARR * fine_fitim =NULL ;
00096 double * chol_fine_fitim=NULL ;
00097 MRI_2dalign_basis * bout = NULL ;
00098
00099 if( ! MRI_IS_2D(imbase) ){
00100 fprintf(stderr,"\n*** mri_2dalign_setup: cannot use nD images!\a\n") ;
00101 return NULL ;
00102 }
00103
00104 im1 = mri_to_float( imbase ) ;
00105 nx = im1->nx ; hnx = 0.5 * nx ;
00106 ny = im1->ny ; hny = 0.5 * ny ;
00107
00108 bim = mri_filt_fft( im1, dfilt_sigma, 0, 0, FILT_FFT_WRAPAROUND ) ;
00109 xim = mri_filt_fft( im1, dfilt_sigma, 1, 0, FILT_FFT_WRAPAROUND ) ;
00110 yim = mri_filt_fft( im1, dfilt_sigma, 0, 1, FILT_FFT_WRAPAROUND ) ;
00111
00112 tim = mri_new( nx , ny , MRI_float ) ;
00113 tar = mri_data_pointer( tim ) ;
00114 xar = mri_data_pointer( xim ) ;
00115 yar = mri_data_pointer( yim ) ;
00116 for( jj=0 ; jj < ny ; jj++ ){
00117 joff = jj * nx ;
00118 for( ii=0 ; ii < nx ; ii++ ){
00119 tar[ii+joff] = DFAC * ( (ii-hnx) * yar[ii+joff]
00120 - (jj-hny) * xar[ii+joff] ) ;
00121 }
00122 }
00123 INIT_IMARR ( fitim ) ;
00124 ADDTO_IMARR( fitim , bim ) ;
00125 ADDTO_IMARR( fitim , xim ) ;
00126 ADDTO_IMARR( fitim , yim ) ;
00127 ADDTO_IMARR( fitim , tim ) ;
00128
00129 if( imwt == NULL ) imww = mri_to_float( bim ) ;
00130 else imww = mri_to_float( imwt ) ;
00131
00132 tar = MRI_FLOAT_PTR(imww) ;
00133 for( ii=0 ; ii < nx*ny ; ii++ ) tar[ii] = fabs(tar[ii]) ;
00134
00135 chol_fitim = mri_startup_lsqfit( fitim , imww ) ;
00136 mri_free(imww) ;
00137
00138 if( use_fine_fit ){
00139 bim = mri_filt_fft( im1, fine_sigma, 0, 0, FILT_FFT_WRAPAROUND ) ;
00140 xim = mri_filt_fft( im1, fine_sigma, 1, 0, FILT_FFT_WRAPAROUND ) ;
00141 yim = mri_filt_fft( im1, fine_sigma, 0, 1, FILT_FFT_WRAPAROUND ) ;
00142
00143 tim = mri_new( nx , ny , MRI_float ) ;
00144 tar = mri_data_pointer( tim ) ;
00145 xar = mri_data_pointer( xim ) ;
00146 yar = mri_data_pointer( yim ) ;
00147 for( jj=0 ; jj < ny ; jj++ ){
00148 joff = jj * nx ;
00149 for( ii=0 ; ii < nx ; ii++ ){
00150 tar[ii+joff] = DFAC * ( (ii-hnx) * yar[ii+joff]
00151 - (jj-hny) * xar[ii+joff] ) ;
00152 }
00153 }
00154 INIT_IMARR ( fine_fitim ) ;
00155 ADDTO_IMARR( fine_fitim , bim ) ;
00156 ADDTO_IMARR( fine_fitim , xim ) ;
00157 ADDTO_IMARR( fine_fitim , yim ) ;
00158 ADDTO_IMARR( fine_fitim , tim ) ;
00159
00160 if( imwt == NULL ) imww = mri_to_float( bim ) ;
00161 else imww = mri_to_float( imwt ) ;
00162
00163 tar = MRI_FLOAT_PTR(imww) ;
00164 for( ii=0 ; ii < nx*ny ; ii++ ) tar[ii] = fabs(tar[ii]) ;
00165
00166 chol_fine_fitim = mri_startup_lsqfit( fine_fitim , imww ) ;
00167 mri_free(imww) ;
00168 }
00169
00170 mri_free(im1) ;
00171
00172 bout = (MRI_2dalign_basis *) malloc( sizeof(MRI_2dalign_basis) ) ;
00173 bout->fitim = fitim ;
00174 bout->chol_fitim = chol_fitim ;
00175 bout->fine_fitim = fine_fitim ;
00176 bout->chol_fine_fitim = chol_fine_fitim ;
00177 return bout ;
00178 }
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 MRI_IMAGE * mri_2dalign_one( MRI_2dalign_basis * basis , MRI_IMAGE * im ,
00190 float * dx , float * dy , float * phi )
00191 {
00192 MRI_IMARR * fitim ;
00193 double * chol_fitim=NULL ;
00194 MRI_IMARR * fine_fitim =NULL ;
00195 double * chol_fine_fitim=NULL ;
00196
00197 float * fit , *dfit ;
00198 int nx,ny , ii,jj , joff , iter , good ;
00199 int use_fine_fit = (fine_sigma > 0.0) ;
00200 MRI_IMAGE * im2 , * bim2 , * tim ;
00201
00202 nx = im->nx ; ny = im->ny ;
00203
00204 fitim = basis->fitim ;
00205 chol_fitim = basis->chol_fitim ;
00206 fine_fitim = basis->fine_fitim ;
00207 chol_fine_fitim = basis->chol_fine_fitim ;
00208
00209
00210
00211 im2 = mri_to_float( im ) ;
00212 bim2 = mri_filt_fft( im2, dfilt_sigma, 0,0, FILT_FFT_WRAPAROUND ) ;
00213 fit = mri_delayed_lsqfit( bim2 , fitim , chol_fitim ) ;
00214 mri_free( bim2 ) ;
00215
00216 iter = 0 ;
00217 good = ( fabs(fit[1]) > dxy_thresh ||
00218 fabs(fit[2]) > dxy_thresh || fabs(fit[3]) > phi_thresh ) ;
00219
00220
00221
00222 while( good ){
00223 tim = MRI_ROTA_COARSE( im2 , fit[1] , fit[2] , fit[3]*DFAC ) ;
00224 bim2 = mri_filt_fft( tim, dfilt_sigma, 0,0, FILT_FFT_WRAPAROUND ) ;
00225 dfit = mri_delayed_lsqfit( bim2 , fitim , chol_fitim ) ;
00226 mri_free( bim2 ) ; mri_free( tim ) ;
00227
00228 fit[1] += dfit[1] ;
00229 fit[2] += dfit[2] ;
00230 fit[3] += dfit[3] ;
00231
00232 good = (++iter < max_iter) &&
00233 ( fabs(dfit[1]) > dxy_thresh ||
00234 fabs(dfit[2]) > dxy_thresh || fabs(dfit[3]) > phi_thresh ) ;
00235
00236 free(dfit) ; dfit = NULL ;
00237 }
00238
00239
00240
00241 if( use_fine_fit ){
00242 good = 1 ;
00243 while( good ){
00244 tim = MRI_ROTA_FINE( im2 , fit[1] , fit[2] , fit[3]*DFAC ) ;
00245 bim2 = mri_filt_fft( tim, fine_sigma, 0,0, FILT_FFT_WRAPAROUND ) ;
00246 dfit = mri_delayed_lsqfit( bim2 , fine_fitim , chol_fine_fitim ) ;
00247 mri_free( bim2 ) ; mri_free( tim ) ;
00248
00249 fit[1] += dfit[1] ;
00250 fit[2] += dfit[2] ;
00251 fit[3] += dfit[3] ;
00252
00253 good = (++iter < max_iter) &&
00254 ( fabs(dfit[1]) > fine_dxy_thresh ||
00255 fabs(dfit[2]) > fine_dxy_thresh || fabs(dfit[3]) > fine_phi_thresh ) ;
00256
00257 free(dfit) ; dfit = NULL ;
00258 }
00259 }
00260
00261
00262
00263 if( dx != NULL ) *dx = fit[1] ;
00264 if( dy != NULL ) *dy = fit[2] ;
00265 if( phi!= NULL ) *phi= fit[3]*DFAC ;
00266
00267
00268
00269 tim = MRI_ROTA_REG( im2 , fit[1],fit[2],fit[3]*DFAC ) ;
00270 mri_free( im2 ) ;
00271 return tim ;
00272 }
00273
00274 MRI_IMARR * mri_2dalign_many( MRI_IMAGE * im , MRI_IMAGE * imwt , MRI_IMARR * ims ,
00275 float * dx , float * dy , float * phi )
00276 {
00277 int kim ;
00278 MRI_IMAGE * tim ;
00279 MRI_IMARR * alim ;
00280 MRI_2dalign_basis * basis ;
00281
00282 basis = mri_2dalign_setup( im , imwt ) ;
00283 if( basis == NULL ) return NULL ;
00284
00285 INIT_IMARR( alim ) ;
00286
00287 for( kim=0 ; kim < ims->num ; kim++ ){
00288 tim = mri_2dalign_one( basis , ims->imarr[kim] , dx+kim , dy+kim , phi+kim ) ;
00289 ADDTO_IMARR(alim,tim) ;
00290 }
00291
00292 mri_2dalign_cleanup( basis ) ;
00293 return alim ;
00294 }
00295
00296 void mri_2dalign_cleanup( MRI_2dalign_basis * basis )
00297 {
00298 if( basis == NULL ) return ;
00299
00300 if( basis->fitim != NULL ){ DESTROY_IMARR( basis->fitim ) ; }
00301 if( basis->chol_fitim != NULL ){ free(basis->chol_fitim) ; }
00302
00303 if( basis->fine_fitim != NULL ){ DESTROY_IMARR( basis->fine_fitim ) ; }
00304 if( basis->chol_fine_fitim != NULL ){ free(basis->chol_fine_fitim) ; }
00305
00306 free(basis) ; return ;
00307 }