#include "mrilib.h" /*------------------------------------------------------------------------*/ /*! Computes various metrics between the histograms (joint and marginal) of two images. At this stage, experimental -- RWCox - 25 Apr 2006. --------------------------------------------------------------------------*/ void mri_metrics( MRI_IMAGE *imp , MRI_IMAGE *imq , float *met ) { int nvox ; int *rst , *pst , *qst ; byte *par, *qar ; float qj,rij , rat,tmp,lrr,rm1,rp1 , fac ; float esum,tsum,hsum , jsum,dsum,xsum , qsum,asum ; register int ii,jj,kk ; MRI_IMAGE *imqq, *impp ; if( imp == NULL || imq == NULL ) return ; if( met == NULL || imp->nvox != imq->nvox ) return ; nvox = imp->nvox ; fac = 1.0f / nvox ; impp = (imp->kind==MRI_byte) ? imp : mri_to_byte(imp) ; imqq = (imq->kind==MRI_byte) ? imq : mri_to_byte(imq) ; par = MRI_BYTE_PTR(impp) ; qar = MRI_BYTE_PTR(imqq) ; pst = (int *)calloc(256 ,sizeof(int)) ; qst = (int *)calloc(256 ,sizeof(int)) ; rst = (int *)calloc(256*256,sizeof(int)) ; for( kk=0 ; kk < nvox ; kk++ ){ ii = par[kk] ; jj = qar[kk] ; pst[ii]++ ; qst[jj]++ ; rst[ii+256*jj]++ ; } esum = tsum = hsum = 0.0f ; jsum = dsum = xsum = 0.0f ; qsum = asum = 0.0f ; for( jj=0 ; jj < 256 ; jj++ ){ qj = (float)qst[jj] ; if( qj > 0.0f ){ kk = 256*jj ; qj *= fac ; for( ii=0 ; ii < 256 ; ii++ ){ rij = (float)rst[ii+kk] ; if( rij > 0.0f ){ rat = (qj *(float)pst[ii]) / rij ; lrr = logf(rat) ; rm1 = rat-1.0f ; rp1 = rat+1.0f ; esum += rij * lrr ; jsum += rij * lrr*rm1 ; tsum += rij * rm1*rm1/rp1 ; dsum += rij * (rat*lrr - rp1*logf(0.5*rp1)) ; xsum += rij * rm1*rm1*rp1/rat ; #if 0 tmp = sqrtf(rat)-1.0f ; hsum += rij * tmp*tmp ; #else tmp = 1.0f/sqrtf(rat)-1.0f ; hsum += rij * tmp ; #endif qsum += rij * (1.0f/rat-1.0f) ; tmp = 0.5*rp1 ; asum += rij * tmp * logf(tmp/sqrtf(rat)) ; } } } } free((void*)rst); free((void*)qst); free((void*)pst); if( impp != imp ) mri_free(impp); if( imqq != imq ) mri_free(imqq); met[METRIC_KULL] = -fac * esum ; met[METRIC_HELL] = fac * hsum ; met[METRIC_TRIA] = fac * tsum ; met[METRIC_JDIV] = fac * jsum * 0.50f ; met[METRIC_JSDV] = fac * dsum * 2.00f ; met[METRIC_XISQ] = fac * xsum * 0.25f ; met[METRIC_XXSQ] = fac * xsum * 0.50f ; met[METRIC_AGDV] = fac * asum ; return ; }