#include "mrilib.h"
/*----------------------------------------------------------------------*/
/*! Return a measure of the difference between 2 images bim and nim,
possibly with a mask to indicate which voxels to include.
The difference is defined as dd below:
ss = min sum [ bim[i] - a * nim[i] ]**2
a i
dd = sqrt( ss / #voxels ) i.e., the RMS difference.
That is, we least squares fit image nim to bim by a scale factor,
and the residual determins the difference. The minimizing value of
'a' is given by
a = BN / NN where BN = sum [ bim[i]*nim[i] ]
NN = sum [ nim[i]**2 ]
so the difference is given by
diff = BB - (BN)**2/NN where BB = sum[ bim[i]**2 ]
- A negative return value indicates an error.
- If bim=0, then the return value will be 0.
- If bim!=0 and nim=0, then the return value is computed with a=0
(that is, it will be the RMS value of bim)
------------------------------------------------------------------------*/
float mri_scaled_diff( MRI_IMAGE *bim , MRI_IMAGE *nim , MRI_IMAGE *msk )
{
int nvox , ii , nmask=0 ;
MRI_IMAGE *fim , *gim ;
float *far , *gar , sdif , ff,gg,fg ;
byte *mar=NULL ;
ENTRY("mri_scaled_diff") ;
if( bim == NULL || nim == NULL ) RETURN(-1.0f) ;
nvox = bim->nvox ; if( nim->nvox != nvox ) RETURN(-1.0f) ;
if( msk != NULL && msk->kind == MRI_byte && msk->nvox == nvox ){
mar = MRI_BYTE_PTR(msk) ;
nmask = THD_countmask( nvox , mar ) ;
if( nmask < 3 ){ nmask = 0 ; mar = NULL ; }
}
fim = (bim->kind != MRI_float) ? mri_to_float(bim) : bim ;
gim = (nim->kind != MRI_float) ? mri_to_float(nim) : nim ;
far = MRI_FLOAT_PTR(fim) ; gar = MRI_FLOAT_PTR(gim) ;
ff = gg = fg = 0.0f ;
for( ii=0 ; ii < nvox ; ii++ ){
if( nmask == 0 || mar[ii] != 0 ){
ff += far[ii] * far[ii] ;
gg += gar[ii] * gar[ii] ;
fg += far[ii] * gar[ii] ;
}
}
if( gg > 0.0f ){ /* normal case */
sdif = ff - fg*fg/gg ;
if( sdif > 0.0f )
sdif = sqrt( sdif / ((nmask > 0) ? nmask : nvox) ) ;
} else if( ff <= 0.0f ) /* far=gar=0 */
sdif = 0.0f ;
else /* gar=0 far!=0 */
sdif = sqrt( ff / ((nmask > 0) ? nmask : nvox) ) ;
/** done **/
if( fim != bim ) mri_free(fim) ;
if( gim != nim ) mri_free(gim) ;
RETURN(sdif) ;
}
syntax highlighted by Code2HTML, v. 0.9.1