#include "mrilib.h"
/*----------------------------------------------------------------*/
/*! Modified MCW_find_clusters():
- added mode variable
- ISOVALUE_MODE => make clusters that are both contiguous
and have the same numerical value
- ISOMERGE_MODE => make clusters that have the same numerical
value, regardless of contiguity
------------------------------------------------------------------*/
MCW_cluster_array * NIH_find_clusters(
int nx, int ny, int nz,
float dx, float dy, float dz,
int ftype , void * fim ,
float max_dist , int mode )
{
MCW_cluster_array *clust_arr ;
MCW_cluster *clust , *mask=NULL ;
int ii,jj,kk , nxy,nxyz , ijk , ijk_last , mnum ;
int icl , jma , ijkcl , ijkma , did_one ;
float fimv ;
short *sfar ;
float *ffar ;
byte *bfar ;
short ic, jc, kc;
short im, jm, km;
ENTRY("NIH_find_clusters") ;
if( fim == NULL ) RETURN(NULL) ;
switch( ftype ){
default: RETURN(NULL) ;
case MRI_short: sfar = (short *) fim ; break ;
case MRI_byte : bfar = (byte *) fim ; break ;
case MRI_float: ffar = (float *) fim ; break ;
}
/* default => use older code (in edt_clust.c) */
if( mode <= 0 || mode > ISOMERGE_MODE ){
RETURN( MCW_find_clusters( nx,ny,nz , dx,dy,dz ,
ftype,fim , max_dist ) ) ;
}
/*--- make a cluster that is a mask of points closer than max_dist ---*/
if( mode == ISOVALUE_MODE ){
mask = MCW_build_mask (dx, dy, dz, max_dist);
if (mask == NULL)
{
fprintf(stderr, "Unable to build mask in NIH_find_clusters");
RETURN(NULL);
}
mnum = mask->num_pt ;
}
nxy = nx*ny ; nxyz = nxy * nz ;
/*--- scan through array, find nonzero point, build a cluster, ... ---*/
INIT_CLARR(clust_arr) ;
ijk_last = 0 ;
do {
/* find nonzero point in 3D array, starting at ijk_last */
switch( ftype ){
case MRI_short:
for( ijk=ijk_last ; ijk < nxyz ; ijk++ ) if( sfar[ijk] != 0 ) break ;
if( ijk < nxyz ){
fimv = sfar[ijk] ; sfar[ijk] = 0 ; /* save found point */
}
break ;
case MRI_byte:
for( ijk=ijk_last ; ijk < nxyz ; ijk++ ) if( bfar[ijk] != 0 ) break ;
if( ijk < nxyz ){
fimv = bfar[ijk] ; bfar[ijk] = 0 ; /* save found point */
}
break ;
case MRI_float:
for( ijk=ijk_last ; ijk < nxyz ; ijk++ ) if( ffar[ijk] != 0.0 ) break ;
if( ijk < nxyz ){
fimv = ffar[ijk] ; ffar[ijk] = 0.0 ; /* save found point */
}
break ;
}
if( ijk == nxyz ) break ; /* didn't find any nonzero point! */
ijk_last = ijk+1 ; /* start here next time */
INIT_CLUSTER(clust) ; /* make a new cluster */
IJK_TO_THREE(ijk,ic,jc,kc,nx,nxy) ; /* find 3D index */
ADDTO_CLUSTER( clust , ic, jc, kc, fimv ) ; /* start cluster off */
switch( mode ){
case ISOVALUE_MODE:{ /* for each point in cluster:
check points offset by mask for nonzero entries in fim
enter those into cluster
continue until end of cluster is reached
(note that cluster is expanding as we progress) */
switch( ftype ){
case MRI_short:
for( icl=0 ; icl < clust->num_pt ; icl++ ){
ic = clust->i[icl]; /* check around this point */
jc = clust->j[icl];
kc = clust->k[icl];
for( jma=0 ; jma < mnum ; jma++ ){
im = ic + mask->i[jma]; /* offset by mask */
jm = jc + mask->j[jma];
km = kc + mask->k[jma];
if( im < 0 || im >= nx ||
jm < 0 || jm >= ny || km < 0 || km >= nz ) continue ;
ijkma = THREE_TO_IJK (im, jm, km, nx, nxy);
if( ijkma < ijk_last || ijkma >= nxyz || sfar[ijkma] != fimv ) continue ;
ADDTO_CLUSTER( clust , im, jm, km, sfar[ijkma] ) ;
sfar[ijkma] = 0 ;
}
}
break ;
case MRI_byte:
for( icl=0 ; icl < clust->num_pt ; icl++ ){
ic = clust->i[icl];
jc = clust->j[icl];
kc = clust->k[icl];
for( jma=0 ; jma < mnum ; jma++ ){
im = ic + mask->i[jma];
jm = jc + mask->j[jma];
km = kc + mask->k[jma];
if( im < 0 || im >= nx ||
jm < 0 || jm >= ny || km < 0 || km >= nz ) continue ;
ijkma = THREE_TO_IJK (im, jm, km, nx, nxy);
if( ijkma < ijk_last || ijkma >= nxyz || bfar[ijkma] != fimv ) continue ;
ADDTO_CLUSTER( clust , im, jm, km, bfar[ijkma] ) ;
bfar[ijkma] = 0 ;
}
}
break ;
case MRI_float:
for( icl=0 ; icl < clust->num_pt ; icl++ ){
ic = clust->i[icl];
jc = clust->j[icl];
kc = clust->k[icl];
for( jma=0 ; jma < mnum ; jma++ ){
im = ic + mask->i[jma];
jm = jc + mask->j[jma];
km = kc + mask->k[jma];
if( im < 0 || im >= nx ||
jm < 0 || jm >= ny || km < 0 || km >= nz ) continue ;
ijkma = THREE_TO_IJK (im, jm, km, nx, nxy);
if( ijkma < ijk_last || ijkma >= nxyz || ffar[ijkma] != fimv ) continue ;
ADDTO_CLUSTER( clust , im, jm, km, ffar[ijkma] ) ;
ffar[ijkma] = 0.0 ;
}
}
break ;
} /* end of switch on array type */
}
break ; /* end of ISOVALUE_MODE */
/*.................................*/
case ISOMERGE_MODE:{ /* find other points with the same value */
switch( ftype ){
case MRI_short:
for( ijk=ijk_last ; ijk < nxyz ; ijk++ )
if( sfar[ijk] == fimv ){
IJK_TO_THREE(ijk,ic,jc,kc,nx,nxy) ; /* find 3D index */
ADDTO_CLUSTER( clust , ic, jc, kc, fimv ) ; /* start cluster off */
sfar[ijk] = 0 ;
}
break ;
case MRI_byte:
for( ijk=ijk_last ; ijk < nxyz ; ijk++ )
if( bfar[ijk] == fimv ){
IJK_TO_THREE(ijk,ic,jc,kc,nx,nxy) ; /* find 3D index */
ADDTO_CLUSTER( clust , ic, jc, kc, fimv ) ; /* start cluster off */
bfar[ijk] = 0 ;
}
break ;
case MRI_float:
for( ijk=ijk_last ; ijk < nxyz ; ijk++ )
if( ffar[ijk] == fimv ){
IJK_TO_THREE(ijk,ic,jc,kc,nx,nxy) ; /* find 3D index */
ADDTO_CLUSTER( clust , ic, jc, kc, fimv ) ; /* start cluster off */
ffar[ijk] = 0 ;
}
break ;
}
}
break ; /* end of ISOMERGE_MODE */
}
ADDTO_CLARR(clust_arr,clust) ;
} while( 1 ) ;
if( mask != NULL ) KILL_CLUSTER(mask) ;
if( clust_arr->num_clu <= 0 ){ DESTROY_CLARR(clust_arr) ; }
RETURN(clust_arr) ;
}
syntax highlighted by Code2HTML, v. 0.9.1