#include "mrilib.h" int main( int argc , char * argv[] ) { int iarg=1 , dcode=0 , maxgap=9 , nftot=0, i=0; char * prefix="rowfillin" , * dstr=NULL; THD_3dim_dataset * inset , * outset ; MRI_IMAGE * brim ; int verb=0, bin=0; if( argc < 2 || strcmp(argv[1],"-help") == 0 ){ printf("Usage: 3dRowFillin [options] dataset\n" "Extracts 1D rows in the given direction from a 3D dataset,\n" "searches for blank (zero) regions, and fills them in if\n" "the blank region isn't too large and it is flanked by\n" "the same value on either edge. For example:\n" " input row = 0 1 2 0 0 2 3 0 3 0 0 4 0\n" " output row = 0 1 2 2 2 2 3 3 3 0 0 4 0\n" "\n" "OPTIONS:\n" " -maxgap N = set the maximum length of a blank region that\n" " will be filled in to 'N' [default=9].\n" " -dir D = set the direction of fill to 'D', which can\n" " be one of the following:\n" " A-P, P-A, I-S, S-I, L-R, R-L, x, y, z, \n" " XYZ.OR, XYZ.AND\n" " The first 6 are anatomical directions;\n" " x,y, and z, are reference to the dataset\n" " internal axes. \n" " XYZ.OR means do the fillin in x, followed by y,\n" " followed by z directions.\n" " XYZ.AND is like XYZ.OR but only accept voxels that\n" " would have been filled in each of the three fill\n" " calls. \n" " Note that with XYZ* options, the fill value depends on\n" " on the axis orientation. So you're better off sticking\n" " to single valued dsets when using them. \n" " See also -binary option below\n" " -binary: Turn input dataset to 0 and 1 before filling in.\n" " Output will also be a binary valued dataset.\n" " -prefix P = set the prefix to 'P' for the output dataset.\n" "\n" "N.B.: If the input dataset has more than one sub-brick,\n" " only the first one will be processed.\n" "\n" "* The intention of this program is to let you fill in slice gaps\n" " made when drawing ROIs with the 'Draw Dataset' plugin. If you\n" " draw every 5th coronal slice, say, then you could fill in using\n" " 3dRowFillin -maxgap 4 -dir A-P -prefix fredfill fred+orig\n" "* This program is moderately obsolescent, since I later added\n" " the 'Linear Fillin' controls to the 'Draw Dataset' plugin.\n" "\n" ) ; PRINT_COMPILE_DATE ; exit(0) ; } mainENTRY("3dRowFillin main"); machdep(); AFNI_logger("3dRowFillin",argc,argv); PRINT_VERSION("3dRowFillin") ; /*-- scan args --*/ while( iarg < argc && argv[iarg][0] == '-' ){ if( strncmp(argv[iarg],"-verb",5) == 0 ){ verb++ ; iarg++ ; continue ; } if( strncmp(argv[iarg],"-bin",4) == 0 ){ bin=1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-prefix") == 0 ){ prefix = argv[++iarg] ; if( !THD_filename_ok(prefix) ){ fprintf(stderr,"*** Illegal string after -prefix!\n"); exit(1) ; } iarg++ ; continue ; } if( strcmp(argv[iarg],"-maxgap") == 0 ){ maxgap = strtol( argv[++iarg] , NULL , 10 ) ; if( maxgap < 1 ){ fprintf(stderr,"*** Illegal value after -maxgap!\n"); exit(1); } iarg++ ; continue ; } if( strcmp(argv[iarg],"-dir") == 0 ){ dstr = argv[++iarg] ; iarg++ ; continue ; } fprintf(stderr,"*** Illegal option: %s\n",argv[iarg]) ; exit(1) ; } if( dstr == NULL ){ fprintf(stderr,"*** No -dir option on command line!\n"); exit(1); } if( iarg >= argc ){ fprintf(stderr,"*** No input dataset on command line!\n"); exit(1); } inset = THD_open_dataset( argv[iarg] ) ; CHECK_OPEN_ERROR(inset,argv[iarg]) ; outset = EDIT_empty_copy( inset ) ; EDIT_dset_items( outset , ADN_prefix , prefix , ADN_none ) ; if( THD_deathcon() && THD_is_file( DSET_HEADNAME(outset) ) ){ fprintf(stderr,"** Output file %s exists -- cannot overwrite!\n", DSET_HEADNAME(outset) ) ; exit(1) ; } tross_Copy_History( inset , outset ) ; tross_Make_History( "3dRowFillin" , argc,argv , outset ) ; if( DSET_NVALS(inset) > 1 ){ fprintf(stderr,"++ WARNING: input dataset has more than one sub-brick!\n"); EDIT_dset_items( outset , ADN_ntt , 0 , ADN_nvals , 1 , ADN_none ) ; } if( DSET_BRICK_TYPE(outset,0) != MRI_short && DSET_BRICK_TYPE(outset,0) != MRI_byte ){ fprintf(stderr,"*** This program only works on byte and short dataset!\n"); exit(1) ; } if (strcasecmp(dstr,"XYZ.OR") ==0) dcode = 4; else if (strcasecmp(dstr,"XYZ.AND")==0) dcode = 5; else { switch( *dstr ){ case 'X': case 'x': dcode = 1 ; break ; case 'Y': case 'y': dcode = 2 ; break ; case 'Z': case 'z': dcode = 3 ; break ; default: if( *dstr == ORIENT_tinystr[outset->daxes->xxorient][0] || *dstr == ORIENT_tinystr[outset->daxes->xxorient][1] ) dcode = 1 ; if( *dstr == ORIENT_tinystr[outset->daxes->yyorient][0] || *dstr == ORIENT_tinystr[outset->daxes->yyorient][1] ) dcode = 2 ; if( *dstr == ORIENT_tinystr[outset->daxes->zzorient][0] || *dstr == ORIENT_tinystr[outset->daxes->zzorient][1] ) dcode = 3 ; break ; } } if( dcode == 0 ){ ERROR_exit("Illegal -dir direction '%s'",dstr) ; } if( verb ) INFO_message("Direction = axis %d in dataset",dcode) ; if (bin) DSET_mallocize(inset); DSET_load(inset) ; CHECK_LOAD_ERROR(inset) ; /* binarize input */ if (bin) { switch(DSET_BRICK_TYPE(inset,0)) { case MRI_short: { short *dp; dp = DSET_ARRAY(inset, 0); for (i=0; ikind , mri_data_pointer(brim) ) ; DSET_unload(inset) ; nftot = THD_dataset_rowfillin( outset , 0 , dcode , maxgap ) ; fprintf(stderr,"++ Number of voxels filled = %d\n",nftot) ; } else if (dcode == 4) { brim = mri_copy( DSET_BRICK(inset,0) ) ; EDIT_substitute_brick( outset , 0 , brim->kind , mri_data_pointer(brim) ) ; DSET_unload(inset) ; nftot = 0; dcode=0; for (dcode=1; dcode<4; ++dcode) { nftot = nftot + THD_dataset_rowfillin( outset , 0 , dcode , maxgap ) ; } fprintf(stderr,"++ Number of voxels OR filled = %d\n",nftot) ; } else if (dcode == 5) { int nf=0; THD_3dim_dataset *otmp[3]={NULL, NULL, NULL}; MRI_IMAGE *brimtmp=NULL; brim = mri_copy( DSET_BRICK(inset,0) ) ; EDIT_substitute_brick( outset , 0 , brim->kind , mri_data_pointer(brim) ) ; for (i=0; i<3; ++i) { otmp[i] = EDIT_empty_copy( outset ) ; brimtmp = mri_copy( DSET_BRICK(inset,0) ) ; EDIT_substitute_brick( otmp[i] , 0 , brimtmp->kind, mri_data_pointer(brimtmp) ) ; THD_dataset_rowfillin( otmp[i] , 0 , i+1 , maxgap); } DSET_unload(inset) ; switch(DSET_BRICK_TYPE(outset,0)) { case MRI_short: { short * dp[3], *doo; nftot = 0; doo = DSET_ARRAY(outset, 0); for (i=0; i<3; ++i) dp[i] = DSET_ARRAY(otmp[i], 0); for (i=0; i