static MRI * edit_amygdala(MRI *mri_in_labeled, MRI *mri_T1, MRI *mri_out_labeled) { int width, height, depth, x, y, z, nchanged, label, total_changed, dup, ddown, left ; MRI *mri_tmp ; mri_out_labeled = MRIcopy(mri_in_labeled, mri_out_labeled) ; mri_tmp = MRIcopy(mri_out_labeled, NULL) ; width = mri_T1->width ; height = mri_T1->height ; depth = mri_T1->depth ; total_changed = 0 ; do { nchanged = 0 ; /* change gray to wm if near amygdala */ for (z = 0 ; z < depth ; z++) { for (y = 0 ; y < height ; y++) { for (x = 0 ; x < width ; x++) { if (x == 95 && y == 127 && z == 119) DiagBreak() ; label = MRIvox(mri_tmp, x, y, z) ; left = 0 ; switch (label) { case Left_Cerebral_Cortex: left = 1 ; case Right_Cerebral_Cortex: dup = distance_to_label(mri_out_labeled, left ? Left_Amygdala : Right_Amygdala,x,y,z,0,-1,0,2); ddown = distance_to_label(mri_out_labeled, left ? Left_Cerebral_White_Matter : Right_Cerebral_White_Matter, x,y,z,0,1,0,3); if (dup <= 1 && ddown <= 1) { label = left ? Left_Cerebral_White_Matter : Right_Cerebral_White_Matter; MRIvox(mri_tmp, x, y, z) = label ; nchanged++ ; continue ; } default: break ; } } } } MRIcopy(mri_tmp, mri_out_labeled) ; total_changed += nchanged ; } while (nchanged > 0) ; MRIfree(&mri_tmp) ; printf("%d amygdala voxels changed.\n", total_changed) ; return(mri_out_labeled) ; }
static MRI * edit_cortical_gray_matter(MRI *mri_in_labeled,MRI *mri_T1,MRI *mri_out_labeled) { int width, height, depth, x, y, z, nchanged, label, total_changed, left, niter, change ; MRI *mri_tmp ; mri_out_labeled = MRIcopy(mri_in_labeled, mri_out_labeled) ; mri_tmp = MRIcopy(mri_out_labeled, NULL) ; width = mri_T1->width ; height = mri_T1->height ; depth = mri_T1->depth ; niter = total_changed = 0 ; do { nchanged = 0 ; /* change gray to wm if near amygdala */ for (z = 0 ; z < depth ; z++) { for (y = 0 ; y < height ; y++) { for (x = 0 ; x < width ; x++) { if (x == 95 && y == 127 && z == 119) DiagBreak() ; label = MRIvox(mri_tmp, x, y, z) ; change = left = 0 ; switch (label) { case Left_Cerebral_Cortex: case Unknown: case Right_Cerebral_Cortex: if (neighborLabel(mri_tmp,x,y,z,1,Left_Cerebral_White_Matter) && neighborLabel(mri_tmp,x,y,z,1,Right_Cerebral_White_Matter)) { left = sagittalNeighbors(mri_tmp,x,y,z,3,Left_Cerebral_White_Matter)> sagittalNeighbors(mri_tmp,x,y,z,3,Right_Cerebral_White_Matter); label = left ? Left_Cerebral_White_Matter : Right_Cerebral_White_Matter; MRIvox(mri_tmp, x, y, z) = label ; nchanged++ ; continue ; } default: break ; } } } } MRIcopy(mri_tmp, mri_out_labeled) ; total_changed += nchanged ; } while ((nchanged > 0) && (niter++ < 3)) ; MRIfree(&mri_tmp) ; printf("%d midline voxels changed.\n", total_changed) ; return(mri_out_labeled) ; }
int relabel_hypointensities_neighboring_gray(MRI *mri) { int x, y, z, label, changed, i ; MRI *mri_tmp = NULL ; for (changed = i = 0 ; i < 2 ; i++) { mri_tmp = MRIcopy(mri, mri_tmp) ; for (x = 0 ; x < mri->width ; x++) { for (y = 0 ; y < mri->height ; y++) { for (z = 0 ; z < mri->depth ; z++) { label = MRIgetVoxVal(mri_tmp, x, y, z, 0) ; if (label != WM_hypointensities) { continue ; } if (MRIneighbors(mri_tmp, x, y, z, Left_Cerebral_Cortex) > 0) { MRIsetVoxVal(mri, x, y, z, 0, Left_Cerebral_Cortex) ; changed++ ; } else if (MRIneighbors(mri_tmp,x,y,z,Right_Cerebral_Cortex) > 0) { MRIsetVoxVal(mri, x, y, z, 0, Right_Cerebral_Cortex) ; changed++ ; } } } } } printf("%d hypointense voxels neighboring cortex changed\n", changed) ; return(NO_ERROR) ; }
int main(int argc, char *argv[]) { char **av ; int ac, nargs, i ; MRI *mri_src, *mri_dst = NULL ; char *in_fname, *out_fname ; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mri_reduce.c,v 1.7 2011/03/02 00:04:24 nicks Exp $", "$Name: stable5 $"); if (nargs && argc - nargs == 1) exit (0); argc -= nargs; Progname = argv[0] ; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; ac = argc ; av = argv ; for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) { nargs = get_option(argc, argv) ; argc -= nargs ; argv += nargs ; } if (argc < 1) argc = 1 ; if (argc < 1) ErrorExit(ERROR_BADPARM, "%s: no input name specified", Progname) ; in_fname = argv[1] ; if (argc < 2) ErrorExit(ERROR_BADPARM, "%s: no output name specified", Progname) ; out_fname = argv[2] ; fprintf(stderr, "reading from %s...", in_fname) ; mri_src = MRIread(in_fname) ; i = 0 ; do { if (i) mri_src = MRIcopy(mri_dst, NULL) ; fprintf(stderr, "\nreducing by 2"); mri_dst = MRIallocSequence(mri_src->width/2, mri_src->height/2, mri_src->depth/2, MRI_FLOAT, mri_src->nframes); MRIreduce(mri_src, mri_dst) ; MRIfree(&mri_src) ; } while (++i < reductions) ; fprintf(stderr, "\nwriting to %s", out_fname) ; MRIwrite(mri_dst, out_fname) ; fprintf(stderr, "\n") ; exit(0) ; return(0) ; }
/***-------------------------------------------------------****/ int main(int argc, char *argv[]) { int nargs, index, ac, nvolumes; char **av ; MRI *mri_and = NULL, *mri ; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, vcid, "$Name: $"); if (nargs && argc - nargs == 1) exit (0); Progname = argv[0] ; argc -= nargs; ac = argc ; av = argv ; for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) { nargs = get_option(argc, argv) ; argc -= nargs ; argv += nargs ; } nvolumes = argc-2 ; if (nvolumes <= 0) usage_exit() ; printf("processing %d input files\n", nvolumes) ; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; for (index = 0 ; index < nvolumes ; index++) { char *fname = argv[index+1] ; printf("processing input volume %d of %d: %s\n", index+1, nvolumes, fname) ; mri = MRIread(fname) ; if (index == 0) mri_and = MRIcopy(mri, NULL) ; else MRIand(mri, mri_and, mri_and, 0) ; MRIfree(&mri) ; } printf("writing output to %s\n", argv[argc-1]) ; MRIwrite(mri_and, argv[argc-1]) ; exit(0); } /* end main() */
MRI * MRIremoveFilledBrightStuff(MRI *mri_T1, MRI *mri_labeled, MRI *mri_dst, int filled_label, float thresh) { int x, y, z, width, height, depth, nwhite, ntested, nchanged ; BUFTYPE val ; float intensity_thresh ; if (!mri_dst) { mri_dst = MRIcopy(mri_labeled, NULL) ; } width = mri_T1->width ; height = mri_T1->height ; depth = mri_T1->depth ; ntested = nchanged = 0 ; for (z = 0 ; z < depth ; z++) { for (y = 0 ; y < height ; y++) { for (x = 0 ; x < width ; x++) { val = MRIgetVoxVal(mri_T1, x, y, z, 0) ; ntested++ ; if (MRIgetVoxVal(mri_labeled, x, y, z, 0) == filled_label && val > thresh) { MRIsetVoxVal(mri_labeled, x, y, z, 0) ; nchanged++ ; } } } } if (Gdiag & DIAG_SHOW) { fprintf(stderr, " %8d voxels tested (%2.2f%%)\n", ntested, 100.0f*(float)ntested/ (float)(width*height*depth)); fprintf(stderr, " %8d voxels changed (%2.2f%%)\n", nchanged, 100.0f*(float)nchanged/ (float)(width*height*depth)); } return(mri_dst) ; }
/*---------------------------------------------------------------*/ MRI *fMRIsqrt(MRI *mri, MRI *mrisqrt) { int c,r,s,f; double val; if (mrisqrt == NULL) mrisqrt = MRIcopy(mri,NULL); if (mrisqrt == NULL) return(NULL); for (c=0; c < mri->width; c++) { for (r=0; r < mri->height; r++) { for (s=0; s < mri->depth; s++) { for (f=0; f < mri->nframes; f++) { val = MRIgetVoxVal(mri,c,r,s,f); if (val < 0.0) val = 0; else val = sqrt(val); MRIsetVoxVal(mri,c,r,s,f,val); } } } } return(mrisqrt); }
static int extract_labeled_image(MRI *mri_src, TRANSFORM *transform, int label, MRI *mri_dst) { MRI *mri_binarized, *mri_tmp ; mri_binarized = MRIclone(mri_src, NULL) ; nvoxels += MRIcopyLabel(mri_src, mri_binarized, label) ; MRIbinarize(mri_binarized, mri_binarized, 1, 0, UNIT_VOLUME) ; if (transform) mri_tmp = TransformCreateDensityMap(transform, mri_binarized, NULL) ; else mri_tmp = MRIcopy(mri_binarized,NULL) ; MRIadd(mri_tmp, mri_dst, mri_dst) ; MRIfree(&mri_binarized) ; MRIfree(&mri_tmp) ; return(NO_ERROR) ; }
MRI * MRIfloatToChar(MRI *mri_src, MRI *mri_dst) { int width, height, depth/*, x, y, z, out_val*/ ; /* float fmax, fmin ;*/ width = mri_src->width ; height = mri_src->height ; depth = mri_src->depth ; if (!mri_dst) mri_dst = MRIalloc(width, height, depth, MRI_UCHAR) ; #if 1 MRIcopy(mri_src, mri_dst) ; #else MRIvalRange(mri_src, &fmin, &fmax) ; for (z = 0 ; z < depth ; z++) { for (y = 0 ; y < height ; y++) { for (x = 0 ; x < width ; x++) {} } } #endif return(mri_dst) ; }
int main(int argc, char *argv[]) { double thresh ; MRI *mri, *mri_abs ; char *out_stem, fname[STRLEN] ; MRI_SEGMENTATION *mriseg ; int s ; LABEL *area ; Progname = argv[0] ; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; mri = MRIread(argv[1]) ; if (mri == NULL) ErrorExit(ERROR_NOFILE, "%s: could not load MRI from %s\n", Progname, argv[1]) ; if (use_abs) mri_abs = MRIabs(mri, NULL) ; else mri_abs = MRIcopy(mri, NULL) ; thresh = atof(argv[2]) ; out_stem = argv[3] ; mriseg = MRIsegment(mri, thresh, 1e10) ; MRIremoveSmallSegments(mriseg, size_thresh) ; printf("segmenting volume at threshold %2.1f yields %d segments\n", thresh, mriseg->nsegments) ; for (s = 0 ; s < mriseg->nsegments ; s++) { area = MRIsegmentToLabel(mriseg, mri_abs, s) ; sprintf(fname, "%s.%3.3d.label", out_stem, s) ; LabelWrite(area, fname) ; } return(0) ; }
/***-------------------------------------------------------****/ int main(int argc, char *argv[]) { int nargs, index, ac, nvolumes; char **av ; MRI *mri_or = NULL, *mri ; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, vcid, "$Name: $"); if (nargs && argc - nargs == 1) exit (0); Progname = argv[0] ; argc -= nargs; ac = argc ; av = argv ; for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) { nargs = get_option(argc, argv) ; argc -= nargs ; argv += nargs ; } nvolumes = argc-2 ; if (nvolumes <= 0) usage_exit() ; printf("processing %d input files\n", nvolumes) ; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; for (index = 0 ; index < nvolumes ; index++) { char *fname = argv[index+1] ; printf("processing input volume %d of %d: %s\n", index+1, nvolumes, fname) ; mri = MRIread(fname) ; if (index == 0){ mri_or = MRIcopy(mri, NULL) ; // if nvolumes == 1 binarize the volume! LZ: MRIbinarize(MRI *mri_src, MRI *mri_dst, float threshold, float low_val,float hi_val) if (nvolumes == 1) { if(use_orig_value) MRIorVal(mri, mri_or, mri_or, 0) ; else MRIor(mri, mri_or, mri_or, 0) ; } } else { if(use_orig_value) MRIorVal(mri, mri_or, mri_or, 0) ; else MRIor(mri, mri_or, mri_or, 0) ; } MRIfree(&mri) ; } printf("writing output to %s\n", argv[argc-1]) ; MRIwrite(mri_or, argv[argc-1]) ; exit(0); } /* end main() */
/*---------------------------------------------------------------*/ int main(int argc, char *argv[]) { int nargs, n, Ntp, nsearch, nsearch2=0; double fwhm = 0, nresels, voxelvolume, nvoxperresel, reselvolume; double car1mn, rar1mn,sar1mn,cfwhm,rfwhm,sfwhm, ftmp; double car2mn, rar2mn,sar2mn; double gmean, gstd, gmax; FILE *fp; sprintf(tmpstr, "S%sER%sRONT%sOR", "URF", "_F", "DO") ; setenv(tmpstr,"1",0); nargs = handle_version_option (argc, argv, vcid, "$Name: $"); if (nargs && argc - nargs == 1) exit (0); argc -= nargs; cmdline = argv2cmdline(argc,argv); uname(&uts); getcwd(cwd,2000); Progname = argv[0] ; argc --; argv++; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; if (argc == 0) usage_exit(); parse_commandline(argc, argv); check_options(); if (checkoptsonly) return(0); if (SynthSeed < 0) SynthSeed = PDFtodSeed(); if (debug) dump_options(stdout); // ------------- load or synthesize input --------------------- InVals = MRIreadType(inpath,InValsType); if(InVals == NULL) exit(1); if(SetTR){ printf("Setting TR to %g ms\n",TR); InVals->tr = TR; } if((nframes < 0 && synth) || !synth) nframes = InVals->nframes; if(nframes < nframesmin && !SmoothOnly && !sum2file) { printf("ERROR: nframes = %d, need at least %d\n", nframes,nframesmin); exit(1); } if (InVals->type != MRI_FLOAT) { mritmp = MRISeqchangeType(InVals, MRI_FLOAT, 0, 0, 0); MRIfree(&InVals); InVals = mritmp; } if(synth) { printf("Synthesizing %d frames, Seed = %d\n",nframes,SynthSeed); mritmp = MRIcloneBySpace(InVals,MRI_FLOAT,nframes); MRIfree(&InVals); MRIrandn(mritmp->width, mritmp->height, mritmp->depth, nframes, 0, 1, mritmp); InVals = mritmp; } voxelvolume = InVals->xsize * InVals->ysize * InVals->zsize ; printf("voxelvolume %g mm3\n",voxelvolume); if(DoSqr){ printf("Computing square of input\n"); MRIsquare(InVals,NULL,InVals); } // -------------------- handle masking ------------------------ if (maskpath) { printf("Loading mask %s\n",maskpath); mask = MRIread(maskpath); if(mask==NULL) exit(1); if(MRIdimMismatch(mask,InVals,0)){ printf("ERROR: dimension mismatch between mask and input\n"); exit(1); } MRIbinarize2(mask, mask, maskthresh, 0, 1); } if (automask) { RFglobalStats(InVals, NULL, &gmean, &gstd, &gmax); maskthresh = gmean * automaskthresh; printf("Computing mask, relative threshold = %g, gmean = %g, absthresh = %g\n", automaskthresh,gmean,maskthresh); mritmp = MRIframeMean(InVals,NULL); //MRIwrite(mritmp,"fmean.mgh"); mask = MRIbinarize2(mritmp, NULL, maskthresh, 0, 1); MRIfree(&mritmp); } if (mask) { if (maskinv) { printf("Inverting mask\n"); MRImaskInvert(mask,mask); } nsearch = MRInMask(mask); if (nsearch == 0) { printf("ERROR: no voxels found in mask\n"); exit(1); } // Erode the mask ----------------------------------------------- if (nerode > 0) { printf("Eroding mask %d times\n",nerode); for (n=0; n<nerode; n++) MRIerode(mask,mask); nsearch2 = MRInMask(mask); if (nsearch2 == 0) { printf("ERROR: no voxels found in mask after eroding\n"); exit(1); } printf("%d voxels in mask after eroding\n",nsearch2); } //---- Save mask ----- if (outmaskpath) MRIwrite(mask,outmaskpath); } else nsearch = InVals->width * InVals->height * InVals->depth; printf("Search region is %d voxels = %lf mm3\n",nsearch,nsearch*voxelvolume); if( (infwhm > 0 || infwhmc > 0 || infwhmr > 0 || infwhms > 0) && SmoothOnly) { if(SaveUnmasked) mritmp = NULL; else mritmp = mask; if(infwhm > 0) { printf("Smoothing input by fwhm=%lf, gstd=%lf\n",infwhm,ingstd); MRImaskedGaussianSmooth(InVals, mritmp, ingstd, InVals); } if(infwhmc > 0 || infwhmr > 0 || infwhms > 0) { printf("Smoothing input by fwhm=(%lf,%lf,%lf) gstd=(%lf,%lf,%lf)\n", infwhmc,infwhmr,infwhms,ingstdc,ingstdr,ingstds); MRIgaussianSmoothNI(InVals, ingstdc, ingstdr, ingstds, InVals); } printf("Saving to %s\n",outpath); MRIwrite(InVals,outpath); printf("SmoothOnly requested, so exiting now\n"); exit(0); } // Make a copy, if needed, prior to doing anything to data if(outpath) InValsCopy = MRIcopy(InVals,NULL); // Compute variance reduction factor ------------------- if(sum2file){ ftmp = MRIsum2All(InVals); fp = fopen(sum2file,"w"); if(fp == NULL){ printf("ERROR: opening %s\n",sum2file); exit(1); } printf("sum2all: %20.10lf\n",ftmp); printf("vrf: %20.10lf\n",1/ftmp); fprintf(fp,"%20.10lf\n",ftmp); exit(0); } //------------------------ Detrend ------------------ if(DetrendOrder >= 0) { Ntp = InVals->nframes; printf("Polynomial detrending, order = %d\n",DetrendOrder); X = MatrixAlloc(Ntp,DetrendOrder+1,MATRIX_REAL); for (n=0;n<Ntp;n++) X->rptr[n+1][1] = 1.0; ftmp = Ntp/2.0; if (DetrendOrder >= 1) for (n=0;n<Ntp;n++) X->rptr[n+1][2] = (n-ftmp)/ftmp; if (DetrendOrder >= 2) for (n=0;n<Ntp;n++) X->rptr[n+1][3] = pow((n-ftmp),2.0)/(ftmp*ftmp); } if(X){ printf("Detrending\n"); if (X->rows != InVals->nframes) { printf("ERROR: dimension mismatch between X and input\n"); exit(1); } mritmp = fMRIdetrend(InVals,X); if (mritmp == NULL) exit(1); MRIfree(&InVals); InVals = mritmp; } // ------------ Smooth Input BY infwhm ------------------------- if(infwhm > 0) { printf("Smoothing input by fwhm=%lf, gstd=%lf\n",infwhm,ingstd); MRImaskedGaussianSmooth(InVals, mask, ingstd, InVals); } // ------------ Smooth Input BY infwhm ------------------------- if(infwhmc > 0 || infwhmr > 0 || infwhms > 0) { printf("Smoothing input by fwhm=(%lf,%lf,%lf) gstd=(%lf,%lf,%lf)\n", infwhmc,infwhmr,infwhms,ingstdc,ingstdr,ingstds); MRIgaussianSmoothNI(InVals, ingstdc, ingstdr, ingstds, InVals); } // ------------ Smooth Input TO fwhm ------------------------- if (tofwhm > 0) { printf("Attempting to smooth to %g +/- %g mm fwhm (nitersmax=%d)\n", tofwhm,tofwhmtol,tofwhmnitersmax); mritmp = MRImaskedGaussianSmoothTo(InVals, mask, tofwhm, tofwhmtol, tofwhmnitersmax, &byfwhm, &tofwhmact, &tofwhmniters, InVals); if (mritmp == NULL) exit(1); printf("Smoothed by %g to %g in %d iterations\n", byfwhm,tofwhmact,tofwhmniters); if (tofwhmfile) { fp = fopen(tofwhmfile,"w"); if (!fp) { printf("ERROR: opening %s\n",tofwhmfile); exit(1); } fprintf(fp,"tofwhm %lf\n",tofwhm); fprintf(fp,"tofwhmtol %lf\n",tofwhmtol); fprintf(fp,"tofwhmact %lf\n",tofwhmact); fprintf(fp,"byfwhm %lf\n",byfwhm); fprintf(fp,"niters %d\n",tofwhmniters); fprintf(fp,"nitersmax %d\n",tofwhmnitersmax); fclose(fp); } } // ------ Save smoothed/detrended ------------------------------ if(outpath) { // This is a bit of a hack in order to be able to save undetrended // Operates on InValsCopy, which has not been modified (requires // smoothing twice, which is silly:). printf("Saving to %s\n",outpath); // Smoothed output will not be masked if (SaveDetrended && X) { mritmp = fMRIdetrend(InValsCopy,X); if (mritmp == NULL) exit(1); MRIfree(&InValsCopy); InValsCopy = mritmp; } if (SaveUnmasked) mritmp = NULL; else mritmp = mask; if(infwhm > 0) MRImaskedGaussianSmooth(InValsCopy, mritmp, ingstd, InValsCopy); if(infwhmc > 0 || infwhmr > 0 || infwhms > 0) MRIgaussianSmoothNI(InValsCopy, ingstdc, ingstdr, ingstds, InValsCopy); if(tofwhm > 0) { bygstd = byfwhm/sqrt(log(256.0)); MRImaskedGaussianSmooth(InValsCopy, mritmp, bygstd, InValsCopy); } MRIwrite(InValsCopy,outpath); MRIfree(&InValsCopy); } // ----------- Compute smoothness ----------------------------- printf("Computing spatial AR1 in volume.\n"); ar1 = fMRIspatialAR1(InVals, mask, NULL); if (ar1 == NULL) exit(1); fMRIspatialAR1Mean(ar1, mask, &car1mn, &rar1mn, &sar1mn); cfwhm = RFar1ToFWHM(car1mn, InVals->xsize); rfwhm = RFar1ToFWHM(rar1mn, InVals->ysize); sfwhm = RFar1ToFWHM(sar1mn, InVals->zsize); fwhm = sqrt((cfwhm*cfwhm + rfwhm*rfwhm + sfwhm*sfwhm)/3.0); printf("ar1mn = (%lf,%lf,%lf)\n",car1mn,rar1mn,sar1mn); printf("colfwhm = %lf\n",cfwhm); printf("rowfwhm = %lf\n",rfwhm); printf("slicefwhm = %lf\n",sfwhm); printf("outfwhm = %lf\n",fwhm); reselvolume = cfwhm*rfwhm*sfwhm; nvoxperresel = reselvolume/voxelvolume; nresels = voxelvolume*nsearch/reselvolume; printf("reselvolume %lf\n",reselvolume); printf("nresels %lf\n",nresels); printf("nvoxperresel %lf\n",nvoxperresel); if(DoAR2){ printf("Computing spatial AR2 in volume.\n"); fMRIspatialAR2Mean(InVals, mask, &car2mn, &rar2mn, &sar2mn); printf("ar2mn = (%lf,%lf,%lf)\n",car2mn,rar2mn,sar2mn); } if(ar1path) MRIwrite(ar1,ar1path); fflush(stdout); // ---------- Save summary file --------------------- if(sumfile) { fp = fopen(sumfile,"w"); if (fp == NULL) { printf("ERROR: opening %s\n",sumfile); exit(1); } dump_options(fp); fprintf(fp,"nsearch2 %d\n",nsearch2); fprintf(fp,"searchspace_vox %d\n",nsearch); fprintf(fp,"searchspace_mm3 %lf\n",nsearch*voxelvolume); fprintf(fp,"voxelvolume_mm3 %g\n",voxelvolume); fprintf(fp,"voxelsize_mm %g %g %g\n",InVals->xsize,InVals->ysize,InVals->zsize); fprintf(fp,"ar1mn %lf %lf %lf\n",car1mn,rar1mn,sar1mn); fprintf(fp,"colfwhm_mm %lf\n",cfwhm); fprintf(fp,"rowfwhm_mm %lf\n",rfwhm); fprintf(fp,"slicefwhm_mm %lf\n",sfwhm); fprintf(fp,"outfwhm_mm %lf\n",fwhm); fprintf(fp,"reselvolume_mm3 %lf\n",reselvolume); fprintf(fp,"nresels %lf\n",nresels); fprintf(fp,"nvox_per_resel %lf\n",nvoxperresel); fclose(fp); } if(datfile) { fp = fopen(datfile,"w"); if(fp == NULL) { printf("ERROR: opening %s\n",datfile); exit(1); } fprintf(fp,"%lf\n",fwhm); fclose(fp); } printf("mri_fwhm done\n"); return 0; }
/*------------------------------------------------------------------------*/ MRI *MRImaskedGaussianSmoothTo(MRI *invol, MRI *mask, double ToFWHM, double tol, int nitersmax, double *pByFWHM, double *pToFWHMActual, int *niters, MRI *outvol) { double SrcFWHM, ByGStd; MRI *volsm; double ya, yb, yc, xa, xb, xc, s1, s2; double xn,yn; double C, R, err; int nth; C = (3.0-sqrt(5.0))/2.0; // golden mean R = 1-C; *niters = 0; SrcFWHM = EvalFWHM(invol, mask); if (SrcFWHM > ToFWHM) { printf("ERROR: MRImaskedGaussianSmoothTo(): the inherent smoothness\n"); printf("of the data set is about fwhm=%gmm, which is more than the\n",SrcFWHM); printf("amount that you want to smooth it to (%gmm). It is impossible\n",ToFWHM); printf("to 'unsmooth' the data.\n"); return(NULL); } xa = 0; ya = SrcFWHM; printf("Unsmoothed actual fwhm is %g\n",ya); // Check whether we are close enough already if (fabs(SrcFWHM-ToFWHM) < tol) { *pByFWHM = 0.0; *pToFWHMActual = SrcFWHM; outvol = MRIcopy(invol,outvol); return(outvol); } volsm = MRIcopy(invol,NULL); // allocate // First point in the bracket // Second point in the bracket (*niters)++; xb = sqrt(ToFWHM*ToFWHM - SrcFWHM*SrcFWHM); // power law ByGStd = xb/sqrt(log(256.0)); printf("Trying smoothing by fwhm %g ",xb); fflush(stdout); MRImaskedGaussianSmooth(invol, mask, ByGStd, volsm); yb = EvalFWHM(volsm, mask); printf("results in actual fwhm of %g\n",yb); // Check whether we are close enough now if (fabs(yb-ToFWHM) < tol) { *pByFWHM = xb; *pToFWHMActual = yb; outvol = MRIcopy(volsm,outvol); MRIfree(&volsm); return(outvol); } // Third point in the bracket. Not sure how to choose this point, // it needs to be far enough to bracket the min, but too far // and we end up doing to many evaluations. (*niters)++; xc = xb + (xb - xa); // ByGStd = xc/sqrt(log(256.0)); printf("Trying smoothing by fwhm %g ",xc); fflush(stdout); MRImaskedGaussianSmooth(invol, mask, ByGStd, volsm); yc = EvalFWHM(volsm, mask); printf("results in actual fwhm of %g\n",yc); // Check whether we are close enough now if (fabs(yc-ToFWHM) < tol) { *pByFWHM = xc; *pToFWHMActual = yc; outvol = MRIcopy(volsm,outvol); MRIfree(&volsm); return(outvol); } if (yc < ToFWHM) { // Did not step far enough out printf("ERROR: did not step far enough out\n"); return(NULL); } // ok, we've brackated the min, now chase it down like a scared rabbit // using a golden section search (see numerical recipes in C). printf("Beginning golden section search.\n"); printf("Expecting roughly %d iterations will be needed.\n", (int)ceil(log(tol/(xc-xa))/log(R))); nth = 0; getybest(xa, ya, xb, yb, xc, yc, pByFWHM, pToFWHMActual, ToFWHM); err = fabs(*pToFWHMActual-ToFWHM); while ( err > tol) { if (nth > nitersmax) { printf("ERROR: searched timed out at niters=%d\n",nth); MRIfree(&volsm); return(NULL); } printf("n=%d by=(%4.2lf,%4.2lf,%4.2lf) to=(%4.2lf,%4.2lf,%4.2lf) err=%g\n", nth, xa, xb, xc, ya, yb, yc, err); fflush(stdout); s1 = xb - xa; s2 = xc - xb; if (s1 > s2) { // s1 is bigger xn = xa + R*s1; printf(" Trying smoothing by fwhm %g ",xn); fflush(stdout); ByGStd = xn/sqrt(log(256.0)); MRImaskedGaussianSmooth(invol, mask, ByGStd, volsm); yn = EvalFWHM(volsm, mask); printf("results in actual fwhm of %g\n",yn); if (fabs(yn-ToFWHM) < fabs(ToFWHM-yb)) { xc = xb; yc = yb; xb = xn; yb = yn; } else { xa = xn; //a replaced by new ya = yn; // b and c stay the same } } else { // s2 is bigger xn = xb + C*s2; ByGStd = xn/sqrt(log(256.0)); printf(" Trying smoothing by fwhm %g ",xn); fflush(stdout); MRImaskedGaussianSmooth(invol, mask, ByGStd, volsm); yn = EvalFWHM(volsm, mask); printf("results in actual fwhm of %g\n",yn); if (fabs(yn-ToFWHM) < fabs(ToFWHM-yb)) { xa = xb; //a replaced by b ya = yb; xb = xn; //b replace by new yb = yn; // c stays the same } else { xc = xn; //c replaced by new yc = yn; // a and b stay the same } } getybest(xa, ya, xb, yb, xc, yc, pByFWHM, pToFWHMActual, ToFWHM); err = fabs(*pToFWHMActual-ToFWHM); nth++; (*niters)++; } printf("niters=%3d by=%6.4lf to=%6.4lf targ=%6.4lf err=%g\n", nth, *pByFWHM, *pToFWHMActual, ToFWHM, err); outvol = MRIcopy(volsm,outvol); MRIfree(&volsm); return(outvol); }
static MRI * MRIcomputeSurfaceDistanceIntensities(MRI_SURFACE *mris, MRI *mri_ribbon, MRI *mri_aparc, MRI *mri, MRI *mri_aseg, int whalf) { MRI *mri_features, *mri_binary, *mri_white_dist, *mri_pial_dist ; int vno, ngm, outside_of_ribbon, label0, label, ohemi_label, xi, yi, zi, xk, yk, zk, x0, y0, z0, hemi_label, assignable ; double xv, yv, zv, step_size, dist, thickness, wdist, pdist, snx, sny, snz, nx, ny, nz, xl, yl, zl, x, y, z, dot, angle ; VERTEX *v ; mri_features = MRIallocSequence(mris->nvertices, 1, 1, MRI_FLOAT, 1) ; // one samples inwards, one in ribbon, and one outside MRIcopyHeader(mri, mri_features) ; mri_binary = MRIcopy(mri_ribbon, NULL) ; mri_binary = MRIbinarize(mri_ribbon, NULL, 1, 0, 1) ; mri_pial_dist = MRIdistanceTransform(mri_binary, NULL, 1, max_pial_dist+1, DTRANS_MODE_SIGNED,NULL); if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) MRIwrite(mri_pial_dist, "pd.mgz") ; MRIclear(mri_binary) ; MRIcopyLabel(mri_ribbon, mri_binary, Left_Cerebral_White_Matter) ; MRIcopyLabel(mri_ribbon, mri_binary, Right_Cerebral_White_Matter) ; MRIbinarize(mri_binary, mri_binary, 1, 0, 1) ; mri_white_dist = MRIdistanceTransform(mri_binary, NULL, 1, max_white_dist+1, DTRANS_MODE_SIGNED,NULL); if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) MRIwrite(mri_white_dist, "wd.mgz") ; if (mris->hemisphere == LEFT_HEMISPHERE) { ohemi_label = Right_Cerebral_Cortex ; hemi_label = Left_Cerebral_Cortex ; } else { hemi_label = Right_Cerebral_Cortex ; ohemi_label = Left_Cerebral_Cortex ; } step_size = mri->xsize/2 ; for (vno = 0 ; vno < mris->nvertices ; vno++) { v = &mris->vertices[vno] ; if (vno == Gdiag_no) DiagBreak() ; if (v->ripflag) continue ; // not cortex nx = v->pialx - v->whitex ; ny = v->pialy - v->whitey ; nz = v->pialz - v->whitez ; thickness = sqrt(nx*nx + ny*ny + nz*nz) ; if (FZERO(thickness)) continue ; // no cortex here x = (v->pialx + v->whitex)/2 ; y = (v->pialy + v->whitey)/2 ; z = (v->pialz + v->whitez)/2 ; // halfway between white and pial is x0 MRISsurfaceRASToVoxelCached(mris, mri_aseg, x, y, z, &xl, &yl, &zl) ; x0 = nint(xl); y0 = nint(yl) ; z0 = nint(zl) ; label0 = MRIgetVoxVal(mri_aparc, x0, y0, z0,0) ; // compute surface normal in voxel coords MRISsurfaceRASToVoxelCached(mris, mri_aseg, x+v->nx, y+v->ny, z+v->nz, &snx, &sny, &snz) ; snx -= xl ; sny -= yl ; snz -= zl ; for (ngm = 0, xk = -whalf ; xk <= whalf ; xk++) { xi = mri_aseg->xi[x0+xk] ; for (yk = -whalf ; yk <= whalf ; yk++) { yi = mri_aseg->yi[y0+yk] ; for (zk = -whalf ; zk <= whalf ; zk++) { zi = mri_aseg->zi[z0+zk] ; label = MRIgetVoxVal(mri_aseg, xi, yi, zi,0) ; if (xi == Gx && yi == Gy && zi == Gz) DiagBreak() ; if (label != hemi_label) continue ; label = MRIgetVoxVal(mri_aparc, xi, yi, zi,0) ; if (label && label != label0) // if outside the ribbon it won't be assigned to a parcel continue ; // constrain it to be in the same cortical parcel // search along vector connecting x0 to this point to make sure it is we don't perforate wm or leave and re-enter cortex nx = xi-x0 ; ny = yi-y0 ; nz = zi-z0 ; thickness = sqrt(nx*nx + ny*ny + nz*nz) ; assignable = 1 ; // assume this point should be counted if (thickness > 0) { nx /= thickness ; ny /= thickness ; nz /= thickness ; dot = nx*snx + ny*sny + nz*snz ; angle = acos(dot) ; if (FABS(angle) > angle_threshold) assignable = 0 ; outside_of_ribbon = 0 ; for (dist = 0 ; assignable && dist <= thickness ; dist += step_size) { xv = x0+nx*dist ; yv = y0+ny*dist ; zv = z0+nz*dist ; if (nint(xv) == Gx && nint(yv) == Gy && nint(zv) == Gz) DiagBreak() ; MRIsampleVolume(mri_pial_dist, xv, yv, zv, &pdist) ; MRIsampleVolume(mri_white_dist, xv, yv, zv, &wdist) ; label = MRIgetVoxVal(mri_aseg, xi, yi, zi,0) ; if (SKIP_LABEL(label) || label == ohemi_label) assignable = 0 ; if (wdist < 0) // entered wm - not assignable assignable = 0 ; else { if (pdist > 0) // outside pial surface outside_of_ribbon = 1 ; else { if (outside_of_ribbon) // left ribbon and reentered assignable = 0 ; } } } } // close of thickness > 0 if (assignable) ngm++ ; else DiagBreak() ; } } } MRIsetVoxVal(mri_features, vno, 0, 0, 0, ngm) ; } MRIfree(&mri_white_dist) ; MRIfree(&mri_pial_dist) ; MRIfree(&mri_binary) ; return(mri_features) ; }
static MRI * MRIcomputeSurfaceDistanceProbabilities(MRI_SURFACE *mris, MRI *mri_ribbon, MRI *mri, MRI *mri_aseg) { MRI *mri_features, *mri_binary, *mri_white_dist, *mri_pial_dist, *mri_mask ; int nwhite_bins, npial_bins, x, y, z, label, i ; HISTOGRAM2D *hw, *hp ; float pdist, wdist, val ; double wval, pval ; mri_features = MRIallocSequence(mri->width, mri->height, mri->depth, MRI_FLOAT, 2) ; MRIcopyHeader(mri, mri_features) ; mri_binary = MRIcopy(mri_ribbon, NULL) ; mri_binary = MRIbinarize(mri_ribbon, NULL, 1, 0, 1) ; mri_pial_dist = MRIdistanceTransform(mri_binary, NULL, 1, max_pial_dist+1, DTRANS_MODE_SIGNED,NULL); if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) MRIwrite(mri_pial_dist, "pd.mgz") ; MRIclear(mri_binary) ; MRIcopyLabel(mri_ribbon, mri_binary, Left_Cerebral_White_Matter) ; MRIcopyLabel(mri_ribbon, mri_binary, Right_Cerebral_White_Matter) ; MRIbinarize(mri_binary, mri_binary, 1, 0, 1) ; mri_white_dist = MRIdistanceTransform(mri_binary, NULL, 1, max_white_dist+1, DTRANS_MODE_SIGNED,NULL); if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) MRIwrite(mri_white_dist, "wd.mgz") ; nwhite_bins = ceil((max_white_dist - min_white_dist) / white_bin_size)+1 ; npial_bins = ceil((max_pial_dist - min_pial_dist) / pial_bin_size)+1 ; hw = HISTO2Dalloc(NBINS, nwhite_bins) ; hp = HISTO2Dalloc(NBINS, npial_bins) ; HISTO2Dinit(hw, NBINS, nwhite_bins, 0, NBINS-1, min_white_dist, max_white_dist) ; HISTO2Dinit(hp, NBINS, npial_bins, 0, NBINS-1, min_pial_dist, max_pial_dist) ; for (x = 0 ; x < mri->width ; x++) for (y = 0 ; y < mri->height ; y++) for (z = 0 ; z < mri->depth ; z++) { label = MRIgetVoxVal(mri_aseg, x, y, z, 0) ; if (IS_CEREBELLUM(label) || IS_VENTRICLE(label) || label == Brain_Stem || IS_CC(label)) continue ; pdist = MRIgetVoxVal(mri_pial_dist, x, y, z, 0) ; wdist = MRIgetVoxVal(mri_pial_dist, x, y, z, 0) ; val = MRIgetVoxVal(mri, x, y, z, 0) ; if (pdist >= min_pial_dist && pdist <= max_pial_dist) HISTO2DaddSample(hp, val, pdist, 0, 0, 0, 0) ; if (wdist >= min_white_dist && wdist <= max_white_dist) HISTO2DaddSample(hw, val, wdist, 0, 0, 0, 0) ; } HISTO2DmakePDF(hp, hp) ; HISTO2DmakePDF(hw, hw) ; for (x = 0 ; x < mri->width ; x++) for (y = 0 ; y < mri->height ; y++) for (z = 0 ; z < mri->depth ; z++) { label = MRIgetVoxVal(mri_aseg, x, y, z, 0) ; if (IS_CEREBELLUM(label) || IS_VENTRICLE(label) || label == Brain_Stem || IS_CC(label)) continue ; pdist = MRIgetVoxVal(mri_pial_dist, x, y, z, 0) ; wdist = MRIgetVoxVal(mri_pial_dist, x, y, z, 0) ; val = MRIgetVoxVal(mri, x, y, z, 0) ; wval = HISTO2DgetCount(hw, val, wdist); if (DZERO(wval) == 0) MRIsetVoxVal(mri_features, x, y, z, 1, -log10(wval)) ; pval = HISTO2DgetCount(hp, val, pdist); if (DZERO(pval) == 0) MRIsetVoxVal(mri_features, x, y, z, 0, -log10(pval)) ; } MRIclear(mri_binary) ; MRIbinarize(mri_ribbon, mri_binary, 1, 0, 1) ; mri_mask = MRIcopy(mri_binary, NULL) ; for (i = 0 ; i < close_order ; i++) { MRIdilate(mri_binary, mri_mask) ; MRIcopy(mri_mask, mri_binary) ; } for (i = 0 ; i < close_order ; i++) { MRIerode(mri_binary, mri_mask) ; MRIcopy(mri_mask, mri_binary) ; } MRIwrite(mri_mask, "m.mgz") ; MRImask(mri_features, mri_mask, mri_features, 0, 0) ; HISTO2Dfree(&hw) ; HISTO2Dfree(&hp) ; MRIfree(&mri_white_dist) ; MRIfree(&mri_pial_dist) ; MRIfree(&mri_binary) ; return(mri_features) ; }
int main(int argc, char *argv[]) { char **av, *surf_name, *out_prefix, *fname; int nargs, ac, i, nsubjects, total, index; double scalar, std, tmp, maxV, minV, meanV; MRI *SrcVals[2], *AvgVals; MRI_SURFACE *BaseSurf; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mris_diff_on_surface.c,v 1.3 2011/03/02 00:04:55 nicks Exp $", "$Name: $"); if (nargs && argc - nargs == 1) exit (0); argc -= nargs; Progname = argv[0] ; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; ac = argc ; av = argv ; for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) { nargs = get_option(argc, argv) ; argc -= nargs ; argv += nargs ; } /* command line: <surf> <datafile 1> <datafile 2> <output prefix> */ if (argc != 5) usage_exit(); surf_name = argv[1]; out_prefix = argv[argc - 1]; if (srctypestring == NULL || trgtypestring == NULL) { printf("Please specify both input and output data type!\n"); usage_exit(); } printf("Reading underlying surface file\n"); BaseSurf = MRISread(surf_name); if (!BaseSurf) ErrorExit(ERROR_NOFILE, "%s:could not read surface %s", Progname, surf_name); printf("Base surface has %d vertices\n", BaseSurf->nvertices); /* Read in the first data file */ fname = argv[2]; /* only two data types are supported */ if (!strcmp(srctypestring,"curv")) { /* curvature file */ if (MRISreadCurvatureFile(BaseSurf, fname) != 0) { printf("ERROR: reading curvature file\n"); exit(1); } SrcVals[0] = MRIcopyMRIS(NULL, BaseSurf, 0, "curv"); } else if (!strcmp(srctypestring,"paint") || !strcmp(srctypestring,"w")) { MRISreadValues(BaseSurf,fname); SrcVals[0] = MRIcopyMRIS(NULL, BaseSurf, 0, "val"); } else { printf("ERROR: unknown data file format\n"); exit(1); } if (SrcVals[0] == NULL) { fprintf(stderr, "ERROR loading data values from %s\n", fname); } /* Read in the second data file */ fname = argv[3]; /* only two data types are supported */ if (!strcmp(srctypestring,"curv")) { /* curvature file */ if (MRISreadCurvatureFile(BaseSurf, fname) != 0) { printf("ERROR: reading curvature file\n"); exit(1); } SrcVals[1] = MRIcopyMRIS(NULL, BaseSurf, 0, "curv"); } else if (!strcmp(srctypestring,"paint") || !strcmp(srctypestring,"w")) { MRISreadValues(BaseSurf,fname); SrcVals[1] = MRIcopyMRIS(NULL, BaseSurf, 0, "val"); } else { printf("ERROR: unknown data file format\n"); exit(1); } if (SrcVals[1] == NULL) { fprintf(stderr, "ERROR loading data values from %s\n", fname); } if (debugflag) { for (i=0; i < 2; i++) { printf("Data%d at vertex %d has value %g\n",i, debugvtx, MRIFseq_vox(SrcVals[i], debugvtx, 0, 0, 0)); } } #if 0 AvgVals = MRIclone(SrcVals[0], NULL); if (negflag) /* Add the two data sets */ AvgVals = MRIadd(SrcVals[0], SrcVals[1], AvgVals); else /* Data1 - Data2 */ AvgVals = MRIsubtract(SrcVals[0], SrcVals[1], AvgVals); #endif AvgVals = MRIcopy(SrcVals[0], NULL); if (negflag) { for (index=0; index < BaseSurf->nvertices; index++) { MRIFseq_vox(AvgVals, index, 0, 0, 0) = MRIFseq_vox(SrcVals[0], index, 0, 0, 0) + MRIFseq_vox(SrcVals[1], index, 0, 0, 0); } } else { for (index=0; index < BaseSurf->nvertices; index++) { MRIFseq_vox(AvgVals, index, 0, 0, 0) = MRIFseq_vox(SrcVals[0], index, 0, 0, 0) - MRIFseq_vox(SrcVals[1], index, 0, 0, 0); } } maxV = -1000.0; minV = 1000.0; meanV=0.0; for (index=0; index < BaseSurf->nvertices; index++) { scalar = MRIFseq_vox(AvgVals, index, 0, 0, 0); if (maxV < scalar) maxV = scalar; if (minV > scalar) minV = scalar; meanV += scalar; } meanV /= BaseSurf->nvertices; printf("Output max = %g, min = %g, mean = %g\n", maxV, minV, meanV); if (debugflag) { printf("Output at vertex %d has value %g\n", debugvtx, MRIFseq_vox(AvgVals, debugvtx, 0, 0, 0)); } if (pathflag) sprintf(fname, "%s", out_prefix); else { if (negflag) sprintf(fname, "%s.sum.w", out_prefix) ; else sprintf(fname, "%s.diff.w", out_prefix) ; } if (!strcmp(trgtypestring,"paint") || !strcmp(trgtypestring,"w")) { /* This function will remove a zero-valued vertices */ /* Make sense, since default value is considered as zero */ /* But it will confuse the processing with matlab! */ /* So I copy the data to the curv field to force every value is * written out */ /* MRIScopyMRI(BaseSurf, AvgVals, framesave, "val");*/ /* MRISwriteValues(BaseSurf,fname); */ MRIScopyMRI(BaseSurf, AvgVals, framesave, "curv"); MRISwriteCurvatureToWFile(BaseSurf,fname); } else { fprintf(stderr, "ERROR unknown output file format.\n"); } /* Free memories */ MRISfree(&BaseSurf); MRIfree(&AvgVals); for (i=0; i < 2; i++) { MRIfree(&SrcVals[i]); } return 0; }
/*------------------------------------------------------*/ MRI *afniRead(const char *fname, int read_volume) { FILE *fp; char header_fname[STRLEN]; char *c; MRI *mri, *header; int big_endian_flag; long brik_file_length; long nvoxels; int bytes_per_voxel; int i, j, k; int swap_flag; AF af; float scaling = 1.; void *pmem = 0; float *pf; short *ps; unsigned char *pc; float det; float xfov, yfov, zfov; float fMin = 0.; float fMax = 0.; float flMin = 0.; float flMax = 0.; int initialized = 0; int frame; int bytes; strcpy(header_fname, fname); c = strrchr(header_fname, '.'); if (c == NULL) { errno = 0; ErrorReturn(NULL, (ERROR_BADPARM, "afniRead(): bad file name %s", fname)); } if (strcmp(c, ".BRIK") != 0) { errno = 0; ErrorReturn(NULL, (ERROR_BADPARM, "afniRead(): bad file name %s", fname)); } sprintf(c, ".HEAD"); if ((fp = fopen(header_fname, "r")) == NULL) { errno = 0; ErrorReturn(NULL, (ERROR_BADFILE, "afniRead(): error opening file %s", header_fname)); } // initialize AFNI structure AFinit(&af); // read header file if (!readAFNIHeader(fp, &af)) return (NULL); printAFNIHeader(&af); // well, we don't have time if (af.numtypes != 1) // should be the same as af.dataset_rank[1] = subbricks { errno = 0; // ErrorReturn(NULL, (ERROR_UNSUPPORTED, "afniRead(): nframes = %d (only 1 frame supported)", af.numtypes)); printf("INFO: number of frames dataset_rank[1] = %d : numtypes = %d \n", af.dataset_rank[1], af.numtypes); } // byteorder_string : required field if (strcmp(af.byteorder_string, "MSB_FIRST") == 0) big_endian_flag = 1; else if (strcmp(af.byteorder_string, "LSB_FIRST") == 0) big_endian_flag = 0; else { errno = 0; ErrorReturn(NULL, (ERROR_BADPARM, "read_afni_header(): unrecognized byte order string %s", af.byteorder_string)); } // brick_types : required field if (af.brick_types[0] == 2 // int || af.brick_types[0] > 3 )// 4 = double, 5 = complex, 6 = rgb { errno = 0; ErrorReturn(NULL, (ERROR_BADPARM, "afniRead(): unsupported data type %d, Must be 0 (byte), 1(short), or 3(float)", af.brick_types[0])); } ////////////////////////////////////////////////////////////////////////////////// // now we allocate space for MRI // dataset_dimensions : required field header = MRIallocHeader(af.dataset_dimensions[0], af.dataset_dimensions[1], af.dataset_dimensions[2], MRI_UCHAR, af.dataset_rank[1] ); // set number of frames header->nframes = af.dataset_rank[1]; // direction cosines (use orient_specific) // orient_specific : required field header->x_r = afni_orientations[af.orient_specific[0]][0]; header->x_a = afni_orientations[af.orient_specific[0]][1]; header->x_s = afni_orientations[af.orient_specific[0]][2]; header->y_r = afni_orientations[af.orient_specific[1]][0]; header->y_a = afni_orientations[af.orient_specific[1]][1]; header->y_s = afni_orientations[af.orient_specific[1]][2]; header->z_r = afni_orientations[af.orient_specific[2]][0]; header->z_a = afni_orientations[af.orient_specific[2]][1]; header->z_s = afni_orientations[af.orient_specific[2]][2]; /* --- quick determinant check --- */ det = + header->x_r * (header->y_a * header->z_s - header->z_a * header->y_s) - header->x_a * (header->y_r * header->z_s - header->z_r * header->y_s) + header->x_s * (header->y_r * header->z_a - header->z_r * header->y_a); if (det == 0) { MRIfree(&header); errno = 0; ErrorReturn(NULL, (ERROR_BADPARM, "read_afni_header(): error in orientations %d, %d, %d (direction cosine matrix has determinant zero)", af.orient_specific[0], af.orient_specific[1], af.orient_specific[2])); } // sizes use delta // delta : required field header->xsize = af.delta[0]; header->ysize = af.delta[1]; header->zsize = af.delta[2]; // uses origin // origin : required field header->c_r = header->x_r * (header->xsize * (header->width-1.0)/2.0 + af.origin[0]) + header->y_r * (header->ysize * (header->height-1.0)/2.0 + af.origin[1]) + header->z_r * (header->zsize * (header->depth-1.0)/2.0 + af.origin[2]); header->c_a = header->x_a * (header->xsize * (header->width-1.0)/2.0 + af.origin[0]) + header->y_a * (header->ysize * (header->height-1.0)/2.0 + af.origin[1]) + header->z_a * (header->zsize * (header->depth-1.0)/2.0 + af.origin[2]); header->c_s = header->x_s * (header->xsize * (header->width-1.0)/2.0 + af.origin[0]) + header->y_s * (header->ysize * (header->height-1.0)/2.0 + af.origin[1]) + header->z_s * (header->zsize * (header->depth-1.0)/2.0 + af.origin[2]); header->ras_good_flag = 1; if (header->xsize < 0) header->xsize = -header->xsize; if (header->ysize < 0) header->ysize = -header->ysize; if (header->zsize < 0) header->zsize = -header->zsize; header->imnr0 = 1; header->imnr1 = header->depth; header->ps = header->xsize; header->thick = header->zsize; header->xend = (header->width / 2.0) * header->xsize; header->xstart = -header->xend; header->yend = (header->height / 2.0) * header->ysize; header->ystart = -header->yend; header->zend = (header->depth / 2.0) * header->zsize; header->zstart = -header->zend; xfov = header->xend - header->xstart; yfov = header->yend - header->ystart; zfov = header->zend - header->zstart; header->fov = ( xfov > yfov ? (xfov > zfov ? xfov : zfov ) : (yfov > zfov ? yfov : zfov ) ); #if (BYTE_ORDER==LITTLE_ENDIAN) //#ifdef Linux swap_flag = big_endian_flag; #else swap_flag = !big_endian_flag; #endif if ((fp = fopen(fname, "r")) == NULL) { MRIfree(&header); errno = 0; ErrorReturn(NULL, (ERROR_BADFILE, "afniRead(): error opening file %s", header_fname)); } fseek(fp, 0, SEEK_END); brik_file_length = ftell(fp); fseek(fp, 0, SEEK_SET); // number of voxels consecutive nvoxels = header->width * header->height * header->depth * header->nframes; if (brik_file_length % nvoxels) { fclose(fp); MRIfree(&header); errno = 0; ErrorReturn(NULL, (ERROR_BADFILE, "afniRead(): BRIK file length (%d) is not divisible by the number of voxels (%d)", brik_file_length, nvoxels)); } // bytes_per_voxel = brik_file_length / nvoxels; // this assumes one frame bytes_per_voxel = af.brick_types[0] + 1; // 0(byte)-> 1, 1(short) -> 2, 3(float)->4 bytes = header->width*header->height*header->depth*bytes_per_voxel; // this check is for nframes = 1 case which is the one we are supporting if (bytes_per_voxel != brik_file_length/nvoxels) { fclose(fp); MRIfree(&header); errno = 0; ErrorReturn(NULL, (ERROR_UNSUPPORTED, "afniRead(): type info stored in header does not agree with the file size: %d != %d/%d", bytes_per_voxel, brik_file_length/nvoxels)); } // if brick_float_facs != 0 then we scale values to be float if (af.numfacs != 0 && af.brick_float_facs[0] != 0.) { header->type = MRI_FLOAT; scaling = af.brick_float_facs[0]; } else { if (bytes_per_voxel == 1) header->type = MRI_UCHAR; else if (bytes_per_voxel == 2) header->type = MRI_SHORT; else if (bytes_per_voxel == 4) header->type = MRI_FLOAT; else { fclose(fp); MRIfree(&header); errno = 0; ErrorReturn(NULL, (ERROR_UNSUPPORTED, "afniRead(): don't know what to do with %d bytes per voxel", bytes_per_voxel)); } } /////////////////////////////////////////////////////////////////////// if (read_volume) { // mri = MRIalloc(header->width, header->height, header->depth, header->type); mri = MRIallocSequence(header->width, header->height, header->depth, header->type, header->nframes) ; MRIcopyHeader(header, mri); for (frame = 0; frame < header->nframes; ++frame) { initialized = 0; for (k = 0;k < mri->depth;k++) { for (j = 0;j < mri->height;j++) { if (af.brick_float_facs[frame]) scaling = af.brick_float_facs[frame]; else scaling = 1.; { pmem = (void *) malloc(bytes_per_voxel*mri->width); if (pmem) { if (fread(pmem, bytes_per_voxel, mri->width, fp) != mri->width) { fclose(fp); MRIfree(&header); errno = 0; ErrorReturn(NULL, (ERROR_BADFILE, "afniRead(): error reading from file %s", fname)); } // swap bytes if (swap_flag) { if (bytes_per_voxel == 2) // short { swab(pmem, pmem, mri->width * 2); } else if (bytes_per_voxel == 4) // float { pf = (float *) pmem; for (i = 0;i < mri->width;i++, pf++) *pf = swapFloat(*pf); } } // now scaling if (bytes_per_voxel == 1) // byte { pc = (unsigned char *) pmem; for (i=0; i < mri->width; i++) { if (scaling == 1.) MRIseq_vox(mri, i, j, k, frame) = *pc; else MRIFseq_vox(mri, i, j, k, frame) = ((float) (*pc))*scaling; ++pc; } findMinMaxByte((unsigned char *) pmem, mri->width, &flMin, &flMax); } if (bytes_per_voxel == 2) // short { ps = (short *) pmem; for (i=0; i < mri->width; i++) { // if (*ps != 0) // printf("%d ", *ps); if (scaling == 1.) MRISseq_vox(mri, i, j, k, frame) = *ps; else MRIFseq_vox(mri, i, j, k, frame) = ((float) (*ps))*scaling; ++ps; } findMinMaxShort((short *) pmem, mri->width, &flMin, &flMax); } else if (bytes_per_voxel == 4) // float { pf = (float *) pmem; for (i=0; i < mri->width; i++) { MRIFseq_vox(mri, i, j, k, frame) = (*pf)*scaling; ++pf; } findMinMaxFloat((float *) pmem, mri->width, &flMin, &flMax); } free(pmem); // if (initialized == 0) { fMin = flMin; fMax = flMax; initialized = 1; } else { if (flMin < fMin) fMin = flMin; if (flMax > fMax) fMax = flMax; // printf("\n fmin =%f, fmax = %f, local min = %f, max = %f\n", fMin, fMax, flMin, flMax); } } else { fclose(fp); MRIfree(&header); errno = 0; ErrorReturn(NULL, (ERROR_BADFILE, "afniRead(): could not allocate memory for reading %s", fname)); } } } // height } // depth // valid only for nframs == 1 { printf("BRICK_STATS min = %f <--> actual min = %f\n", af.brick_stats[0+2*frame], fMin*scaling); printf("BRICK_STATS max = %f <--> actual max = %f\n", af.brick_stats[1+2*frame], fMax*scaling); } } // nframes } else // not reading volume mri = MRIcopy(header, NULL); strcpy(mri->fname, fname); fclose(fp); MRIfree(&header); AFclean(&af); return(mri); } /* end afniRead() */
int main(int argc, char *argv[]) { char **av ; int ac, nargs, n ; MRI *mri_src, *mri_dst = NULL, *mri_bias, *mri_orig, *mri_aseg = NULL ; char *in_fname, *out_fname ; int msec, minutes, seconds ; struct timeb start ; char cmdline[CMD_LINE_LEN] ; make_cmd_version_string (argc, argv, "$Id: mri_normalize.c,v 1.80 2012/10/16 21:38:35 nicks Exp $", "$Name: $", cmdline); /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mri_normalize.c,v 1.80 2012/10/16 21:38:35 nicks Exp $", "$Name: $"); if (nargs && argc - nargs == 1) { exit (0); } argc -= nargs; Progname = argv[0] ; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; mni.max_gradient = MAX_GRADIENT ; ac = argc ; av = argv ; for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) { nargs = get_option(argc, argv) ; argc -= nargs ; argv += nargs ; } if (argc < 3) { usage_exit(0) ; } if (argc < 1) { ErrorExit(ERROR_BADPARM, "%s: no input name specified", Progname) ; } in_fname = argv[1] ; if (argc < 2) { ErrorExit(ERROR_BADPARM, "%s: no output name specified", Progname) ; } out_fname = argv[2] ; if(verbose) { printf( "reading from %s...\n", in_fname) ; } mri_src = MRIread(in_fname) ; if (!mri_src) ErrorExit(ERROR_NO_FILE, "%s: could not open source file %s", Progname, in_fname) ; MRIaddCommandLine(mri_src, cmdline) ; if(nsurfs > 0) { MRI_SURFACE *mris ; MRI *mri_dist=NULL, *mri_dist_sup=NULL, *mri_ctrl, *mri_dist_one ; LTA *lta= NULL ; int i ; TRANSFORM *surface_xform ; if (control_point_fname) // do one pass with only file control points first { MRI3dUseFileControlPoints(mri_src, control_point_fname) ; mri_dst = MRI3dGentleNormalize(mri_src, NULL, DEFAULT_DESIRED_WHITE_MATTER_VALUE, NULL, intensity_above, intensity_below/2,1, bias_sigma, mri_not_control); } else { mri_dst = MRIcopy(mri_src, NULL) ; } for (i = 0 ; i < nsurfs ; i++) { mris = MRISread(surface_fnames[i]) ; if (mris == NULL) ErrorExit(ERROR_NOFILE,"%s: could not surface %s", Progname,surface_fnames[i]); surface_xform = surface_xforms[i] ; TransformInvert(surface_xform, NULL) ; if (surface_xform->type == MNI_TRANSFORM_TYPE || surface_xform->type == TRANSFORM_ARRAY_TYPE || surface_xform->type == REGISTER_DAT) { lta = (LTA *)(surface_xform->xform) ; #if 0 if (invert) { VOL_GEOM vgtmp; LT *lt; MATRIX *m_tmp = lta->xforms[0].m_L ; lta->xforms[0].m_L = MatrixInverse(lta->xforms[0].m_L, NULL) ; MatrixFree(&m_tmp) ; lt = <a->xforms[0]; if (lt->dst.valid == 0 || lt->src.valid == 0) { printf( "WARNING:***************************************************************\n"); printf( "WARNING:dst volume infor is invalid. Most likely produce wrong inverse.\n"); printf( "WARNING:***************************************************************\n"); } copyVolGeom(<->dst, &vgtmp); copyVolGeom(<->src, <->dst); copyVolGeom(&vgtmp, <->src); } #endif } if (stricmp(surface_xform_fnames[i], "identity.nofile") != 0) { MRIStransform(mris, NULL, surface_xform, NULL) ; } mri_dist_one = MRIcloneDifferentType(mri_dst, MRI_FLOAT) ; printf("computing distance transform\n") ; MRIScomputeDistanceToSurface(mris, mri_dist_one, mri_dist_one->xsize) ; if (i == 0) { mri_dist = MRIcopy(mri_dist_one, NULL) ; } else { MRIcombineDistanceTransforms(mri_dist_one, mri_dist, mri_dist) ; } // MRIminAbs(mri_dist_one, mri_dist, mri_dist) ; MRIfree(&mri_dist_one) ; } MRIscalarMul(mri_dist, mri_dist, -1) ; if (nonmax_suppress) { printf("computing nonmaximum suppression\n") ; mri_dist_sup = MRInonMaxSuppress(mri_dist, NULL, 0, 1) ; mri_ctrl = MRIcloneDifferentType(mri_dist_sup, MRI_UCHAR) ; MRIbinarize(mri_dist_sup, mri_ctrl, min_dist, CONTROL_NONE, CONTROL_MARKED) ; } else if (erode) { int i ; mri_ctrl = MRIcloneDifferentType(mri_dist, MRI_UCHAR) ; MRIbinarize(mri_dist, mri_ctrl, min_dist, CONTROL_NONE, CONTROL_MARKED) ; for (i = 0 ; i < erode ; i++) { MRIerode(mri_ctrl, mri_ctrl) ; } } else { mri_ctrl = MRIcloneDifferentType(mri_dist, MRI_UCHAR) ; MRIbinarize(mri_dist, mri_ctrl, min_dist, CONTROL_NONE, CONTROL_MARKED) ; } if (control_point_fname) { MRInormAddFileControlPoints(mri_ctrl, CONTROL_MARKED) ; } if (mask_sigma > 0) { MRI *mri_smooth, *mri_mag, *mri_grad ; mri_smooth = MRIgaussianSmooth(mri_dst, mask_sigma, 1, NULL) ; mri_mag = MRIcloneDifferentType(mri_dst, MRI_FLOAT) ; mri_grad = MRIsobel(mri_smooth, NULL, mri_mag) ; MRIbinarize(mri_mag, mri_mag, mask_thresh, 1, 0) ; MRImask(mri_ctrl, mri_mag, mri_ctrl, 0, CONTROL_NONE) ; MRIfree(&mri_grad) ; MRIfree(&mri_mag) ; MRIfree(&mri_smooth) ; } if (mask_orig_fname) { MRI *mri_orig ; mri_orig = MRIread(mask_orig_fname) ; MRIbinarize(mri_orig, mri_orig, mask_orig_thresh, 0, 1) ; MRImask(mri_ctrl, mri_orig, mri_ctrl, 0, CONTROL_NONE) ; MRIfree(&mri_orig) ; } if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_dist, "d.mgz"); MRIwrite(mri_dist_sup, "dm.mgz"); MRIwrite(mri_ctrl, "c.mgz"); } MRIeraseBorderPlanes(mri_ctrl, 4) ; if (aseg_fname) { mri_aseg = MRIread(aseg_fname) ; if (mri_aseg == NULL) { ErrorExit(ERROR_NOFILE, "%s: could not load aseg from %s", Progname, aseg_fname) ; } remove_nonwm_voxels(mri_ctrl, mri_aseg, mri_ctrl) ; MRIfree(&mri_aseg) ; } else { remove_surface_outliers(mri_ctrl, mri_dist, mri_dst, mri_ctrl) ; } mri_bias = MRIbuildBiasImage(mri_dst, mri_ctrl, NULL, 0.0) ; if (mri_dist) { MRIfree(&mri_dist) ; } if (mri_dist_sup) { MRIfree(&mri_dist_sup) ; } if (bias_sigma> 0) { MRI *mri_kernel = MRIgaussian1d(bias_sigma, -1) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_bias, "b.mgz") ; } printf("smoothing bias field\n") ; MRIconvolveGaussian(mri_bias, mri_bias, mri_kernel) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_bias, "bs.mgz") ; } MRIfree(&mri_kernel); } MRIfree(&mri_ctrl) ; mri_dst = MRIapplyBiasCorrectionSameGeometry (mri_dst, mri_bias, mri_dst, DEFAULT_DESIRED_WHITE_MATTER_VALUE) ; printf("writing normalized volume to %s\n", out_fname) ; MRIwrite(mri_dst, out_fname) ; exit(0) ; } // end if(surface_fname) if (!mriConformed(mri_src) && conform > 0) { printf("unconformed source detected - conforming...\n") ; mri_src = MRIconform(mri_src) ; } if (mask_fname) { MRI *mri_mask ; mri_mask = MRIread(mask_fname) ; if (!mri_mask) ErrorExit(ERROR_NOFILE, "%s: could not open mask volume %s.\n", Progname, mask_fname) ; MRImask(mri_src, mri_mask, mri_src, 0, 0) ; MRIfree(&mri_mask) ; } if (read_flag) { MRI *mri_ctrl ; double scale ; mri_bias = MRIread(bias_volume_fname) ; if (!mri_bias) ErrorExit (ERROR_BADPARM, "%s: could not read bias volume %s", Progname, bias_volume_fname) ; mri_ctrl = MRIread(control_volume_fname) ; if (!mri_ctrl) ErrorExit (ERROR_BADPARM, "%s: could not read control volume %s", Progname, control_volume_fname) ; MRIbinarize(mri_ctrl, mri_ctrl, 1, 0, 128) ; mri_dst = MRImultiply(mri_bias, mri_src, NULL) ; scale = MRImeanInLabel(mri_dst, mri_ctrl, 128) ; printf("mean in wm is %2.0f, scaling by %2.2f\n", scale, 110/scale) ; scale = 110/scale ; MRIscalarMul(mri_dst, mri_dst, scale) ; MRIwrite(mri_dst, out_fname) ; exit(0) ; } if(long_flag) { MRI *mri_ctrl ; double scale ; mri_bias = MRIread(long_bias_volume_fname) ; if (!mri_bias) ErrorExit (ERROR_BADPARM, "%s: could not read bias volume %s", Progname, long_bias_volume_fname) ; mri_ctrl = MRIread(long_control_volume_fname) ; if (!mri_ctrl) ErrorExit (ERROR_BADPARM, "%s: could not read control volume %s", Progname, long_control_volume_fname) ; MRIbinarize(mri_ctrl, mri_ctrl, 1, 0, CONTROL_MARKED) ; if (mri_ctrl->type != MRI_UCHAR) { MRI *mri_tmp ; mri_tmp = MRIchangeType(mri_ctrl, MRI_UCHAR, 0, 1,1); MRIfree(&mri_ctrl) ; mri_ctrl = mri_tmp ; } scale = MRImeanInLabel(mri_src, mri_ctrl, CONTROL_MARKED) ; printf("mean in wm is %2.0f, scaling by %2.2f\n", scale, 110/scale) ; scale = DEFAULT_DESIRED_WHITE_MATTER_VALUE/scale ; mri_dst = MRIscalarMul(mri_src, NULL, scale) ; MRIremoveWMOutliers(mri_dst, mri_ctrl, mri_ctrl, intensity_below/2) ; mri_bias = MRIbuildBiasImage(mri_dst, mri_ctrl, NULL, 0.0) ; MRIsoapBubble(mri_bias, mri_ctrl, mri_bias, 50, 1) ; MRIapplyBiasCorrectionSameGeometry(mri_dst, mri_bias, mri_dst, DEFAULT_DESIRED_WHITE_MATTER_VALUE); // MRIwrite(mri_dst, out_fname) ; // exit(0) ; } // end if(long_flag) if (grad_thresh > 0) { float thresh ; MRI *mri_mag, *mri_grad, *mri_smooth ; MRI *mri_kernel = MRIgaussian1d(.5, -1) ; mri_not_control = MRIcloneDifferentType(mri_src, MRI_UCHAR) ; switch (scan_type) { case MRI_MGH_MPRAGE: thresh = 15 ; break ; case MRI_WASHU_MPRAGE: thresh = 20 ; break ; case MRI_UNKNOWN: default: thresh = 12 ; break ; } mri_smooth = MRIconvolveGaussian(mri_src, NULL, mri_kernel) ; thresh = grad_thresh ; mri_mag = MRIcloneDifferentType(mri_src, MRI_FLOAT) ; mri_grad = MRIsobel(mri_smooth, NULL, mri_mag) ; MRIwrite(mri_mag, "m.mgz") ; MRIbinarize(mri_mag, mri_not_control, thresh, 0, 1) ; MRIwrite(mri_not_control, "nc.mgz") ; MRIfree(&mri_mag) ; MRIfree(&mri_grad) ; MRIfree(&mri_smooth) ; MRIfree(&mri_kernel) ; } #if 0 #if 0 if ((mri_src->type != MRI_UCHAR) || (!(mri_src->xsize == 1 && mri_src->ysize == 1 && mri_src->zsize == 1))) #else if (conform || (mri_src->type != MRI_UCHAR && conform > 0)) #endif { MRI *mri_tmp ; fprintf (stderr, "downsampling to 8 bits and scaling to isotropic voxels...\n") ; mri_tmp = MRIconform(mri_src) ; mri_src = mri_tmp ; } #endif if(aseg_fname) { printf("Reading aseg %s\n",aseg_fname); mri_aseg = MRIread(aseg_fname) ; if (mri_aseg == NULL) ErrorExit (ERROR_NOFILE, "%s: could not read aseg from file %s", Progname, aseg_fname) ; if (!mriConformed(mri_aseg)) { ErrorExit(ERROR_UNSUPPORTED, "%s: aseg volume %s must be conformed", Progname, aseg_fname) ; } } else { mri_aseg = NULL ; } if(verbose) { printf( "normalizing image...\n") ; } fflush(stdout); fflush(stderr); TimerStart(&start) ; if (control_point_fname) { MRI3dUseFileControlPoints(mri_src, control_point_fname) ; } // this just setup writing control-point volume saving if(control_volume_fname) { MRI3dWriteControlPoints(control_volume_fname) ; } /* first do a gentle normalization to get things in the right intensity range */ if(long_flag == 0) // if long, then this will already have been done with base control points { if(control_point_fname != NULL) /* do one pass with only file control points first */ mri_dst = MRI3dGentleNormalize(mri_src, NULL, DEFAULT_DESIRED_WHITE_MATTER_VALUE, NULL, intensity_above, intensity_below/2,1, bias_sigma, mri_not_control); else { mri_dst = MRIcopy(mri_src, NULL) ; } } fflush(stdout); fflush(stderr); if(mri_aseg) { MRI *mri_ctrl, *mri_bias ; int i ; printf("processing with aseg\n"); mri_ctrl = MRIclone(mri_aseg, NULL) ; for (i = 0 ; i < NWM_LABELS ; i++) { MRIcopyLabel(mri_aseg, mri_ctrl, aseg_wm_labels[i]) ; } printf("removing outliers in the aseg WM...\n") ; MRIremoveWMOutliersAndRetainMedialSurface(mri_dst, mri_ctrl, mri_ctrl, intensity_below) ; MRIbinarize(mri_ctrl, mri_ctrl, 1, CONTROL_NONE, CONTROL_MARKED) ; MRInormAddFileControlPoints(mri_ctrl, CONTROL_MARKED) ; if (interior_fname1) { MRIS *mris_interior1, *mris_interior2 ; mris_interior1 = MRISread(interior_fname1) ; if (mris_interior1 == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read white matter surface from %s\n", Progname, interior_fname1) ; mris_interior2 = MRISread(interior_fname2) ; if (mris_interior2 == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read white matter surface from %s\n", Progname, interior_fname2) ; add_interior_points(mri_ctrl, mri_dst, intensity_above, 1.25*intensity_below, mris_interior1, mris_interior2, mri_aseg, mri_ctrl) ; MRISfree(&mris_interior1) ; MRISfree(&mris_interior2) ; } if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_ctrl, "norm_ctrl.mgz") ; } printf("Building bias image\n"); fflush(stdout); fflush(stderr); mri_bias = MRIbuildBiasImage(mri_dst, mri_ctrl, NULL, 0.0) ; fflush(stdout); fflush(stderr); if (bias_sigma> 0) { printf("Smoothing with sigma %g\n",bias_sigma); MRI *mri_kernel = MRIgaussian1d(bias_sigma, -1) ; MRIconvolveGaussian(mri_bias, mri_bias, mri_kernel) ; MRIfree(&mri_kernel); fflush(stdout); fflush(stderr); } MRIfree(&mri_ctrl) ; MRIfree(&mri_aseg) ; printf("Applying bias correction\n"); mri_dst = MRIapplyBiasCorrectionSameGeometry (mri_dst, mri_bias, mri_dst, DEFAULT_DESIRED_WHITE_MATTER_VALUE) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_dst, "norm_1.mgz") ; } fflush(stdout); fflush(stderr); } // if(mri_aseg) else { printf("processing without aseg, no1d=%d\n",no1d); if (!no1d) { printf("MRInormInit(): \n"); MRInormInit(mri_src, &mni, 0, 0, 0, 0, 0.0f) ; printf("MRInormalize(): \n"); mri_dst = MRInormalize(mri_src, NULL, &mni) ; if (!mri_dst) { no1d = 1 ; printf("1d normalization failed - trying no1d...\n") ; // ErrorExit(ERROR_BADPARM, "%s: normalization failed", Progname) ; } } if(no1d) { if ((file_only && nosnr) || ((gentle_flag != 0) && (control_point_fname != NULL))) { if (mri_dst == NULL) { mri_dst = MRIcopy(mri_src, NULL) ; } } else { if (nosnr) { if (interior_fname1) { MRIS *mris_interior1, *mris_interior2 ; MRI *mri_ctrl ; printf("computing initial normalization using surface interiors\n"); mri_ctrl = MRIcloneDifferentType(mri_src, MRI_UCHAR) ; mris_interior1 = MRISread(interior_fname1) ; if (mris_interior1 == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read white matter surface from %s\n", Progname, interior_fname1) ; mris_interior2 = MRISread(interior_fname2) ; if (mris_interior2 == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read white matter surface from %s\n", Progname, interior_fname2) ; add_interior_points(mri_ctrl, mri_dst, intensity_above, 1.25*intensity_below, mris_interior1, mris_interior2, mri_aseg, mri_ctrl) ; MRISfree(&mris_interior1) ; MRISfree(&mris_interior2) ; mri_bias = MRIbuildBiasImage(mri_dst, mri_ctrl, NULL, 0.0) ; if (bias_sigma> 0) { MRI *mri_kernel = MRIgaussian1d(bias_sigma, -1) ; MRIconvolveGaussian(mri_bias, mri_bias, mri_kernel) ; MRIfree(&mri_kernel); } mri_dst = MRIapplyBiasCorrectionSameGeometry (mri_src, mri_bias, mri_dst, DEFAULT_DESIRED_WHITE_MATTER_VALUE) ; MRIfree(&mri_ctrl) ; } else if (long_flag == 0) // no initial normalization specified { mri_dst = MRIcopy(mri_src, NULL) ; } } else { printf("computing initial normalization using SNR...\n") ; mri_dst = MRInormalizeHighSignalLowStd (mri_src, mri_dst, bias_sigma, DEFAULT_DESIRED_WHITE_MATTER_VALUE) ; } } if (!mri_dst) ErrorExit (ERROR_BADPARM, "%s: could not allocate volume", Progname) ; } } // else (not using aseg) fflush(stdout); fflush(stderr); if (file_only == 0) MRI3dGentleNormalize(mri_dst, NULL, DEFAULT_DESIRED_WHITE_MATTER_VALUE, mri_dst, intensity_above, intensity_below/2, file_only, bias_sigma, mri_not_control); mri_orig = MRIcopy(mri_dst, NULL) ; printf("\n"); printf("Iterating %d times\n",num_3d_iter); for (n = 0 ; n < num_3d_iter ; n++) { if(file_only) { break ; } printf( "---------------------------------\n"); printf( "3d normalization pass %d of %d\n", n+1, num_3d_iter) ; if (gentle_flag) MRI3dGentleNormalize(mri_dst, NULL, DEFAULT_DESIRED_WHITE_MATTER_VALUE, mri_dst, intensity_above/2, intensity_below/2, file_only, bias_sigma, mri_not_control); else MRI3dNormalize(mri_orig, mri_dst, DEFAULT_DESIRED_WHITE_MATTER_VALUE, mri_dst, intensity_above, intensity_below, file_only, prune, bias_sigma, scan_type, mri_not_control); } printf( "Done iterating ---------------------------------\n"); // this just setup writing control-point volume saving if(control_volume_fname) { MRI3dWriteControlPoints(control_volume_fname) ; } if(bias_volume_fname) { mri_bias = compute_bias(mri_src, mri_dst, NULL) ; printf("writing bias field to %s....\n", bias_volume_fname) ; MRIwrite(mri_bias, bias_volume_fname) ; MRIfree(&mri_bias) ; } if (verbose) { printf("writing output to %s\n", out_fname) ; } MRIwrite(mri_dst, out_fname) ; msec = TimerStop(&start) ; MRIfree(&mri_src); MRIfree(&mri_dst); seconds = nint((float)msec/1000.0f) ; minutes = seconds / 60 ; seconds = seconds % 60 ; printf( "3D bias adjustment took %d minutes and %d seconds.\n", minutes, seconds) ; exit(0) ; return(0) ; }
int MRIsampleParcellationToSurface(MRI_SURFACE *mris, MRI *mri_parc) { int min_label, max_label, **label_histo, l, vno, nlabels, x, y, z, max_l ; float fmin, fmax, max_count, d ; MRIS_HASH_TABLE *mht ; VERTEX *v ; Real xs, ys, zs, xv, yv, zv, val ; MRI *mri_parc_unused ; mri_parc_unused = MRIcopy(mri_parc, NULL) ; MRIvalRange(mri_parc, &fmin, &fmax) ; min_label = (int)floor(fmin) ; max_label = (int)ceil(fmax) ; nlabels = max_label - min_label + 1 ; label_histo = (int **)calloc(mris->nvertices, sizeof(int *)) ; if (label_histo == NULL) ErrorExit(ERROR_NOMEMORY, "%s: could not create label frequency histo", Progname) ; for (vno = 0 ; vno < mris->nvertices ; vno++) { label_histo[vno] = (int *)calloc(nlabels, sizeof(int)) ; if (label_histo[vno] == NULL) ErrorExit(ERROR_NOMEMORY, "%s: could not create label frequency histo[%d] with %d bins", Progname, vno, nlabels) ; } mht = MHTfillVertexTableRes(mris, NULL, CURRENT_VERTICES, 8.0) ; MRISclearMarks(mris) ; // build histograms at each vertex for (x = 0 ; x < mri_parc->width ; x++) { for (y = 0 ; y < mri_parc->height ; y++) { for (z = 0 ; z < mri_parc->depth ; z++) { if (x == Gx && y == Gy && z == Gz) DiagBreak() ; l = (int)MRIgetVoxVal(mri_parc, x, y, z, 0) ; if (l == 0) continue ; MRIvoxelToSurfaceRAS(mri_parc, x, y, z, &xs, &ys, &zs) ; v = MHTfindClosestVertexInTable(mht, mris, xs, ys, zs, 0) ; if (v == NULL) continue ; if (sqrt(SQR(v->x-xs) + SQR(v->y-ys) + SQR(v->z-zs)) > 3) continue ; MRIsetVoxVal(mri_parc_unused, x, y, z, 0, 0) ; vno = v-mris->vertices ; if (vno == Gdiag_no) { printf("v %d: sampling from (%d, %d, %d) - %d\n", vno, x, y, z, l); DiagBreak() ; } label_histo[vno][l-min_label]++ ; } } } MRIwrite(mri_parc_unused, "pu.mgz") ; for (vno = 0 ; vno < mris->nvertices ; vno++) { if (vno == Gdiag_no) DiagBreak() ; max_l = 0 ; max_count = 0 ; for (l = 0 ; l < nlabels ; l++) { if (label_histo[vno][l] > max_count) { max_count = label_histo[vno][l] ; max_l = l+min_label ; } } v = &mris->vertices[vno] ; v->val = v->annotation = max_l ; if (max_count > 0) v->marked = 1 ; } for (vno = 0 ; vno < mris->nvertices ; vno++) { v = &mris->vertices[vno] ; if (vno == Gdiag_no) DiagBreak() ; if (v->marked) continue ; // found something here for (d = 0 ; d <= 2 ; d += 0.25) { xs = v->x + d*v->nx; ys = v->y + d*v->ny; zs = v->z + d*v->nz; MRIsurfaceRASToVoxel(mri_parc, xs, ys, zs, &xv, &yv, &zv); MRIsampleVolumeType(mri_parc, xv, yv, zv, &val, SAMPLE_NEAREST) ; l = (int)nint(val) ; if (l > 0) { v->val = v->annotation = l ; break ; } } } MHTfree(&mht) ; for (vno = 0 ; vno < mris->nvertices ; vno++) free(label_histo[vno]) ; free(label_histo) ; MRIfree(&mri_parc_unused) ; return(NO_ERROR) ; }
int main(int argc, char *argv[]) { char **av ; int ac, nargs, width, height, depth, x, y, z, xborder, yborder, zborder, xrborder, yrborder, zrborder ; char *in_fname, *out_fname ; MRI *mri_smooth, *mri_grad, *mri_filter_src, *mri_filter_dst, *mri_dst, *mri_tmp, *mri_blur, *mri_src, *mri_filtered, *mri_direction, *mri_offset, *mri_up, *mri_polv, *mri_dir, *mri_clip, *mri_full ; MRI_REGION region, clip_region ; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mri_nlfilter.c,v 1.14 2011/03/02 00:04:23 nicks Exp $", "$Name: $"); if (nargs && argc - nargs == 1) exit (0); argc -= nargs; Progname = argv[0] ; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; ac = argc ; av = argv ; for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) { nargs = get_option(argc, argv) ; argc -= nargs ; argv += nargs ; } if (argc < 3) usage_exit() ; in_fname = argv[1] ; out_fname = argv[2] ; mri_full = mri_src = MRIread(in_fname) ; if (!mri_src) ErrorExit(ERROR_NOFILE, "%s: could not read '%s'", Progname, in_fname) ; if (!FZERO(blur_sigma)) /* allocate a blurring kernel */ { mri_blur = MRIgaussian1d(blur_sigma, 0) ; if (!mri_blur) ErrorExit(ERROR_BADPARM, "%s: could not allocate blurring kernel with sigma=%2.3f", Progname, blur_sigma) ; } else mri_blur = NULL ; MRIboundingBox(mri_full, 0, &clip_region) ; REGIONexpand(&clip_region, &clip_region, (filter_window_size+1)/2) ; mri_src = MRIextractRegion(mri_full, NULL, &clip_region) ; width = mri_src->width ; height = mri_src->height ; depth = mri_src->depth ; mri_dst = MRIclone(mri_src, NULL) ; if (!mri_dst) ErrorExit(ERROR_NOFILE, "%s: could allocate space for destination image", Progname) ; for (z = 0 ; z < depth ; z += region_size) { for (y = 0 ; y < height ; y += region_size) { DiagHeartbeat((float)(z*height+y) / (float)(height*(depth-1))) ; for (x = 0 ; x < width ; x += region_size) { region.x = x ; region.y = y ; region.z = z ; region.dx = region.dy = region.dz = region_size ; if (region.x == 142) DiagBreak() ; REGIONexpand(®ion, ®ion, (filter_window_size+1)/2) ; MRIclipRegion(mri_src, ®ion, ®ion) ; if (region.x == 142) DiagBreak() ; /* check for < 0 width regions */ xborder = x-region.x ; yborder = y-region.y ; zborder = z-region.z ; xrborder = MAX(0, (region.dx-xborder) - region_size) ; yrborder = MAX(0, (region.dy-yborder) - region_size) ; zrborder = MAX(0, (region.dz-zborder) - region_size) ; #if 0 if (region.dx < 2*xborder || region.dy<2*yborder||region.dz<2*zborder) continue ; #endif if (DIAG_VERBOSE_ON && (Gdiag & DIAG_SHOW)) fprintf(stderr, "extracting region (%d, %d, %d) --> (%d, %d, %d)...", region.x,region.y,region.z, region.x+region.dx-1, region.y+region.dy-1,region.z+region.dz-1) ; mri_clip = MRIextractRegion(mri_src, NULL, ®ion) ; if (DIAG_VERBOSE_ON && (Gdiag & DIAG_SHOW)) fprintf(stderr, "done.\nsmoothing region and up-sampling...") ; if (mri_blur) /* smooth the input image to generate offset field */ mri_smooth = MRIconvolveGaussian(mri_clip, NULL, mri_blur) ; else mri_smooth = MRIcopy(mri_clip, NULL) ; /* no smoothing */ if (!mri_smooth) ErrorExit(ERROR_BADPARM, "%s: image smoothing failed", Progname) ; /* now up-sample the smoothed image, and compute offset field in up-sampled domain */ mri_up = MRIupsample2(mri_smooth, NULL) ; if (!mri_up) ErrorExit(ERROR_BADPARM, "%s: up sampling failed", Progname) ; MRIfree(&mri_smooth) ; if (DIAG_VERBOSE_ON && (Gdiag & DIAG_SHOW)) fprintf(stderr, "done.\n") ; mri_smooth = mri_up ; mri_grad = MRIsobel(mri_smooth, NULL, NULL) ; mri_dir = MRIclone(mri_smooth, NULL) ; MRIfree(&mri_smooth) ; if (DIAG_VERBOSE_ON && (Gdiag & DIAG_SHOW)) fprintf(stderr, "computing direction map...") ; mri_direction = MRIoffsetDirection(mri_grad, offset_window_size, NULL, mri_dir) ; if (DIAG_VERBOSE_ON && (Gdiag & DIAG_SHOW)) fprintf(stderr, "computing offset magnitudes...") ; MRIfree(&mri_grad) ; mri_offset = MRIoffsetMagnitude(mri_direction, NULL, offset_search_len); MRIfree(&mri_direction) ; if (!mri_offset) ErrorExit(ERROR_NOMEMORY, "%s: offset calculation failed", Progname) ; if (DIAG_VERBOSE_ON && (Gdiag & DIAG_SHOW)) fprintf(stderr, "done.\nfiltering image...") ; mri_filter_src = MRIupsample2(mri_clip, NULL) ; MRIfree(&mri_clip) ; switch (filter_type) { case FILTER_CPOLV_MEDIAN: mri_polv = MRIplaneOfLeastVarianceNormal(mri_filter_src,NULL,5); mri_filter_dst = MRIpolvMedian(mri_filter_src, NULL, mri_polv,filter_window_size); MRIfree(&mri_polv) ; break ; case FILTER_GAUSSIAN: mri_filter_dst = MRIconvolveGaussian(mri_filter_src, NULL, mri_gaussian) ; if (!mri_filter_dst) ErrorExit(ERROR_NOMEMORY, "%s: could not allocate temporary buffer space",Progname); break ; case FILTER_MEDIAN: mri_filter_dst = MRImedian(mri_filter_src,NULL,filter_window_size, NULL); if (!mri_filter_dst) ErrorExit(ERROR_NOMEMORY, "%s: could not allocate temporary buffer space",Progname); break ; case FILTER_MEAN: mri_filter_dst = MRImean(mri_filter_src, NULL, filter_window_size) ; if (!mri_filter_dst) ErrorExit(ERROR_NOMEMORY, "%s: could not allocate temporary buffer space",Progname); break ; case FILTER_MINMAX: mri_filter_dst = MRIminmax(mri_filter_src, NULL, mri_dir, filter_window_size) ; if (!mri_filter_dst) ErrorExit(ERROR_NOMEMORY, "%s: could not allocate space for filtered image", Progname) ; break ; default: mri_filter_dst = MRIcopy(mri_filter_src, NULL) ; /* no filtering */ break ; } MRIfree(&mri_dir) ; MRIfree(&mri_filter_src) ; if (no_offset) { mri_filtered = MRIcopy(mri_filter_dst, NULL) ; } else { if (DIAG_VERBOSE_ON && (Gdiag & DIAG_SHOW)) fprintf(stderr, "applying offset field...") ; if (Gdiag & DIAG_WRITE) MRIwrite(mri_filter_dst, "minmax.mgz") ; mri_filtered = MRIapplyOffset(mri_filter_dst, NULL, mri_offset) ; if (!mri_filtered) ErrorExit(ERROR_NOMEMORY, "%s: could not allocate filtered image", Progname) ; if (DIAG_VERBOSE_ON && (Gdiag & DIAG_SHOW)) fprintf(stderr, "done.\n") ; if (region.x == 142) DiagBreak() ; MRIfree(&mri_offset) ; } MRIfree(&mri_filter_dst) ; if (Gdiag & DIAG_WRITE) MRIwrite(mri_filtered, "upfilt.mgz") ; mri_tmp = MRIdownsample2(mri_filtered, NULL) ; MRIfree(&mri_filtered) ; if (Gdiag & DIAG_WRITE) MRIwrite(mri_tmp, "downfilt.mgz") ; region.x += xborder ; region.y += yborder ; region.z += zborder ; #if 0 region.dx -=2*xborder; region.dy-= 2*yborder; region.dz -= 2 * zborder; #else region.dx -= xrborder + xborder; region.dy -= yrborder + yborder; region.dz -= zrborder + zborder; #endif if (region.dx <= 0 || region.dy <= 0 || region.dz <= 0) { fprintf(stderr, "invalid region: (%d,%d,%d) --> (%d,%d,%d)\n", region.x,region.y,region.z,region.dx,region.dy,region.dz); } else MRIextractIntoRegion(mri_tmp,mri_dst,xborder,yborder,zborder,®ion); MRIfree(&mri_tmp); } } } MRIextractIntoRegion(mri_dst,mri_full, 0, 0, 0, &clip_region); MRIfree(&mri_dst) ; if (DIAG_VERBOSE_ON && (Gdiag & DIAG_SHOW)) fprintf(stderr, "writing output image %s...", out_fname) ; MRIwrite(mri_full, out_fname) ; MRIfree(&mri_full) ; if (DIAG_VERBOSE_ON && (Gdiag & DIAG_SHOW)) fprintf(stderr, "done.\n") ; exit(0) ; return(0) ; /* for ansi */ }
int main(int argc, char *argv[]) { char **av, *out_name ; int ac, nargs ; int msec, minutes, seconds ; struct timeb start ; GCA_MORPH *gcam ; MRI *mri = NULL ; MATRIX *m; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mri_warp_convert.c,v 1.1 2012/02/13 23:05:52 jonp Exp $", "$Name: $"); if (nargs && argc - nargs == 1) { exit (0); } argc -= nargs; Progname = basename(argv[0]) ; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; TimerStart(&start) ; ac = argc ; av = argv ; for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) { nargs = get_option(argc, argv) ; argc -= nargs ; argv += nargs ; } if (argc < 3) { usage_exit(1) ; } // mri_convert expects a relative warp fprintf(stdout, "[%s]: reading warp file '%s'\n", Progname, argv[1]); fprintf(stdout, "assuming RELATIVE warp convention\n"); // TODO: add support for absolute warps as well, add option to specify convention mri = MRIread(argv[1]) ; if (mri == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read warp volume %s\n", Progname,argv[1]) ; m = MRIgetVoxelToRasXform(mri) ; // NOTE: this assumes a standard siemens image orientation in which // case a neurological orientation means that the first frame is // flipped if ( MatrixDeterminant(m) > 0 ) { fprintf(stdout, "non-negative Jacobian determinant -- converting to radiological ordering\n"); } { // 2012/feb/08: tested with anisotropic voxel sizes MRI *mri2 = NULL ; int c=0,r=0,s=0; float v; mri2 = MRIcopy(mri,NULL); for(c=0; c < mri->width; c++) { for(r=0; r < mri->height; r++) { for(s=0; s < mri->depth; s++) { // only flip first frame (by negating relative shifts) v = MRIgetVoxVal(mri, c,r,s,0) / mri->xsize; if ( MatrixDeterminant(m) > 0 ) MRIsetVoxVal( mri2,c,r,s,0,-v); else MRIsetVoxVal( mri2,c,r,s,0, v); v = MRIgetVoxVal(mri, c,r,s,1) / mri->ysize; MRIsetVoxVal( mri2,c,r,s,1, v); v = MRIgetVoxVal(mri, c,r,s,2) / mri->zsize; MRIsetVoxVal( mri2,c,r,s,2, v); } } } MRIfree(&mri); mri = mri2; } MatrixFree(&m) ; // this does all the work! (gcamorph.c) gcam = GCAMalloc(mri->width, mri->height, mri->depth) ; GCAMinitVolGeom(gcam, mri, mri) ; // not sure if removing singularities is ever a bad thing #if 1 GCAMremoveSingularitiesAndReadWarpFromMRI(gcam, mri) ; #else GCAMreadWarpFromMRI(gcam, mri) ; #endif fprintf(stdout, "[%s]: writing warp file '%s'\n", Progname, argv[2]); out_name = argv[2] ; GCAMwrite(gcam, out_name) ; msec = TimerStop(&start) ; seconds = nint((float)msec/1000.0f) ; minutes = seconds / 60 ; seconds = seconds % 60 ; fprintf(stderr, "conversion took %d minutes and %d seconds.\n", minutes, seconds) ; exit(0) ; return(0) ; }
MRI *MRInormalizeXH(MRI *mri_src, MRI *mri_dst, MRI *mri_mask) { /* Normalize the source volume to be zero mean and variance 1*/ /* mri_dst and mri_src can be the same */ int width, height, depth, x, y, z; float mean, variance, total, tmpval; if (mri_src->type != MRI_FLOAT) { printf("Normalization is only applied for float-typed volume \n"); mri_dst = MRIcopy(mri_src, mri_dst); return (mri_dst); } width = mri_src->width ; height = mri_src->height ; depth = mri_src->depth ; if (!mri_dst) mri_dst = MRIclone(mri_src, NULL) ; /* compute mean */ mean = 0.0; total = 0.0; for (z = 0 ; z < depth ; z++) for (y = 0 ; y < height ; y++) for (x = 0 ; x < width ; x++) { if (!mri_mask) { mean += MRIFvox(mri_src, x, y, z); total += 1; } else { if (MRIvox(mri_mask, x, y, z) >0) { mean += MRIFvox(mri_src, x, y, z); total += 1; } } } if (total > 0.0) mean = mean/total; /* compute variance */ variance = 0.0; for (z = 0 ; z < depth ; z++) for (y = 0 ; y < height ; y++) for (x = 0 ; x < width ; x++) { if (!mri_mask) { tmpval = MRIFvox(mri_src, x, y, z) - mean; variance += tmpval*tmpval; } else { if (MRIvox(mri_mask, x, y, z) >0) { tmpval = MRIFvox(mri_src, x, y, z) - mean; variance += tmpval*tmpval; } } } if (total > 0) variance = sqrt(variance/total); else variance = 1; /* normalization: invert variance first to save time */ variance = 1.0/variance; for (z = 0 ; z < depth ; z++) for (y = 0 ; y < height ; y++) for (x = 0 ; x < width ; x++) { tmpval = MRIFvox(mri_src, x, y, z) - mean; MRIFvox(mri_dst, x, y, z) = tmpval*variance; } return (mri_dst); }
int main(int argc, char *argv[]) { char **av, *in_fname; int ac, nargs, i, j, x, y, z, width, height, depth; MRI *mri_flash[MAX_IMAGES], *mri_label, *mri_mask, *mri_tmp; int msec, minutes, seconds, nvolumes, nvolumes_total ; struct timeb start ; float max_val, min_val, value; float *LDAmean1, *LDAmean2, *LDAweight; int label; double sum_white, sum_gray; int count_white, count_gray; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mri_ms_LDA.c,v 1.4 2011/03/02 00:04:23 nicks Exp $", "$Name: $"); if (nargs && argc - nargs == 1) exit (0); argc -= nargs; Progname = argv[0] ; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; TimerStart(&start) ; ac = argc ; av = argv ; for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) { nargs = get_option(argc, argv) ; argc -= nargs ; argv += nargs ; } if (argc < 2) usage_exit(1) ; printf("command line parsing finished\n"); if (have_weight == 0 && ldaflag == 0) { printf("Use -lda option to specify two class labels to optimize CNR on \n"); usage_exit(0); } if (have_weight == 0 && label_fname == NULL) { printf("Use -label option to specify file for segmentation \n"); usage_exit(0); } if (have_weight == 1 && weight_fname == NULL) { printf("Use -weight option to specify file for input LDA weights \n") ; usage_exit(0); } if (have_weight == 1 && synth_fname == NULL) { printf("Use -synth option to specify file for output synthesized volume \n") ; usage_exit(0); } ////////////////////////////////////////////////////////////////////////////////// /*** Read in the input multi-echo volumes ***/ nvolumes = 0 ; for (i = 1 ; i < argc; i++) { in_fname = argv[i] ; printf("reading %s...\n", in_fname) ; mri_flash[nvolumes] = MRIread(in_fname) ; if (mri_flash[nvolumes] == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read volume %s", Progname, in_fname) ; /* conform will convert all data to UCHAR, which will reduce data resolution*/ printf("%s read in. \n", in_fname) ; if (conform) { printf("embedding and interpolating volume\n") ; mri_tmp = MRIconform(mri_flash[nvolumes]) ; MRIfree(&mri_flash[nvolumes]); mri_flash[nvolumes] = mri_tmp ; } /* Change all volumes to float type for convenience */ if (mri_flash[nvolumes]->type != MRI_FLOAT) { printf("Volume %d type is %d\n", nvolumes+1, mri_flash[nvolumes]->type); printf("Change data to float type \n"); mri_tmp = MRIchangeType(mri_flash[nvolumes], MRI_FLOAT, 0, 1.0, 1); MRIfree(&mri_flash[nvolumes]); mri_flash[nvolumes] = mri_tmp; //swap } nvolumes++ ; } printf("All data read in\n"); /////////////////////////////////////////////////////////////////////////// nvolumes_total = nvolumes ; /* all volumes read in */ for (i = 0 ; i < nvolumes ; i++) { for (j = i+1 ; j < nvolumes ; j++) { if ((mri_flash[i]->width != mri_flash[j]->width) || (mri_flash[i]->height != mri_flash[j]->height) || (mri_flash[i]->depth != mri_flash[j]->depth)) ErrorExit(ERROR_BADPARM, "%s:\nvolumes %d (type %d) and %d (type %d) don't match (%d x %d x %d) vs (%d x %d x %d)\n", Progname, i, mri_flash[i]->type, j, mri_flash[j]->type, mri_flash[i]->width, mri_flash[i]->height, mri_flash[i]->depth, mri_flash[j]->width, mri_flash[j]->height, mri_flash[j]->depth) ; } } width = mri_flash[0]->width; height = mri_flash[0]->height; depth = mri_flash[0]->depth; if (label_fname != NULL) { mri_label = MRIread(label_fname); if (!mri_label) ErrorExit(ERROR_NOFILE, "%s: could not read input volume %s\n", Progname, label_fname); if ((mri_label->width != mri_flash[0]->width) || (mri_label->height != mri_flash[0]->height) || (mri_label->depth != mri_flash[0]->depth)) ErrorExit(ERROR_BADPARM, "%s: label volume size doesn't match data volumes\n", Progname); /* if(mri_label->type != MRI_UCHAR) ErrorExit(ERROR_BADPARM, "%s: label volume is not UCHAR type \n", Progname); */ } if (mask_fname != NULL) { mri_mask = MRIread(mask_fname); if (!mri_mask) ErrorExit(ERROR_NOFILE, "%s: could not read input volume %s\n", Progname, mask_fname); if ((mri_mask->width != mri_flash[0]->width) || (mri_mask->height != mri_flash[0]->height) || (mri_mask->depth != mri_flash[0]->depth)) ErrorExit(ERROR_BADPARM, "%s: mask volume size doesn't macth data volumes\n", Progname); if (mri_mask->type != MRI_UCHAR) ErrorExit(ERROR_BADPARM, "%s: mask volume is not UCHAR type \n", Progname); } else { if (have_weight == 1) noise_threshold = - 1e20; printf("Threshold input vol1 at %g to create mask \n", noise_threshold); printf("this threshold is useful to process skull-stripped data \n"); mri_mask = MRIalloc(mri_flash[0]->width, mri_flash[0]->height, mri_flash[0]->depth, MRI_UCHAR); MRIcopyHeader(mri_flash[0], mri_mask); /* Simply set mask to be 1 everywhere */ for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if ((float)MRIgetVoxVal(mri_flash[0], x, y,z,0) < noise_threshold) MRIvox(mri_mask, x, y,z) = 0; else MRIvox(mri_mask, x, y,z) = 1; } } /* Normalize input volumes */ if (normflag) { printf("Normalize input volumes to zero mean, variance 1\n"); for (i=0; i <nvolumes_total; i++) { mri_flash[i] = MRInormalizeXH(mri_flash[i], mri_flash[i], mri_mask); } printf("Normalization done.\n"); } if (0) { printf("Using both hemi-sphere by changing rh-labels\n"); for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { label = (int)MRIgetVoxVal(mri_label, x, y,z,0); if (label == 41) /* white matter */ MRIsetVoxVal(mri_label, x, y, z, 0, 2); else if (label == 42) /* gm */ MRIsetVoxVal(mri_label, x, y, z, 0, 3); } } if (debug_flag && window_flag) { /* Limit LDA to a local window */ printf("Local window size = %d\n", window_size); window_size /= 2; for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if (MRIvox(mri_mask, x, y,z) == 0) continue; if (z < (Gz - window_size) || z >(Gz + window_size) || y <(Gy - window_size) || y > (Gy + window_size) || x < (Gx - window_size) || x > (Gx + window_size)) MRIvox(mri_mask, x, y,z) = 0; } } LDAmean1 = (float *)malloc(nvolumes_total*sizeof(float)); LDAmean2 = (float *)malloc(nvolumes_total*sizeof(float)); LDAweight = (float *)malloc(nvolumes_total*sizeof(float)); if (have_weight) { printf("Read in LDA weights from weight-file\n"); input_weights_to_file(LDAweight, weight_fname, nvolumes_total); } else { /* compute LDA weights */ printf("Compute LDA weights to maximize CNR for region %d and region %d\n", class1, class2); /* Compute class means */ update_LDAmeans(mri_flash, mri_label, mri_mask, LDAmean1, LDAmean2, nvolumes_total, class1, class2); printf("class means computed \n"); /* Compute Fisher's LDA weights */ computeLDAweights(LDAweight, mri_flash, mri_label, mri_mask, LDAmean1, LDAmean2, nvolumes_total, class1, class2); if (weight_fname != NULL) { output_weights_to_file(LDAweight, weight_fname, nvolumes_total); } } printf("LDA weights are: \n"); for (i=0; i < nvolumes_total; i++) { printf("%g ", LDAweight[i]); } printf("\n"); if (synth_fname != NULL) { /* linear projection of input volumes to a 1D volume */ min_val = 10000.0; max_val = -10000.0; for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if (whole_volume == 0 && MRIvox(mri_mask, x, y, z) == 0) continue; value = 0.0; for (i=0; i < nvolumes_total; i++) { value += MRIFvox(mri_flash[i], x, y, z)*LDAweight[i]; } // if(value < 0) value = 0; if (max_val < value) max_val = value; if (min_val > value) min_val = value; /* Borrow mri_flash[0] to store the float values first */ MRIFvox(mri_flash[0], x, y, z) = value; } printf("max_val = %g, min_val = %g \n", max_val, min_val); /* Check to make sure class1 has higher intensity than class2 */ if (have_weight == 0) { sum_white =0; count_white = 0; sum_gray = 0; count_gray = 0; for (z=0; z < depth; z++) { if (count_white > 300 && count_gray > 300) break; for (y=0; y< height; y++) { for (x=0; x < width; x++) { if ((int)MRIgetVoxVal(mri_label, x, y,z,0) == class1) { sum_white += MRIFvox(mri_flash[0], x, y, z); count_white += 1; } else if ((int)MRIgetVoxVal(mri_label, x, y,z,0) == class2) { sum_gray += MRIFvox(mri_flash[0], x, y, z); count_gray += 1; } } } } if (count_white > 1 && count_gray > 1) { if (sum_white *count_gray < sum_gray*count_white) { for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if (whole_volume == 0 && MRIvox(mri_mask, x, y, z) == 0) continue; value = MRIFvox(mri_flash[0], x, y, z); MRIFvox(mri_flash[0], x, y, z) = max_val - value; } max_val = max_val - min_val; min_val = 0; } } } /* The following is copied to be consistent with mri_synthesize */ /* Don't know why add min_val, minus should make more sense */ for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if (whole_volume == 0 && MRIvox(mri_mask, x, y, z) == 0) { MRIFvox(mri_flash[0], x, y, z) = 0; /*background always set to 0 */ continue; } /* Borrow mri_flash[0] to store the float values first */ if (shift_value > 0) { value = MRIFvox(mri_flash[0], x, y, z) + shift_value; if (value < 0) value = 0; MRIFvox(mri_flash[0], x, y, z) = value; } else if (mask_fname != NULL) MRIFvox(mri_flash[0], x, y, z) -= min_val; } MRIfree(&mri_mask); if (mri_flash[0]->type == out_type) { mri_mask = MRIcopy(mri_flash[0], mri_mask); } else { mri_mask = MRIchangeType(mri_flash[0], out_type, 0.1, 0.99, 0); } /* Scale output to [0, 255] */ if (0) { for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if (whole_volume == 0 && MRIvox(mri_mask, x, y, z) == 0) continue; value = (MRIFvox(mri_flash[0], x, y, z) - min_val)*255.0/(max_val - min_val) + 0.5; /* +0.5 for round-off */ if (value > 255.0) value = 255.0; if (value < 0) value = 0; /* Borrow mri_flash[0] to store the float values first */ MRIvox(mri_mask, x, y, z) = (BUFTYPE) value; } } /* Output synthesized volume */ MRIwrite(mri_mask, synth_fname); } free(LDAmean1); free(LDAmean2); free(LDAweight); msec = TimerStop(&start) ; seconds = nint((float)msec/1000.0f) ; minutes = seconds / 60 ; seconds = seconds % 60 ; printf("LDA took %d minutes and %d seconds.\n", minutes, seconds) ; MRIfree(&mri_mask); if (label_fname) MRIfree(&mri_label); for (i=0; i < nvolumes_total; i++) { MRIfree(&mri_flash[i]); } exit(0); }
/* Actually no need to modify this function, since I will only use the float * type here, so the roundoff I added will never take effect. * What I need to modify is the MRIchangeType function! */ MRI *MRIlinearTransformInterpBSpline(MRI *mri_src, MRI *mri_dst, MATRIX *mA, int splinedegree) { int y1, y2, y3, width, height, depth ; VECTOR *v_X, *v_Y ; /* original and transformed coordinate systems */ MATRIX *mAinv ; /* inverse of mA */ double val, x1, x2, x3 ; MRI *mri_Bcoeff; mAinv = MatrixInverse(mA, NULL) ; /* will sample from dst back to src */ if (!mAinv) ErrorReturn(NULL, (ERROR_BADPARM, "MRIlinearTransformBSpline: xform is singular")) ; if (!mri_dst) mri_dst = MRIclone(mri_src, NULL) ; else MRIclear(mri_dst) ; /* set all values to zero */ if (mri_src->type != MRI_FLOAT) mri_Bcoeff = MRIchangeType(mri_src, MRI_FLOAT, 0, 1.0, 1); else mri_Bcoeff = MRIcopy(mri_src, NULL); /* convert between a representation based on image samples */ /* and a representation based on image B-spline coefficients */ if (SamplesToCoefficients(mri_Bcoeff, splinedegree)) { ErrorReturn(NULL, (ERROR_BADPARM, "Change of basis failed\n")); } printf("Direct B-spline Transform Finished. \n"); width = mri_src->width ; height = mri_src->height ; depth = mri_src->depth ; v_X = VectorAlloc(4, MATRIX_REAL) ; /* input (src) coordinates */ v_Y = VectorAlloc(4, MATRIX_REAL) ; /* transformed (dst) coordinates */ v_Y->rptr[4][1] = 1.0f ; for (y3 = 0 ; y3 < mri_dst->depth ; y3++) { V3_Z(v_Y) = y3 ; for (y2 = 0 ; y2 < mri_dst->height ; y2++) { V3_Y(v_Y) = y2 ; for (y1 = 0 ; y1 < mri_dst->width ; y1++) { V3_X(v_Y) = y1 ; MatrixMultiply(mAinv, v_Y, v_X) ; x1 = V3_X(v_X) ; x2 = V3_Y(v_X) ; x3 = V3_Z(v_X) ; if (x1 <= -0.5 || x1 >= (width - 0.5) || x2 <= -0.5 || x2 >= (height - 0.5) || x3 <= -0.5 || x3 >= (depth-0.5)) val = 0.0; else val = InterpolatedValue(mri_Bcoeff, x1, x2, x3, splinedegree); switch (mri_dst->type) { case MRI_UCHAR: if (val <-0.5) val = -0.5; if (val > 254.5) val = 254.5; MRIvox(mri_dst,y1,y2,y3) = (BUFTYPE)nint(val+0.5) ; break ; case MRI_SHORT: MRISvox(mri_dst,y1,y2,y3) = (short)nint(val+0.5) ; break ; case MRI_FLOAT: MRIFvox(mri_dst,y1,y2,y3) = (float)(val) ; break ; case MRI_INT: MRIIvox(mri_dst,y1,y2,y3) = nint(val+0.5) ; break ; default: ErrorReturn(NULL, (ERROR_UNSUPPORTED, "MRIlinearTransformBSpline: unsupported dst type %d", mri_dst->type)) ; break ; } } } } MatrixFree(&v_X) ; MatrixFree(&mAinv) ; MatrixFree(&v_Y) ; MRIfree(&mri_Bcoeff); return(mri_dst) ; }
int main(int argc, char *argv[]) { char **av, *source_fname, *target_fname, *out_fname, fname[STRLEN] ; int ac, nargs, new_transform = 0, pad ; MRI *mri_target, *mri_source, *mri_orig_source ; MRI_REGION box ; struct timeb start ; int msec, minutes, seconds ; GCA_MORPH *gcam ; MATRIX *m_L/*, *m_I*/ ; LTA *lta ; /* initialize the morph params */ memset(&mp, 0, sizeof(GCA_MORPH_PARMS)); /* for nonlinear morph */ mp.l_jacobian = 1 ; mp.min_sigma = 0.4 ; mp.l_distance = 0 ; mp.l_log_likelihood = .025 ; mp.dt = 0.005 ; mp.noneg = True ; mp.exp_k = 20 ; mp.diag_write_snapshots = 1 ; mp.momentum = 0.9 ; if (FZERO(mp.l_smoothness)) mp.l_smoothness = 2 ; mp.sigma = 8 ; mp.relabel_avgs = -1 ; mp.navgs = 256 ; mp.levels = 6 ; mp.integration_type = GCAM_INTEGRATE_BOTH ; mp.nsmall = 1 ; mp.reset_avgs = -1 ; mp.npasses = 3 ; mp.regrid = regrid? True : False ; mp.tol = 0.1 ; mp.niterations = 1000 ; TimerStart(&start) ; setRandomSeed(-1L) ; DiagInit(NULL, NULL, NULL) ; ErrorInit(NULL, NULL, NULL) ; Progname = argv[0] ; ac = argc ; av = argv ; for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) { nargs = get_option(argc, argv) ; argc -= nargs ; argv += nargs ; } if (argc < 4) usage_exit(1) ; source_fname = argv[1] ; target_fname = argv[2] ; out_fname = argv[3] ; FileNameOnly(out_fname, fname) ; FileNameRemoveExtension(fname, fname) ; strcpy(mp.base_name, fname) ; mri_source = MRIread(source_fname) ; if (!mri_source) ErrorExit(ERROR_NOFILE, "%s: could not read source label volume %s", Progname, source_fname) ; if (mri_source->type == MRI_INT) { MRI *mri_tmp = MRIchangeType(mri_source, MRI_FLOAT, 0, 1, 1) ; MRIfree(&mri_source); mri_source = mri_tmp ; } mri_target = MRIread(target_fname) ; if (!mri_target) ErrorExit(ERROR_NOFILE, "%s: could not read target label volume %s", Progname, target_fname) ; if (mri_target->type == MRI_INT) { MRI *mri_tmp = MRIchangeType(mri_target, MRI_FLOAT, 0, 1, 1) ; MRIfree(&mri_target); mri_target = mri_tmp ; } if (erosions > 0) { int n ; for (n = 0 ; n < erosions ; n++) { MRIerodeZero(mri_target, mri_target) ; MRIerodeZero(mri_source, mri_source) ; } } if (scale_values > 0) { MRIscalarMul(mri_source, mri_source, scale_values) ; MRIscalarMul(mri_target, mri_target, scale_values) ; } if (transform && transform->type == MORPH_3D_TYPE) TransformRas2Vox(transform, mri_source,NULL) ; if (use_aseg == 0) { if (match_peak_intensity_ratio) MRImatchIntensityRatio(mri_source, mri_target, mri_source, .8, 1.2, 100, 125) ; else if (match_mean_intensity) MRImatchMeanIntensity(mri_source, mri_target, mri_source) ; MRIboundingBox(mri_source, 0, &box) ; pad = (int)ceil(PADVOX * MAX(mri_target->xsize,MAX(mri_target->ysize,mri_target->zsize)) / MIN(mri_source->xsize,MIN(mri_source->ysize,mri_source->zsize))); #if 0 { MRI *mri_tmp ; if (pad < 1) pad = 1 ; printf("padding source with %d voxels...\n", pad) ; mri_tmp = MRIextractRegionAndPad(mri_source, NULL, &box, pad) ; if ((Gdiag & DIAG_WRITE) && DIAG_VERBOSE_ON) MRIwrite(mri_tmp, "t.mgz") ; MRIfree(&mri_source) ; mri_source = mri_tmp ; } #endif } mri_orig_source = MRIcopy(mri_source, NULL) ; mp.max_grad = 0.3*mri_source->xsize ; if (transform == NULL) transform = TransformAlloc(LINEAR_VOXEL_TO_VOXEL, NULL) ; if (transform->type != MORPH_3D_TYPE) // initializing m3d from a linear transform { new_transform = 1 ; lta = ((LTA *)(transform->xform)) ; if (lta->type != LINEAR_VOX_TO_VOX) { printf("converting ras xform to voxel xform\n") ; m_L = MRIrasXformToVoxelXform(mri_source, mri_target, lta->xforms[0].m_L, NULL) ; MatrixFree(<a->xforms[0].m_L) ; lta->type = LINEAR_VOX_TO_VOX ; } else { printf("using voxel xform\n") ; m_L = lta->xforms[0].m_L ; } #if 0 if (Gsx >= 0) // update debugging coords { VECTOR *v1, *v2 ; v1 = VectorAlloc(4, MATRIX_REAL) ; Gsx -= (box.x-pad) ; Gsy -= (box.y-pad) ; Gsz -= (box.z-pad) ; V3_X(v1) = Gsx ; V3_Y(v1) = Gsy ; V3_Z(v1) = Gsz ; VECTOR_ELT(v1,4) = 1.0 ; v2 = MatrixMultiply(m_L, v1, NULL) ; Gsx = nint(V3_X(v2)) ; Gsy = nint(V3_Y(v2)) ; Gsz = nint(V3_Z(v2)) ; MatrixFree(&v2) ; MatrixFree(&v1) ; printf("mapping by transform (%d, %d, %d) --> (%d, %d, %d) for rgb writing\n", Gx, Gy, Gz, Gsx, Gsy, Gsz) ; } #endif if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) write_snapshot(mri_target, mri_source, m_L, &mp, 0, 1, "linear_init"); lta->xforms[0].m_L = m_L ; printf("initializing GCAM with vox->vox matrix:\n") ; MatrixPrint(stdout, m_L) ; gcam = GCAMcreateFromIntensityImage(mri_source, mri_target, transform) ; #if 0 gcam->gca = gcaAllocMax(1, 1, 1, mri_target->width, mri_target->height, mri_target->depth, 0, 0) ; #endif GCAMinitVolGeom(gcam, mri_source, mri_target) ; if (use_aseg) { if (ribbon_name) { char fname[STRLEN], path[STRLEN], *str, *hemi ; int h, s, label ; MRI_SURFACE *mris_white, *mris_pial ; MRI *mri ; for (s = 0 ; s <= 1 ; s++) // source and target { if (s == 0) { str = source_surf ; mri = mri_source ; FileNamePath(mri->fname, path) ; strcat(path, "/../surf") ; } else { mri = mri_target ; FileNamePath(mri->fname, path) ; strcat(path, "/../elastic") ; str = target_surf ; } // sorry - these values come from FreeSurferColorLUT.txt MRIreplaceValueRange(mri, mri, 1000, 1034, Left_Cerebral_Cortex) ; MRIreplaceValueRange(mri, mri, 1100, 1180, Left_Cerebral_Cortex) ; MRIreplaceValueRange(mri, mri, 2000, 2034, Right_Cerebral_Cortex) ; MRIreplaceValueRange(mri, mri, 2100, 2180, Right_Cerebral_Cortex) ; for (h = LEFT_HEMISPHERE ; h <= RIGHT_HEMISPHERE ; h++) { if (h == LEFT_HEMISPHERE) { hemi = "lh" ; label = Left_Cerebral_Cortex ; } else { label = Right_Cerebral_Cortex ; hemi = "rh" ; } sprintf(fname, "%s/%s%s.white", path, hemi, str) ; mris_white = MRISread(fname) ; if (mris_white == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read surface %s", Progname, fname) ; MRISsaveVertexPositions(mris_white, WHITE_VERTICES) ; sprintf(fname, "%s/%s%s.pial", path, hemi, str) ; mris_pial = MRISread(fname) ; if (mris_pial == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read surface %s", Progname, fname) ; MRISsaveVertexPositions(mris_pial, PIAL_VERTICES) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { sprintf(fname, "sb.mgz") ; MRIwrite(mri_source, fname) ; sprintf(fname, "tb.mgz") ; MRIwrite(mri_target, fname) ; } insert_ribbon_into_aseg(mri, mri, mris_white, mris_pial, h) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { sprintf(fname, "sa.mgz") ; MRIwrite(mri_source, fname) ; sprintf(fname, "ta.mgz") ; MRIwrite(mri_target, fname) ; } MRISfree(&mris_white) ; MRISfree(&mris_pial) ; } } if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { sprintf(fname, "s.mgz") ; MRIwrite(mri_source, fname) ; sprintf(fname, "t.mgz") ; MRIwrite(mri_target, fname) ; } } GCAMinitLabels(gcam, mri_target) ; GCAMsetVariances(gcam, 1.0) ; mp.mri_dist_map = create_distance_transforms(mri_source, mri_target, NULL, 40.0, gcam) ; } } else /* use a previously create morph and integrate it some more */ { printf("using previously create gcam...\n") ; gcam = (GCA_MORPH *)(transform->xform) ; GCAMrasToVox(gcam, mri_source) ; if (use_aseg) { GCAMinitLabels(gcam, mri_target) ; GCAMsetVariances(gcam, 1.0) ; mp.mri_dist_map = create_distance_transforms(mri_source, mri_target, NULL, 40.0, gcam) ; } else GCAMaddIntensitiesFromImage(gcam, mri_target) ; } if (gcam->width != mri_source->width || gcam->height != mri_source->height || gcam->depth != mri_source->depth) ErrorExit(ERROR_BADPARM, "%s: warning gcam (%d, %d, %d), doesn't match source vol (%d, %d, %d)", Progname, gcam->width, gcam->height, gcam->depth, mri_source->width, mri_source->height, mri_source->depth) ; mp.mri_diag = mri_source ; mp.diag_morph_from_atlas = 0 ; mp.diag_write_snapshots = 1 ; mp.diag_sample_type = use_aseg ? SAMPLE_NEAREST : SAMPLE_TRILINEAR ; mp.diag_volume = use_aseg ? GCAM_LABEL : GCAM_MEANS ; if (renormalize) GCAMnormalizeIntensities(gcam, mri_target) ; if (mp.write_iterations != 0) { char fname[STRLEN] ; MRI *mri_gca ; if (getenv("DONT_COMPRESS")) sprintf(fname, "%s_target.mgh", mp.base_name) ; else sprintf(fname, "%s_target.mgz", mp.base_name) ; if (mp.diag_morph_from_atlas == 0) { printf("writing target volume to %s...\n", fname) ; MRIwrite(mri_target, fname) ; sprintf(fname, "%s_target", mp.base_name) ; MRIwriteImageViews(mri_target, fname, IMAGE_SIZE) ; } else { if (use_aseg) mri_gca = GCAMwriteMRI(gcam, NULL, GCAM_LABEL) ; else { mri_gca = MRIclone(mri_source, NULL) ; GCAMbuildMostLikelyVolume(gcam, mri_gca) ; } printf("writing target volume to %s...\n", fname) ; MRIwrite(mri_gca, fname) ; sprintf(fname, "%s_target", mp.base_name) ; MRIwriteImageViews(mri_gca, fname, IMAGE_SIZE) ; MRIfree(&mri_gca) ; } } if (nozero) { printf("disabling zero nodes\n") ; GCAMignoreZero(gcam, mri_target) ; } mp.mri = mri_target ; if (mp.regrid == True && new_transform == 0) GCAMregrid(gcam, mri_target, PAD, &mp, &mri_source) ; mp.write_fname = out_fname ; GCAMregister(gcam, mri_source, &mp) ; // atlas is target, morph target into register with it if (apply_transform) { MRI *mri_aligned ; char fname[STRLEN] ; FileNameRemoveExtension(out_fname, fname) ; strcat(fname, ".mgz") ; mri_aligned = GCAMmorphToAtlas(mp.mri, gcam, NULL, -1, mp.diag_sample_type) ; printf("writing transformed output volume to %s...\n", fname) ; MRIwrite(mri_aligned, fname) ; MRIfree(&mri_aligned) ; } printf("writing warp vector field to %s\n", out_fname) ; GCAMvoxToRas(gcam) ; GCAMwrite(gcam, out_fname) ; GCAMrasToVox(gcam, mri_source) ; msec = TimerStop(&start) ; seconds = nint((float)msec/1000.0f) ; minutes = seconds / 60 ; seconds = seconds % 60 ; printf("registration took %d minutes and %d seconds.\n", minutes, seconds) ; exit(0) ; return(0) ; }
static MRI * add_interior_points(MRI *mri_src, MRI *mri_vals, float intensity_above, float intensity_below, MRI_SURFACE *mris_white1, MRI_SURFACE *mris_white2, MRI *mri_aseg, MRI *mri_dst) { int x, y, z, ctrl, label, i ; float val ; MRI *mri_core ; MRI *mri_interior, *mri_tmp ; mri_interior = MRIclone(mri_src, NULL) ; MRISfillInterior(mris_white1, mri_src->xsize, mri_interior) ; mri_tmp = MRIclone(mri_src, NULL) ; MRISfillInterior(mris_white2, mri_src->xsize, mri_tmp) ; MRIcopyLabel(mri_tmp, mri_interior, 1) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_interior, "i.mgz") ; } mri_core = MRIerode(mri_interior, NULL) ; for (i = 1 ; i < nint(1.0/mri_src->xsize) ; i++) { MRIcopy(mri_core, mri_tmp) ; MRIerode(mri_tmp, mri_core) ; } MRIfree(&mri_tmp) ; if (mri_aseg == NULL) { for (x = 0 ; x < mri_src->width ; x++) for (y = 0 ; y < mri_src->height ; y++) for (z = 0 ; z < mri_src->depth ; z++) { if (Gx == x && Gy == y && Gz == z) { DiagBreak() ; } ctrl = MRIgetVoxVal(mri_core, x, y, z, 0) ; if (ctrl > 0) { MRIsetVoxVal(mri_dst, x, y, z, 0, ctrl) ; } } } else { for (x = 0 ; x < mri_src->width ; x++) for (y = 0 ; y < mri_src->height ; y++) for (z = 0 ; z < mri_src->depth ; z++) { if (Gx == x && Gy == y && Gz == z) { DiagBreak() ; } ctrl = MRIgetVoxVal(mri_src, x, y, z, 0) ; if (ctrl == 0) // add in some missed ones that are inside the surface { label = MRIgetVoxVal(mri_aseg, x, y, z, 0) ; if (IS_GM(label) || IS_WM(label)) { val = MRIgetVoxVal(mri_vals, x, y, z, 0) ; if ((val >= 110-intensity_below && val <= 110 + intensity_above)&& MRIgetVoxVal(mri_core, x, y, z, 0) > 0) { ctrl = 1 ; } } } MRIsetVoxVal(mri_dst, x, y, z, 0, ctrl) ; } } MRIfree(&mri_core) ; return(mri_dst) ; }
static MRI * MRIremoveWMOutliers(MRI *mri_src, MRI *mri_src_ctrl, MRI *mri_dst_ctrl, int intensity_below) { MRI *mri_bin, *mri_outliers = NULL ; float max, thresh, val; HISTOGRAM *histo, *hsmooth ; int wm_peak, x, y, z, nremoved = 0, whalf = 5, total ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_src_ctrl, "sc.mgz") ; } if (mri_dst_ctrl == NULL) { mri_dst_ctrl = MRIcopy(mri_src_ctrl, NULL) ; } mri_bin = MRIbinarize(mri_src_ctrl, NULL, 1, 0, CONTROL_MARKED) ; histo = MRIhistogramLabel(mri_src, mri_bin, 1, 256) ; hsmooth = HISTOcopy(histo, NULL) ; HISTOsmooth(histo, hsmooth, 2) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { HISTOplot(histo, "h.plt") ; HISTOplot(hsmooth, "hs.plt") ; } wm_peak = HISTOfindHighestPeakInRegion(hsmooth, 1, hsmooth->nbins-1) ; wm_peak = hsmooth->bins[wm_peak] ; thresh = wm_peak-intensity_below ; HISTOfree(&histo) ; HISTOfree(&hsmooth) ; if (Gdiag & DIAG_WRITE) { mri_outliers = MRIclone(mri_dst_ctrl, NULL) ; } for (total = x = 0 ; x < mri_src->width ; x++) { for (y = 0 ; y < mri_src->height ; y++) { for (z = 0 ; z < mri_src->depth ; z++) { if (x == Gx && y == Gy && z == Gz) { DiagBreak() ; } if (nint(MRIgetVoxVal(mri_dst_ctrl, x, y, z, 0)) == 0) { continue ; } max = MRImaxInLabelInRegion(mri_src, mri_bin, 1, x, y, z, whalf); val = MRIgetVoxVal(mri_src, x, y, z, 0) ; total++ ; if (val+intensity_below < max && val < thresh) { MRIsetVoxVal(mri_dst_ctrl, x, y, z, 0, 0) ; if (mri_outliers) { MRIsetVoxVal(mri_outliers, x, y, z, 0, 128) ; } nremoved++ ; } } } } printf( "%d control points removed (%2.1f%%)\n", nremoved, 100.0*(double)nremoved/(double)total) ; if (mri_outliers) { printf( "writing out.mgz outlier volume\n") ; MRIwrite(mri_outliers, "out.mgz") ; MRIfree(&mri_outliers) ; } if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_dst_ctrl, "dc.mgz") ; } MRIfree(&mri_bin) ; return(mri_dst_ctrl); }
static int remove_surface_outliers(MRI *mri_ctrl_src, MRI *mri_dist, MRI *mri_src, MRI *mri_ctrl_dst) { int x, y, z, wsize ; HISTOGRAM *h, *hs ; double mean, sigma, val ; MRI *mri_outlier = MRIclone(mri_ctrl_src, NULL) ; mri_ctrl_dst = MRIcopy(mri_ctrl_src, mri_ctrl_dst) ; wsize = nint(WSIZE_MM/mri_src->xsize) ; for (x = 0 ; x < mri_src->width ; x++) for (y = 0 ; y < mri_src->height ; y++) for (z = 0 ; z < mri_src->depth ; z++) { if (x == Gx && y == Gy && z == Gz) { DiagBreak() ; } if ((int)MRIgetVoxVal(mri_ctrl_src, x, y,z, 0) == 0) { continue ; // not a control point } val = MRIgetVoxVal(mri_src, x, y, z, 0) ; #if 1 if (val < 80 || val > 130) { MRIsetVoxVal(mri_ctrl_dst, x, y, z, 0, 0) ; // remove it as a control point MRIsetVoxVal(mri_outlier, x, y, z, 0, 1) ; // diagnostics continue ; } #endif #if 1 if (val > 100 || val < 120) { continue ; // not an outlier } #endif h = MRIhistogramVoxel(mri_src, 0, NULL, x, y, z, wsize, mri_dist, mri_src->xsize) ; HISTOsoapBubbleZeros(h, h, 100) ; hs = HISTOsmooth(h, NULL, .5); HISTOrobustGaussianFit(hs, .5, &mean, &sigma) ; #define MAX_SIGMA 10 // for intensity normalized images if (sigma > MAX_SIGMA) { sigma = MAX_SIGMA ; } if (fabs((mean-val)/sigma) > 2) { MRIsetVoxVal(mri_ctrl_dst, x, y, z, 0, 0) ; // remove it as a control point MRIsetVoxVal(mri_outlier, x, y, z, 0, 1) ; // diagnostics } if (Gdiag & DIAG_WRITE) { HISTOplot(h, "h.plt") ; HISTOplot(h, "hs.plt") ; } HISTOfree(&h) ; HISTOfree(&hs) ; } if (Gdiag & DIAG_WRITE) { MRIwrite(mri_outlier, "o.mgz") ; } MRIfree(&mri_outlier) ; return(NO_ERROR) ; }
/***-------------------------------------------------------****/ int main(int argc, char *argv[]) { int nargs, ac, nvolumes; char **av ; MRI *outmri0 = NULL, *outmri1 = NULL, *outmri2 = NULL, *outmri3 = NULL, *outmri4 = NULL, *segmri ; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, vcid, "$Name: $"); if (nargs && argc - nargs == 1) exit (0); Progname = argv[0] ; argc -= nargs; ac = argc ; av = argv ; for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) { nargs = get_option(argc, argv) ; argc -= nargs ; argv += nargs ; } nvolumes = argc-1 ; printf("processing %d input files\n", nvolumes) ; if (nvolumes != 2) usage_exit() ; printf("processing %d input files\n", nvolumes) ; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; char *fname = argv[1] ; printf("processing segmentation input volume %s\n", fname) ; segmri = MRIread(fname) ; //int width = segmri->width ; //int height = segmri->height ; //int depth = segmri->depth ; char *outputfname = argv[2] ; printf("output fname %s\n", outputfname) ; // GM/WM outmri0 = MRIcopy(segmri, NULL) ; // MRIwrite(outmri0, "/tmp/segmri.mgz") ; correct_gmwm_boundaries(segmri, outmri0); // MRIwrite(outmri0, "/tmp/outmri0.mgz") ; // putamen / pallidum outmri1 = MRIcopy(outmri0, NULL) ; correct_putamen_pallidum_boundaries(outmri0, outmri1); // MRIwrite(outmri1, "/tmp/outmri1.mgz") ; // GM / WM outmri2 = MRIcopy(outmri1, NULL) ; correct_gmwm_boundaries_2(outmri1, outmri2); // MRIwrite(outmri2, "/tmp/outmri2.mgz") ; // find largest connected components and close holes outmri3 = MRIcopy(segmri, NULL) ; MRIvalueFill(outmri3, 0); correct_largestCC_and_fill_holes(outmri2, outmri3); // MRIwrite(outmri3, "/tmp/outmri3.mgz") ; // fill leftover voxels in origiinal mask outmri4 = MRIcopy(outmri3, NULL) ; fill_leftover_voxels(segmri, outmri3, outmri4); // MRIwrite(outmri4, "/tmp/outmri4.mgz") ; // outmri0 = MRIcopy(outmri4, NULL) ; correct_gmwm_boundaries(outmri4, outmri0); // MRIwrite(outmri0, "/tmp/redone-outmri0.mgz") ; outmri1 = MRIcopy(outmri0, NULL) ; correct_putamen_pallidum_boundaries(outmri0, outmri1); // MRIwrite(outmri1, "/tmp/redone-outmri1.mgz") ; outmri2 = MRIcopy(outmri1, NULL) ; correct_gmwm_boundaries_2(outmri1, outmri2); // MRIwrite(outmri2, "/tmp/redone-outmri2.mgz") ; // printf("writing output to %s\n", outputfname) ; MRIwrite(outmri2, outputfname) ; MRIfree(&segmri) ; MRIfree(&outmri0); MRIfree(&outmri1); MRIfree(&outmri2); MRIfree(&outmri3); MRIfree(&outmri4); exit(0); } /* end main() */
static MRI * MRIremoveWMOutliersAndRetainMedialSurface(MRI *mri_src, MRI *mri_src_ctrl, MRI *mri_dst_ctrl, int intensity_below) { MRI *mri_inside, *mri_bin ; HISTOGRAM *histo, *hsmooth ; int wm_peak, x, y, z, nremoved ; float thresh, hi_thresh ; double val, lmean, max ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_src_ctrl, "sc.mgz") ; } if (mri_dst_ctrl != mri_src_ctrl) { mri_dst_ctrl = MRIcopy(mri_src_ctrl, mri_dst_ctrl) ; } mri_inside = MRIerode(mri_dst_ctrl, NULL) ; MRIbinarize(mri_inside, mri_inside, 1, 0, 1) ; histo = MRIhistogramLabel(mri_src, mri_inside, 1, 256) ; hsmooth = HISTOcopy(histo, NULL) ; HISTOsmooth(histo, hsmooth, 2) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { HISTOplot(histo, "h.plt") ; HISTOplot(hsmooth, "hs.plt") ; } printf("using wm (%d) threshold %2.1f for removing exterior voxels\n", wm_peak, thresh) ; wm_peak = HISTOfindHighestPeakInRegion(hsmooth, 1, hsmooth->nbins-1) ; wm_peak = hsmooth->bins[wm_peak] ; thresh = wm_peak-intensity_below ; hi_thresh = wm_peak-.5*intensity_below ; printf("using wm (%d) threshold %2.1f for removing exterior voxels\n", wm_peak, thresh) ; // now remove stuff that's on the border and is pretty dark for (nremoved = x = 0 ; x < mri_src->width ; x++) { for (y = 0 ; y < mri_src->height ; y++) { for (z = 0 ; z < mri_src->depth ; z++) { if (x == Gx && y == Gy && z == Gz) { DiagBreak() ; } /* if it's a control point, it's not in the interior of the wm, and it's T1 val is too low */ if (MRIgetVoxVal(mri_dst_ctrl, x, y, z, 0) == 0) { continue ; // not a control point } /* if it's way far from the wm mode then remove it even if it's in the interior */ val = MRIgetVoxVal(mri_src, x, y, z, 0) ; if (val < thresh-5) { MRIsetVoxVal(mri_dst_ctrl, x, y, z, 0, 0) ; nremoved++ ; } if (nint(MRIgetVoxVal(mri_inside, x, y, z, 0)) > 0) // don't process interior voxels further { continue ; // in the interior } if (val < thresh) { MRIsetVoxVal(mri_dst_ctrl, x, y, z, 0, 0) ; nremoved++ ; } else { lmean = MRImeanInLabelInRegion(mri_src, mri_inside, 1, x, y, z, 7); if (val < lmean-10) { MRIsetVoxVal(mri_dst_ctrl, x, y, z, 0, 0) ; nremoved++ ; } } } } } #if 0 for (x = 0 ; x < mri_src->width ; x++) { for (y = 0 ; y < mri_src->height ; y++) { for (z = 0 ; z < mri_src->depth ; z++) { if (x == Gx && y == Gy && z == Gz) { DiagBreak() ; } /* if it's a control point, it's not in the interior of the wm, and it's T1 val is too low */ if (MRIgetVoxVal(mri_dst_ctrl, x, y, z, 0) == 0) { continue ; // not a control point } if (MRIcountNonzeroInNbhd(mri_dst_ctrl,3, x, y, z)<=2) { MRIsetVoxVal(mri_dst_ctrl, x, y, z, 0, 0) ; nremoved++ ; } } } } #endif /* now take out voxels that have too big an intensity diff with surrounding ones */ mri_bin = MRIbinarize(mri_dst_ctrl, NULL, 1, 0, 1) ; for (x = 0 ; x < mri_src->width ; x++) { for (y = 0 ; y < mri_src->height ; y++) { for (z = 0 ; z < mri_src->depth ; z++) { if (x == Gx && y == Gy && z == Gz) { DiagBreak() ; } /* if it's a control point, it's not in the interior of the wm, and it's T1 val is too low */ if (MRIgetVoxVal(mri_dst_ctrl, x, y, z, 0) == 0) { continue ; // not a control point } val = MRIgetVoxVal(mri_src, x, y, z, 0) ; max = MRImaxInLabelInRegion(mri_src, mri_bin, 1, x, y, z, 3); if (val+7 < max && val < hi_thresh) { MRIsetVoxVal(mri_dst_ctrl, x, y, z, 0, 0) ; nremoved++ ; } } } } MRIfree(&mri_bin) ; printf( "%d control points removed\n", nremoved) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_dst_ctrl, "dc.mgz") ; } HISTOfree(&histo) ; HISTOfree(&hsmooth) ; MRIfree(&mri_inside) ; return(mri_dst_ctrl) ; }