/*! \fn int CCSegment(MRI *seg, int segid, int segidunknown) Constraints a sementation ID to consist of voxels that are spatially contiguous (6 face neighbors, not edge or corner). The voxels in the largest cluster are not changed. The voxels in the other clusters are set to segidunknown. */ int CCSegment(MRI *seg, int segid, int segidunknown) { MRI_SEGMENTATION *sgmnt; int k,kmax,index,c,r,s; sgmnt = MRIsegment(seg,segid-.5,segid+.5); printf(" Found %d clusters\n",sgmnt->nsegments); kmax = 0; for (k=0; k < sgmnt->nsegments; k++) if (sgmnt->segments[k].nvoxels > sgmnt->segments[kmax].nvoxels) { kmax = k; } for (k=0; k < sgmnt->nsegments; k++) { printf(" %d k %f\n",k,sgmnt->segments[k].area); if (k==kmax) { continue; } for (index = 0; index < sgmnt->segments[k].nvoxels; index++) { c = sgmnt->segments[k].voxels[index].x; r = sgmnt->segments[k].voxels[index].y; s = sgmnt->segments[k].voxels[index].z; MRIsetVoxVal(seg,c,r,s,0,segidunknown); } } MRIsegmentFree(&sgmnt); return(0); }
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) ; }
MRI * MRIfillBasalGanglia(MRI *mri_src, MRI *mri_dst) { float low_thresh, hi_thresh ; int total_filled, depth, height, width, x, y, z, xi, yi, zi, xk, yk, zk, fill, val0, val, i ; MRI *mri_bg ; Real tx, ty, tz ; MRI_SEGMENTATION *mriseg ; MRI_SEGMENT *mseg ; float dx_left, dx_right, dy, dz, dist_left, dist_right ; if (!mri_dst) { mri_dst = MRIcopy(mri_src, NULL) ; } mri_bg = MRIclone(mri_src, NULL) ; width = mri_src->width ; height = mri_src->height ; depth = mri_src->depth ; low_thresh = 85 ; hi_thresh = 105 ; total_filled = 0 ; for (z = 0 ; z < depth ; z++) { for (y = 0 ; y < height ; y++) { for (x = 0 ; x < width ; x++) { if (x == 152 && y == 117 && z == 132) /* 93 */ { DiagBreak() ; } val0 = MRIgetVoxVal(mri_src, x, y, z, 0) ; #if 0 if (val0 >= low_thresh && val0 <= hi_thresh && MRIvox(mri_dst,x,y,z) < WM_MIN_VAL) #else if (val0 >= 85 && val0 <= 105) #endif { #undef WHALF #undef WSIZE #define WSIZE 7 #define WHALF ((WSIZE-1)/2) fill = 1 ; for (zk = -WHALF ; fill && zk <= WHALF ; zk++) { zi = mri_src->zi[z+zk] ; for (yk = -WHALF ; fill && yk <= WHALF ; yk++) { yi = mri_src->yi[y+yk] ; for (xk = -WHALF ; fill && xk <= WHALF ; xk++) { xi = mri_src->xi[x+xk] ; val = MRIgetVoxVal(mri_src, xi, yi, zi, 0) ; if (val < 85 || val > 110) { fill = 0 ; /* not homogeneous enough */ } } } } } else { fill = 0 ; } if (fill) { total_filled++ ; } if (fill) { MRIsetVoxVal(mri_bg, x, y, z, 0, BASAL_GANGLIA_FILL) ; } } } } MRIclose(mri_bg, mri_bg) ; /* remove small holes */ /* segment into connected components */ mriseg = MRIsegment(mri_bg, 1, 255) ; fprintf(stderr, "segmenting thick gray regions: %d %d mm segments found\n", mriseg->nsegments, WSIZE) ; /* dilate into regions that are not on */ for (i = 0 ; i < 2*WSIZE ; i++) { MRIsegmentDilateThreshold(mriseg, mri_src, mri_src, 80, 100) ; } /* fill basal ganglia components */ MRIclear(mri_bg) ; for (total_filled = i = 0 ; i < mriseg->nsegments ; i++) { #define TAL_BG_LEFT_X -30 #define TAL_BG_RIGHT_X 30 #define TAL_BG_Y 5 #define TAL_BG_Z 5 #define MAX_DIST 25 mseg = &mriseg->segments[i] ; MRIvoxelToTalairach(mri_src, mseg->cx, mseg->cy, mseg->cz,&tx, &ty,&tz); dx_left = tx - TAL_BG_LEFT_X ; dx_right = tx - TAL_BG_RIGHT_X ; dy = ty - TAL_BG_Y ; dz = tz - TAL_BG_Z ; dist_left = sqrt(dx_left*dx_left+dy*dy+dz*dz) ; dist_right = sqrt(dx_right*dx_right+dy*dy+dz*dz) ; if (dist_left > MAX_DIST && dist_right > MAX_DIST) { continue ; } fprintf(stderr, "filling segment %d with %d voxels\n\tc = " "(%2.1f,%2.1f,%2.1f) tal (%2.1f,%2.1f,%2.1f), dist %2.1f,%2.1f\n", i, mseg->nvoxels, mseg->cx, mseg->cy, mseg->cz, tx, ty, tz, dist_left, dist_right) ; MRIsegmentToImage(mri_src, mri_bg, mriseg, i) ; total_filled += mseg->nvoxels ; } #if 1 /* MRIremoveIslands(mri_bg, mri_bg, 3, .56) ;*/ MRIbinarize(mri_bg, mri_bg, WM_MIN_VAL, 0, BASAL_GANGLIA_FILL) ; #endif MRIsegmentFree(&mriseg) ; MRIunion(mri_dst, mri_bg, mri_dst) ; MRIfree(&mri_bg) ; if (Gdiag & DIAG_SHOW) { fprintf(stderr, "%d basal ganglia points filled\n", total_filled); } return(mri_dst) ; }
MRI * MRIfillVentricles(MRI *mri_src, MRI *mri_dst) { int width, height, depth, x, y, z, xk, yk, xi, yi, nfilled, total, s ; MRI *mri_filled, *mri_ventricles = NULL ; MRI_SEGMENTATION *mriseg ; MRI_SEGMENT *mseg ; Real xt, yt, zt ; if (!mri_dst) { mri_dst = MRIclone(mri_src, NULL) ; } width = mri_src->width ; height = mri_src->height ; depth = mri_src->depth ; MRIcopy(mri_src, mri_dst) ; mri_filled = MRIcopy(mri_src, NULL) ; MRIreplaceValues(mri_filled, mri_filled, VENTRICLE_FILL, VENTRICLE_FILL-1) ; /* first fill each coronal slice starting from a background seed */ for (z = 0 ; z < depth ; z++) { total = 0 ; do { nfilled = 0 ; MRIsetVoxVal(mri_filled, 0, 0, z, 0, VENTRICLE_FILL) ; for (y = 0 ; y < height ; y++) { for (x = 0 ; x < width ; x++) { if (MRIgetVoxVal(mri_filled, x, y, z, 0) == VENTRICLE_FILL) { for (yk = -1 ; yk <= 1 ; yk++) { yi = mri_src->yi[y+yk] ; for (xk = -1 ; xk <= 1 ; xk++) { xi = mri_src->xi[x+xk] ; if (!MRIgetVoxVal(mri_filled, xi, yi, z, 0)) { nfilled++ ; MRIsetVoxVal(mri_filled, xi, yi, z, 0, VENTRICLE_FILL) ; } } } } } } total += nfilled ; } while (nfilled > 0) ; } MRIcomplement(mri_filled, mri_filled) ; MRIreplaceValues(mri_filled, mri_filled, 1, VENTRICLE_FILL) ; mriseg = MRIsegment(mri_filled, 1, 255) ; fprintf(stderr, "%d segments found...\n", mriseg->nsegments) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_filled, "exterior_filled.mgh") ; } for (s = 0 ; s < mriseg->nsegments ; s++) { mseg = &mriseg->segments[s] ; if (mseg->nvoxels < 100 || mseg->z1-mseg->z0 < 7) { continue ; } MRIvoxelToTalairach(mri_src, mseg->cx, mseg->cy, mseg->cz, &xt, &yt, &zt); fprintf(stderr, "added segment %d, nvox=%d, bbox [%d:%d, %d:%d, %d:%d]\n" "\tc = %2.1f, %2.1f, %2.1f (tal = %2.1f, %2.1f, %2.1f)\n", s, mseg->nvoxels, mseg->x0, mseg->x1, mseg->y0,mseg->y1,mseg->z0, mseg->z1, mseg->cx, mseg->cy, mseg->cz, xt, yt, zt) ; mri_ventricles = MRIsegmentToImage(mri_filled, mri_ventricles, mriseg, s) ; } MRIfree(&mri_filled) ; MRIsegmentFree(&mriseg) ; /* remove voxels close to the midline so that the cc can still be found */ for (z = 0 ; z < depth ; z++) { for (y = 0 ; y < height ; y++) { for (x = 0 ; x < width ; x++) { MRIvoxelToTalairach(mri_src, x, y, z, &xt, &yt, &zt); if (fabs(xt) < 5) { MRIsetVoxVal(mri_ventricles, x, y, z, 0, 0) ; } } } } if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_ventricles, "ventricles.mgh") ; } MRIunion(mri_ventricles, mri_dst, mri_dst) ; MRIfree(&mri_ventricles) ; return(mri_dst) ; }
int main(int argc, char *argv[]) { char **av, fname[STRLEN], *T1_fname, *PD_fname, *output_dir, *mdir ; int ac, nargs, msec, s ; MRI_SURFACE *mris ; MRI *mri_flash1, *mri_flash2, *mri_masked, *mri_masked_smooth, *mri_kernel, *mri_mean, *mri_dif, *mri_binary, *mri_distance ; MRI *mri_smooth, *mri_grad, *mri_inner ; struct timeb then ; double l_spring ; MRI_SEGMENTATION *mriseg ; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mris_AA_shrinkwrap.c,v 1.5 2011/03/02 00:04:34 nicks Exp $", "$Name: stable5 $"); if (nargs && argc - nargs == 1) exit (0); argc -= nargs; Gdiag |= DIAG_SHOW ; Progname = argv[0] ; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; memset(&parms, 0, sizeof(parms)) ; parms.projection = NO_PROJECTION ; parms.tol = 0.05 ; parms.check_tol = 1 ; parms.ignore_energy = 1 ; parms.dt = 0.5f ; parms.base_dt = BASE_DT_SCALE*parms.dt ; parms.l_spring_norm = 1 ; parms.l_shrinkwrap = 0 ; parms.l_intensity = 1 ; parms.niterations = 0 ; parms.write_iterations = 0 /*WRITE_ITERATIONS */; parms.integration_type = INTEGRATE_MOMENTUM ; parms.momentum = 0.0 /*0.8*/ ; parms.l_intensity = 1 ; parms.dt_increase = 1.0 /* DT_INCREASE */; parms.dt_decrease = 0.50 /* DT_DECREASE*/ ; parms.error_ratio = 50.0 /*ERROR_RATIO */; /* parms.integration_type = INTEGRATE_LINE_MINIMIZE ;*/ parms.l_surf_repulse = 0.0 ; parms.l_repulse = 0 /*1*/ ; ac = argc ; av = argv ; for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) { nargs = get_option(argc, argv) ; argc -= nargs ; argv += nargs ; } mdir = getenv("FREESURFER_HOME") ; if (!mdir) ErrorExit(ERROR_BADPARM, "FREESURFER_HOME not defined in environment") ; if (argc < 4) usage_exit() ; /* set default parameters for white and gray matter surfaces */ parms.niterations = 1000 ; if (parms.momentum < 0.0) parms.momentum = 0.0 /*0.75*/ ; TimerStart(&then) ; T1_fname = argv[1] ; PD_fname = argv[2] ; output_dir = argv[3] ; fprintf(stderr, "reading volume %s...\n", T1_fname) ; mri_flash1 = MRIread(T1_fname) ; if (!mri_flash1) ErrorExit(ERROR_NOFILE, "%s: could not read input volume %s", Progname, T1_fname) ; mri_flash2 = MRIread(PD_fname) ; if (!mri_flash2) ErrorExit(ERROR_NOFILE, "%s: could not read input volume %s", Progname, T1_fname) ; // setMRIforSurface(mri_flash1); sprintf(fname, "%s/lib/bem/ic%d.tri", mdir, ic_init) ; mris = MRISread(fname) ; if (!mris) ErrorExit(ERROR_NOFILE, "%s: could not read icosahedron %s", Progname, fname) ; mri_mean = MRImean(mri_flash1, NULL, 5) ; MRIwrite(mri_mean, "mean.mgz") ; mri_dif = MRIabsdiff(mri_flash1, mri_flash2, NULL) ; MRIwrite(mri_dif, "dif.mgz") ; mriseg = MRIsegment(mri_mean, 30, 100000) ; s = MRIsegmentMax(mriseg) ; mri_masked = MRIsegmentToImage(mri_flash1, NULL, mriseg, s) ; MRIwrite(mri_masked, "mask.mgz") ; MRIsegmentFree(&mriseg) ; // MRIthresholdMask(mri_dif, mri_masked, mri_dif, 1, 0) ; // MRIwrite(mri_dif, "dif_masked.mgz") ; mri_kernel = MRIgaussian1d(2, 0) ; mri_smooth = MRIconvolveGaussian(mri_dif, NULL, mri_kernel) ; MRIwrite(mri_smooth, "smooth.mgz") ; MRIScopyVolGeomFromMRI(mris, mri_smooth) ; mris->useRealRAS = 1 ; initialize_surface_position(mris, mri_dif, 1, &parms) ; MRISwrite(mris, "init") ; MRISrepositionToInnerSkull(mris, mri_smooth, &parms) ; exit(0) ; mri_grad = MRIsobel(mri_smooth, NULL, NULL) ; MRIwrite(mri_grad, "grad.mgz") ; mri_inner = MRIfindInnerBoundary(mri_dif, mri_grad, NULL, 5.0) ; MRIwrite(mri_inner, "inner.mgz") ; MRIbinarize(mri_inner, mri_inner, 10, 0, 128) ; MRISpositionOptimalSphere(mris, mri_inner, 6) ; MRISwrite(mris, "optimal") ; exit(0) ; parms.sigma = 4 / mri_flash1->xsize ; // mri_dist = create_distance_map(mri_masked, NULL, BORDER_VAL, OUTSIDE_BORDER_STEP) ; MRISsetVals(mris,parms.sigma) ; MRIScopyValToVal2(mris) ; MRISsetVals(mris, 0) ; sprintf(parms.base_name, "%s_inner_skull%s%s", "test", output_suffix, suffix) ; parms.mri_brain = mri_masked ; l_spring = parms.l_spring_norm ; mri_kernel = MRIgaussian1d(parms.sigma, 0) ; mri_binary = MRIbinarize(mri_dif, mri_binary, 40, 0, 128) ; MRIwrite(mri_binary, "bin.mgz") ; mri_distance = MRIdistanceTransform(mri_binary, NULL, 128, 100, DTRANS_MODE_SIGNED, NULL) ; MRIwrite(mri_distance, "dist.mgz") ; mri_masked_smooth = MRIconvolveGaussian(mri_distance, NULL, mri_kernel) ; MRIfree(&mri_kernel) ; MRIwrite(mri_masked_smooth, "dif_smooth.mgz") ; MRISwrite(mris, "inner_skull.tri") ; msec = TimerStop(&then) ; fprintf(stderr,"positioning took %2.1f minutes\n", (float)msec/(60*1000.0f)); exit(0) ; return(0) ; /* for ansi */ }
static int augment_thicknesses(FCD_DATA *fcd, MRI *mri_pvals, double min_dist, double max_dist, double thresh) { int h, vno ; VERTEX *v ; MRI_SURFACE *mris ; MRI *mri_thickness ; double nx, ny, nz, x0, y0, z0, d, x, y, z, val ; MRI_SEGMENTATION *mriseg ; mriseg = MRIsegment(mri_pvals, thresh, 1e10) ; MRIeraseSmallSegments(mriseg, mri_pvals, 20) ; MRIremoveSmallSegments(mriseg, 100) ; if (Gdiag & DIAG_WRITE) { MRIwrite(mri_pvals, "pvals.mgz") ; } MRIsegmentFree(&mriseg) ; for (h = 0 ; h <= 1 ; h++) // do each hemi { if (h == 0) // left hemi { mri_thickness = fcd->lh_thickness_on_lh ; mris = fcd->mris_lh ; } else // right hemi { mri_thickness = fcd->rh_thickness_on_rh ; mris = fcd->mris_rh ; } for (vno = 0 ; vno < mris->nvertices ; vno++) { if (vno == Gdiag_no) { DiagBreak() ; } v = &mris->vertices[vno] ; if (v->ripflag) { continue ; } MRISvertexNormalInVoxelCoords(mris, mri_pvals, vno, &nx, &ny, &nz) ; MRISvertexToVoxel(mris, v, mri_pvals, &x0, &y0, &z0) ; for (d = 0 ; d <= max_dist ; d += 0.5) { x = x0+d*nx ; y = y0+d*ny ; z = z0+d*nz ; MRIsampleVolume(mri_pvals, x, y, z, &val) ; if (val < thresh) { break ; } } if (d > min_dist) // a string of unlikely values { val = MRIgetVoxVal(mri_thickness, vno, 0, 0, 0) ; MRIsetVoxVal(mri_thickness, vno, 0, 0, 0, val+d) ; } } } return(NO_ERROR) ; }
int FCDcomputeThicknessLabels(FCD_DATA *fcd, double thickness_thresh, double sigma, int size_thresh) { MRI *mri_lh, *mri_rh, *mri_lh_diff, *mri_rh_diff ; int niter, vno, s ; MRI_SEGMENTATION *mriseg ; fcdFreeLabels(fcd) ; // free old ones if they exist niter = SIGMA_TO_SURFACE_SMOOTH_STEPS(sigma) ; // do LH mri_lh = MRIclone(fcd->lh_thickness_on_lh, NULL) ; mri_rh = MRIclone(fcd->lh_thickness_on_lh, NULL) ; exec_progress_callback(1, 8, 0, 1) ; MRISwriteFrameToValues(fcd->mris_lh, fcd->lh_thickness_on_lh, 0) ; MRISaverageVals(fcd->mris_lh, niter) ; MRISreadFrameFromValues(fcd->mris_lh, mri_lh, 0) ; exec_progress_callback(2, 8, 0, 1) ; MRISwriteFrameToValues(fcd->mris_lh, fcd->rh_thickness_on_lh, 0) ; MRISaverageVals(fcd->mris_lh, niter) ; MRISreadFrameFromValues(fcd->mris_lh, mri_rh, 0) ; mri_lh_diff = MRIsubtract(mri_lh, mri_rh, NULL) ; // lh minus rh on lh MRIfree(&mri_lh); MRIfree(&mri_rh) ; // do RH mri_lh = MRIclone(fcd->lh_thickness_on_rh, NULL) ; mri_rh = MRIclone(fcd->lh_thickness_on_rh, NULL) ; exec_progress_callback(3, 8, 0, 1) ; MRISwriteFrameToValues(fcd->mris_rh, fcd->lh_thickness_on_rh, 0) ; MRISaverageVals(fcd->mris_rh, niter) ; MRISreadFrameFromValues(fcd->mris_rh, mri_lh, 0) ; exec_progress_callback(4, 8, 0, 1) ; MRISwriteFrameToValues(fcd->mris_rh, fcd->rh_thickness_on_rh, 0) ; MRISaverageVals(fcd->mris_rh, niter) ; MRISreadFrameFromValues(fcd->mris_rh, mri_rh, 0) ; mri_rh_diff = MRIsubtract(mri_rh, mri_lh, NULL) ; // lh minus rh on rh MRIfree(&mri_lh); MRIfree(&mri_rh) ; MRIclear(fcd->mri_thickness_increase) ; MRIclear(fcd->mri_thickness_decrease) ; exec_progress_callback(5, 8, 0, 1) ; // process left hemisphere #if 1 #ifdef HAVE_OPENMP #pragma omp parallel for shared(fcd, mri_lh_diff, Gdiag_no, thickness_thresh) schedule(static,1) #endif #endif for (vno = 0 ; vno < fcd->mris_lh->nvertices ; vno++) { double d ; float val, val2, thickness; int base_label ; VERTEX *v ; v = &fcd->mris_lh->vertices[vno] ; if (v->ripflag) { continue ; } thickness = MRIgetVoxVal(fcd->lh_thickness_on_lh, vno, 0, 0, 0) ; if (vno == Gdiag_no) { DiagBreak() ; } val = MRIgetVoxVal(mri_lh_diff, vno, 0, 0, 0) ; if (fabs(val) < thickness_thresh) { continue ; } for (d = 0, base_label = 0 ; d < thickness ; d += 0.25) { double xv, yv, zv; double xs = v->x+d*v->nx ; double ys = v->y+d*v->ny ; double zs = v->z+d*v->nz ; MRISsurfaceRASToVoxel(fcd->mris_lh, fcd->mri_thickness_increase, xs, ys, zs, &xv, &yv, &zv) ; int xvi = nint(xv) ; int yvi = nint(yv) ; int zvi = nint(zv) ; int label = MRIgetVoxVal(fcd->mri_aparc, xvi, yvi, zvi, 0) ; if (IS_WM(label) == 0 && label >= MIN_CORTICAL_PARCELLATION && label != ctx_lh_unknown) { if (label != base_label) { if (base_label) { break ; } } else { base_label = label ; } if (val >= 0) { val2 = MRIgetVoxVal(fcd->mri_thickness_increase, xvi, yvi, zvi, 0) ; // check another thread already populated this voxel if (val > val2) { MRIsetVoxVal(fcd->mri_thickness_increase, xvi, yvi, zvi, 0, val) ; } } else { val2 = MRIgetVoxVal(fcd->mri_thickness_decrease, xvi, yvi, zvi, 0) ; // check if another thread already populated this voxel if (val < val2) { MRIsetVoxVal(fcd->mri_thickness_decrease, xvi, yvi, zvi, 0, val) ; } } } } } exec_progress_callback(6, 8, 0, 1) ; // now do right hemisphere #if 1 #ifdef HAVE_OPENMP #pragma omp parallel for shared(fcd, mri_rh_diff, Gdiag_no, thickness_thresh) schedule(static,1) #endif #endif for (vno = 0 ; vno < fcd->mris_rh->nvertices ; vno++) { double d ; float val, val2, thickness; int base_label ; VERTEX *v ; v = &fcd->mris_rh->vertices[vno] ; if (v->ripflag) { continue ; } if (vno == Gdiag_no) { DiagBreak() ; } val = MRIgetVoxVal(mri_rh_diff, vno, 0, 0, 0) ; if (fabs(val) < thickness_thresh) { continue ; } thickness = MRIgetVoxVal(fcd->rh_thickness_on_rh, vno, 0, 0, 0) ; for (d = 0, base_label = 0; d < thickness ; d += 0.25) { double xv, yv, zv; double xs = v->x+d*v->nx ; double ys = v->y+d*v->ny ; double zs = v->z+d*v->nz ; MRISsurfaceRASToVoxel(fcd->mris_rh, fcd->mri_thickness_increase, xs, ys, zs, &xv, &yv, &zv) ; int xvi = nint(xv) ; int yvi = nint(yv) ; int zvi = nint(zv) ; int label = MRIgetVoxVal(fcd->mri_aparc, xvi, yvi, zvi, 0) ; if (IS_WM(label) == 0 && label >= MIN_CORTICAL_PARCELLATION && label != ctx_rh_unknown) { if (label != base_label) { if (base_label) { break ; } } else { base_label = label ; } if (val >= 0) { val2 = MRIgetVoxVal(fcd->mri_thickness_increase, xvi, yvi, zvi, 0) ; if (val > val2) { MRIsetVoxVal(fcd->mri_thickness_increase, xvi, yvi, zvi, 0, val) ; } } else { val2 = MRIgetVoxVal(fcd->mri_thickness_decrease, xvi, yvi, zvi, 0) ; if (val < val2) { MRIsetVoxVal(fcd->mri_thickness_decrease, xvi, yvi, zvi, 0, val) ; } } } } } exec_progress_callback(7, 8, 0, 1) ; mriseg = MRIsegment(fcd->mri_thickness_increase, thickness_thresh, 1e10) ; MRIeraseSmallSegments(mriseg, fcd->mri_thickness_increase, thickness_thresh) ; MRIsegmentFree(&mriseg) ; MRIclose(fcd->mri_thickness_increase, fcd->mri_thickness_increase) ; mriseg = MRIsegment(fcd->mri_thickness_increase, thickness_thresh, 1e10) ; MRIremoveSmallSegments(mriseg, size_thresh) ; printf("segmenting volume at threshold %2.1f with %d " "smoothing iters yields %d segments\n", thickness_thresh, niter,mriseg->nsegments) ; fflush(stdout) ; exec_progress_callback(8, 8, 0, 1) ; fcd->nlabels = mriseg->nsegments ; for (s = 0 ; s < mriseg->nsegments ; s++) { int label ; fcd->labels[s] = MRIsegmentToLabel(mriseg, fcd->mri_thickness_increase, s) ; label = most_frequent_label(fcd->mri_aparc, &mriseg->segments[s]) ; strcpy(fcd->labels[s]->name, cma_label_to_name(label)) ; } sort_labels(fcd) ; MRIadd(fcd->mri_thickness_increase, fcd->mri_thickness_decrease, fcd->mri_thickness_difference); for (s = 0 ; s < mriseg->nsegments ; s++) { printf("%s: %2.3fmm\n", fcd->label_names[s], fcd->labels[s]->avg_stat) ; fflush(stdout) ; } MRIfree(&mri_lh_diff) ; MRIfree(&mri_rh_diff) ; MRIsegmentFree(&mriseg) ; return(fcd->nlabels) ; }