static float compute_overlap(MRI *mri_seg1, MRI *mri_seg2, TRANSFORM *transform1, TRANSFORM *transform2) { int x, y, z, width, height, depth, l1, l2, x2, y2, z2 ; float overlap, x1, y1, z1 ; TransformInvert(transform1, mri_seg1) ; width = mri_seg1->width ; height = mri_seg1->height ; depth = mri_seg1->depth ; for (overlap = 0.0f, x = 0 ; x < width ; x++) { for (y = 0 ; y < height ; y++) { for (z = 0 ; z < depth ; z++) { l1 = MRIvox(mri_seg1, x, y, z) ; TransformSample(transform1, x, y, z, &x1, &y1, &z1) ; /* atlas coords of s1 */ TransformSampleInverseVoxel(transform2, width, height, depth, nint(x1), nint(y1), nint(z1), &x2, &y2, &z2) ; l2 = MRIvox(mri_seg2, x2, y2, z2) ; if (l1 == l2) overlap++ ; } } } return(overlap) ; }
static int get_option(int argc, char *argv[]) { int nargs = 0 ; char *option ; option = argv[1] + 1 ; /* past '-' */ StrUpper(option) ; if (!stricmp(option, "debug_voxel")) { Gsx = Gx = atoi(argv[2]) ; Gsy = Gy = atoi(argv[3]) ; Gsz = Gz = atoi(argv[4]) ; nargs = 3 ; printf("debugging voxel (%d, %d, %d)\n", Gx, Gy, Gz) ; } else if (!stricmp(option, "debug_node")) { Gx = atoi(argv[2]) ; Gy = atoi(argv[3]) ; Gz = atoi(argv[4]) ; nargs = 3 ; printf("debugging node (%d, %d, %d)\n", Gx, Gy, Gz) ; } else if (!stricmp(option, "OPTIMAL")) { mp.integration_type = GCAM_INTEGRATE_OPTIMAL ; printf("using optimal time-step integration\n") ; } else if (!stricmp(option, "NONEG")) { mp.noneg = atoi(argv[2]) ; nargs = 1 ; printf("%s allowing temporary folds during numerical minimization\n", mp.noneg ? "not" : "") ; } else if (!stricmp(option, "renormalize")) { renormalize = atoi(argv[2]) ; nargs = 1 ; printf("%srenormalizing intensities\n", renormalize ? "" : "not "); if (renormalize == 0) { match_mean_intensity = match_peak_intensity_ratio = 0 ; } } else if (!stricmp(option, "aseg")) { match_mean_intensity = match_peak_intensity_ratio = 0 ; use_aseg = 1 ; mp.l_dtrans = 1 ; mp.l_log_likelihood = 0 ; renormalize = 0 ; printf("treating inputs as segmentations\n") ; mp.dtrans_labels = dtrans_labels ; mp.ndtrans = NDTRANS_LABELS ; } else if (!stricmp(option, "diag2")) { mp.mri_diag2 = MRIread(argv[2]) ; if (mp.mri_diag2 == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read diag volume from %s", Progname, argv[2]) ; nargs = 1 ; printf("writing d2 diagnostics for input volume %s\n", argv[2]) ; } else if (!stricmp(option, "MOMENTUM") || !stricmp(option, "FIXED")) { mp.integration_type = GCAM_INTEGRATE_FIXED ; printf("using optimal time-step integration\n") ; } else if (!stricmp(option, "distance")) { distance = atof(argv[2]) ; nargs = 1 ; printf("expanding border by %2.1f mm every outer cycle\n", distance); } else if (!stricmp(option, "dtrans")) { mp.l_dtrans = atof(argv[2]) ; nargs = 1 ; printf("setting distance transform coefficient to %2.3f\n", mp.l_dtrans) ; } else if (!stricmp(option, "match_peak")) { match_peak_intensity_ratio = 1 ; match_mean_intensity = 0 ; printf("matching peak of intensity ratio histogram\n") ; } else if (!stricmp(option, "erode")) { erosions = atoi(argv[2]) ; nargs = 1 ; printf("eroding source and target image %d times before morphing\n", erosions) ; } else if (!stricmp(option, "match_mean")) { match_peak_intensity_ratio = 0 ; match_mean_intensity = atoi(argv[2]) ; nargs = 1 ; printf("%smatching peak of intensity ratio histogram\n", match_mean_intensity ? "" : "not ") ; } else if (!stricmp(option, "intensity") ||!stricmp(option, "ll")) { mp.l_log_likelihood = atof(argv[2]) ; nargs = 1 ; printf("setting l_log_likelihood = %2.3f\n", mp.l_log_likelihood ); } else if (!stricmp(option, "noregrid")) { regrid = 0 ; mp.regrid = False ; printf("disabling regridding...\n") ; } else if (!stricmp(option, "regrid")) { regrid = 1 ; mp.regrid = True ; printf("enabling regridding...\n") ; } else if (!stricmp(option, "view")) { Gsx = atoi(argv[2]) ; Gsy = atoi(argv[3]) ; Gsz = atoi(argv[4]) ; nargs = 3 ; printf("viewing voxel (%d, %d, %d)\n", Gsx, Gsy, Gsz) ; } else if (!stricmp(option, "LEVELS")) { mp.levels = atoi(argv[2]) ; nargs = 1 ; printf("levels = %d\n", mp.levels) ; } else if (!stricmp(option, "area_smoothness") || !stricmp(option, "asmooth")) { mp.l_area_smoothness = atof(argv[2]) ; nargs = 1 ; printf("using l_area_smoothness=%2.3f\n", mp.l_area_smoothness) ; } else if (!stricmp(option, "area")) { mp.l_area = atof(argv[2]) ; nargs = 1 ; printf("using l_area=%2.3f\n", mp.l_area) ; } else if (!stricmp(option, "area_intensity")) { mp.l_area_intensity = atof(argv[2]) ; nargs = 1 ; printf("using l_area_intensity=%2.3f\n", mp.l_area_intensity) ; } else if (!stricmp(option, "tol")) { mp.tol = atof(argv[2]) ; nargs = 1 ; printf("using tol=%2.3f\n", mp.tol) ; } else if (!stricmp(option, "sigma")) { mp.sigma = atof(argv[2]) ; nargs = 1 ; printf("using sigma=%2.3f\n", mp.sigma) ; } else if (!stricmp(option, "min_sigma")) { mp.min_sigma = atof(argv[2]) ; nargs = 1 ; printf("using min sigma=%2.3f\n", mp.min_sigma) ; } else if (!stricmp(option, "ribbon")) { ribbon_name = argv[2] ; printf("reading ribbon from %s and inserting into aseg\n", ribbon_name) ; nargs = 1 ; } else if (!stricmp(option, "rthresh")) { mp.ratio_thresh = atof(argv[2]) ; mp.uncompress = 1 ; nargs = 1 ; printf("using compression ratio threshold = %2.3f...\n", mp.ratio_thresh) ; } else if (!stricmp(option, "scale")) { scale_values = atof(argv[2]) ; nargs = 1 ; printf("scaling input values by %2.3f\n", scale_values) ; } else if (!stricmp(option, "dt")) { mp.dt = atof(argv[2]) ; nargs = 1 ; printf("using dt = %2.3f\n", mp.dt) ; } else if (!stricmp(option, "passes")) { mp.npasses = atoi(argv[2]) ; nargs = 1 ; printf("integrating in %d passes (default=3)\n", mp.npasses) ; } else if (!stricmp(option, "skip")) { skip = atoi(argv[2]); printf("skipping %d voxels in source data...\n", skip) ; nargs = 1 ; } else if (!stricmp(option, "apply")) { apply_transform = atoi(argv[2]) ; nargs = 1 ; printf("%sapplying transform after registration\n", apply_transform ? "" : "not ") ; } else switch (*option) { case 'D': mp.l_distance = atof(argv[2]) ; nargs = 1 ; printf("using l_distance = %2.3f\n", mp.l_distance) ; break ; case 'M': mp.momentum = atof(argv[2]) ; nargs = 1 ; printf("momentum = %2.2f\n", mp.momentum) ; break ; case 'N': mp.niterations = atoi(argv[2]) ; nargs = 1 ; printf("using niterations = %d\n", mp.niterations) ; break ; case 'S': mp.l_smoothness = atof(argv[2]) ; nargs = 1 ; printf("using l_smoothness = %2.3f\n", mp.l_smoothness) ; break ; case 'T': printf("reading transform from %s...\n", argv[2]) ; transform = TransformRead(argv[2]) ; if (transform == NULL) ErrorExit(ERROR_NOFILE,"%s: could not read transform from %s\n",Progname,argv[2]); nargs = 1 ; if (transform->type == LINEAR_VOX_TO_VOX) { printf("converting transform to ras....\n") ; LTAvoxelToRasXform((LTA *)(transform->xform), NULL, NULL) ; } break ; case 'I': printf("reading transform from %s...\n", argv[2]) ; transform = TransformRead(argv[2]) ; if (transform == NULL) ErrorExit(ERROR_NOFILE,"%s: could not read transform from %s\n",Progname,argv[2]); TransformInvert(transform, NULL) ; TransformSwapInverse(transform) ; if (transform->type == LINEAR_VOX_TO_VOX) { printf("converting transform to ras....\n") ; LTAvoxelToRasXform((LTA *)(transform->xform), NULL, NULL) ; } nargs = 1 ; break ; case 'B': mp.l_binary = atof(argv[2]) ; nargs = 1 ; printf("using l_binary=%2.3f\n", mp.l_binary) ; break ; case 'J': mp.l_jacobian = atof(argv[2]) ; nargs = 1 ; printf("using l_jacobian=%2.3f\n", mp.l_jacobian) ; break ; case 'Z': nozero = (atoi(argv[2]) == 0) ; printf("%sdisabling zero image locations\n", nozero ? "" : "not ") ; nargs = 1 ; break ; case 'A': mp.navgs = atoi(argv[2]) ; nargs = 1 ; printf("smoothing gradient with %d averages...\n", mp.navgs) ; break ; case 'K': mp.exp_k = atof(argv[2]) ; printf("setting exp_k to %2.2f (default=%2.2f)\n", mp.exp_k, EXP_K) ; nargs = 1 ; break ; case 'W': mp.write_iterations = atoi(argv[2]) ; Gdiag |= DIAG_WRITE ; nargs = 1 ; printf("setting write iterations = %d\n", mp.write_iterations) ; break ; case '?': case 'U': usage_exit(1); break ; default: printf("unknown option %s\n", argv[1]) ; usage_exit(1) ; break ; } return(nargs) ; }
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 main(int argc, char *argv[]) { char **av, fname[STRLEN], *out_fname, *subject_name, *cp ; int ac, nargs, i, n, noint = 0, options ; int msec, minutes, seconds, nsubjects, input ; struct timeb start ; GCA *gca ; MRI *mri_seg, *mri_tmp, *mri_inputs ; TRANSFORM *transform ; LTA *lta; GCA_BOUNDARY *gcab ; Progname = argv[0] ; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; TimerStart(&start) ; parms.use_gradient = 0 ; spacing = 8 ; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mri_gcab_train.c,v 1.4 2011/03/16 20:23:33 fischl Exp $", "$Name: $"); if (nargs && argc - nargs == 1) exit (0); argc -= nargs; // parse command line args ac = argc ; av = argv ; for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) { nargs = get_option(argc, argv) ; argc -= nargs ; argv += nargs ; } printf("reading gca from %s\n", argv[1]) ; gca = GCAread(argv[1]) ; if (!gca) exit(Gerror) ; if (!strlen(subjects_dir)) /* hasn't been set on command line */ { cp = getenv("SUBJECTS_DIR") ; if (!cp) ErrorExit(ERROR_BADPARM, "%s: SUBJECTS_DIR not defined in environment", Progname); strcpy(subjects_dir, cp) ; if (argc < 4) usage_exit(1) ; } // options parsed. subjects and gca name remaining out_fname = argv[argc-1] ; nsubjects = argc-3 ; for (options = i = 0 ; i < nsubjects ; i++) { if (argv[i+1][0] == '-') { nsubjects-- ; options++ ; } } printf("training on %d subject and writing results to %s\n", nsubjects, out_fname) ; n = 0 ; gcab = GCABalloc(gca, 8, 0, 30, 10, target_label); strcpy(gcab->gca_fname, argv[1]) ; // going through the subject one at a time for (nargs = i = 0 ; i < nsubjects+options ; i++) { subject_name = argv[i+2] ; ////////////////////////////////////////////////////////////// printf("***************************************" "************************************\n"); printf("processing subject %s, %d of %d...\n", subject_name,i+1-nargs, nsubjects); if (stricmp(subject_name, "-NOINT") == 0) { printf("not using intensity information for subsequent subjects...\n"); noint = 1 ; nargs++ ; continue ; } else if (stricmp(subject_name, "-INT") == 0) { printf("using intensity information for subsequent subjects...\n"); noint = 0 ; nargs++ ; continue ; } // reading this subject segmentation sprintf(fname, "%s/%s/mri/%s", subjects_dir, subject_name, seg_dir) ; if (Gdiag & DIAG_SHOW && DIAG_VERBOSE_ON) fprintf(stderr, "Reading segmentation from %s...\n", fname) ; mri_seg = MRIread(fname) ; if (!mri_seg) ErrorExit(ERROR_NOFILE, "%s: could not read segmentation file %s", Progname, fname) ; if ((mri_seg->type != MRI_UCHAR) && (mri_seg->type != MRI_FLOAT)) { ErrorExit (ERROR_NOFILE, "%s: segmentation file %s is not type UCHAR or FLOAT", Progname, fname) ; } if (binarize) { int j ; for (j = 0 ; j < 256 ; j++) { if (j == binarize_in) MRIreplaceValues(mri_seg, mri_seg, j, binarize_out) ; else MRIreplaceValues(mri_seg, mri_seg, j, 0) ; } } if (insert_fname) { MRI *mri_insert ; sprintf(fname, "%s/%s/mri/%s", subjects_dir, subject_name, insert_fname) ; mri_insert = MRIread(fname) ; if (mri_insert == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read volume from %s for insertion", Progname, insert_fname) ; MRIbinarize(mri_insert, mri_insert, 1, 0, insert_label) ; MRIcopyLabel(mri_insert, mri_seg, insert_label) ; MRIfree(&mri_insert) ; } replaceLabels(mri_seg) ; MRIeraseBorderPlanes(mri_seg, 1) ; for (input = 0 ; input < gca->ninputs ; input++) { //////////// set the gca type ////////////////////////////// // is this T1/PD training? // how can we allow flash data training ??????? // currently checks the TE, TR, FA to be the same for all inputs // thus we cannot allow flash data training. //////////////////////////////////////////////////////////// sprintf(fname, "%s/%s/mri/%s", subjects_dir, subject_name,input_names[input]); if (DIAG_VERBOSE_ON) printf("reading co-registered input from %s...\n", fname) ; fprintf(stderr, " reading input %d: %s\n", input, fname); mri_tmp = MRIread(fname) ; if (!mri_tmp) ErrorExit (ERROR_NOFILE, "%s: could not read image from file %s", Progname, fname) ; // input check 1 if (getSliceDirection(mri_tmp) != MRI_CORONAL) { ErrorExit (ERROR_BADPARM, "%s: must be in coronal direction, but it is not\n", fname); } // input check 2 if (mri_tmp->xsize != 1 || mri_tmp->ysize != 1 || mri_tmp->zsize != 1) { ErrorExit (ERROR_BADPARM, "%s: must have 1mm voxel size, but have (%f, %f, %f)\n", fname, mri_tmp->xsize, mri_tmp->ysize, mri_tmp->ysize); } // input check 3 is removed. now we can handle c_(ras) != 0 case // input check 4 if (i == 0) { TRs[input] = mri_tmp->tr ; FAs[input] = mri_tmp->flip_angle ; TEs[input] = mri_tmp->te ; } else if (!FEQUAL(TRs[input],mri_tmp->tr) || !FEQUAL(FAs[input],mri_tmp->flip_angle) || !FEQUAL(TEs[input], mri_tmp->te)) ErrorExit (ERROR_BADPARM, "%s: subject %s input volume %s: sequence parameters " "(%2.1f, %2.1f, %2.1f)" "don't match other inputs (%2.1f, %2.1f, %2.1f)", Progname, subject_name, fname, mri_tmp->tr, DEGREES(mri_tmp->flip_angle), mri_tmp->te, TRs[input], DEGREES(FAs[input]), TEs[input]) ; // first time do the following if (input == 0) { int nframes = gca->ninputs ; /////////////////////////////////////////////////////////// mri_inputs = MRIallocSequence(mri_tmp->width, mri_tmp->height, mri_tmp->depth, mri_tmp->type, nframes) ; if (!mri_inputs) ErrorExit (ERROR_NOMEMORY, "%s: could not allocate input volume %dx%dx%dx%d", mri_tmp->width, mri_tmp->height, mri_tmp->depth,nframes) ; MRIcopyHeader(mri_tmp, mri_inputs) ; } // -mask option //////////////////////////////////////////// if (mask_fname) { MRI *mri_mask ; sprintf(fname, "%s/%s/mri/%s", subjects_dir, subject_name, mask_fname); printf("reading volume %s for masking...\n", fname) ; mri_mask = MRIread(fname) ; if (!mri_mask) ErrorExit(ERROR_NOFILE, "%s: could not open mask volume %s.\n", Progname, fname) ; MRImask(mri_tmp, mri_mask, mri_tmp, 0, 0) ; MRIfree(&mri_mask) ; } MRIcopyFrame(mri_tmp, mri_inputs, 0, input) ; MRIfree(&mri_tmp) ; }// end of inputs per subject ///////////////////////////////////////////////////////// // xform_name is given, then we can use the consistent c_(r,a,s) for gca ///////////////////////////////////////////////////////// if (xform_name) { // we read talairach.xfm which is a RAS-to-RAS sprintf(fname, "%s/%s/mri/transforms/%s", subjects_dir, subject_name, xform_name) ; if (Gdiag & DIAG_SHOW && DIAG_VERBOSE_ON) printf("INFO: reading transform file %s...\n", fname); if (!FileExists(fname)) { fprintf(stderr,"ERROR: cannot find transform file %s\n",fname); exit(1); } transform = TransformRead(fname); if (!transform) ErrorExit(ERROR_NOFILE, "%s: could not read transform from file %s", Progname, fname); modify_transform(transform, mri_inputs, gca); // Here we do 2 things // 1. modify gca direction cosines to // that of the transform destination (both linear and non-linear) // 2. if ras-to-ras transform, // then change it to vox-to-vox transform (linear case) // modify transform to store inverse also TransformInvert(transform, mri_inputs) ; // verify inverse lta = (LTA *) transform->xform; } else { GCAreinit(mri_inputs, gca); // just use the input value, since dst = src volume transform = TransformAlloc(LINEAR_VOXEL_TO_VOXEL, NULL) ; } //////////////////////////////////////////////////////////////////// // train gca //////////////////////////////////////////////////////////////////// // segmentation is seg volume // inputs is the volumes of all inputs // transform is for this subject // noint is whether to use intensity information or not GCABtrain(gcab, mri_inputs, mri_seg, transform, target_label) ; MRIfree(&mri_seg) ; MRIfree(&mri_inputs) ; TransformFree(&transform) ; } GCABcompleteTraining(gcab) ; if (smooth > 0) { printf("regularizing conditional densities with smooth=%2.2f\n", smooth) ; GCAregularizeConditionalDensities(gca, smooth) ; } if (navgs) { printf("applying mean filter %d times to conditional densities\n", navgs) ; GCAmeanFilterConditionalDensities(gca, navgs) ; } printf("writing trained GCAB to %s...\n", out_fname) ; if (GCABwrite(gcab, out_fname) != NO_ERROR) ErrorExit (ERROR_BADFILE, "%s: could not write gca to %s", Progname, out_fname) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRI *mri ; mri = GCAbuildMostLikelyVolume(gca, NULL) ; MRIwrite(mri, "m.mgz") ; MRIfree(&mri) ; } if (histo_fname) { FILE *fp ; int histo_counts[10000], xn, yn, zn, max_count ; GCA_NODE *gcan ; memset(histo_counts, 0, sizeof(histo_counts)) ; fp = fopen(histo_fname, "w") ; if (!fp) ErrorExit(ERROR_BADFILE, "%s: could not open histo file %s", Progname, histo_fname) ; max_count = 0 ; for (xn = 0 ; xn < gca->node_width; xn++) { for (yn = 0 ; yn < gca->node_height ; yn++) { for (zn = 0 ; zn < gca->node_depth ; zn++) { gcan = &gca->nodes[xn][yn][zn] ; if (gcan->nlabels < 1) continue ; if (gcan->nlabels == 1 && IS_UNKNOWN(gcan->labels[0])) continue ; histo_counts[gcan->nlabels]++ ; if (gcan->nlabels > max_count) max_count = gcan->nlabels ; } } } max_count = 20 ; for (xn = 1 ; xn < max_count ; xn++) fprintf(fp, "%d %d\n", xn, histo_counts[xn]) ; fclose(fp) ; } GCAfree(&gca) ; msec = TimerStop(&start) ; seconds = nint((float)msec/1000.0f) ; minutes = seconds / 60 ; seconds = seconds % 60 ; printf("classifier array training took %d minutes" " and %d seconds.\n", minutes, seconds) ; exit(0) ; return(0) ; }
int compute_tissue_modes( MRI *mri_inputs, GCA *gca, GCA_SAMPLE *gcas, TRANSFORM *transform, int nsamples, double *pwm, double *pgm, double *pfluid ) { int x, y, z, width, height, depth, i, xp, yp, zp ; float vals[MAX_GCA_INPUTS] ; int countOutside = 0, ngm, nwm, nfluid; double gm, wm, fluid ; /* go through each GC in the sample and compute the probability of the image at that point. */ width = mri_inputs->width ; height = mri_inputs->height; depth = mri_inputs->depth ; // store inverse transformation .. forward:input->gca template, // inv: gca template->input TransformInvert(transform, mri_inputs) ; // go through all sample points for (ngm = nwm = nfluid = 0, wm = gm = fluid = 0.0, i = 0 ; i < nsamples ; i++) { /////////////////// diag code ///////////////////////////// if (i == Gdiag_no) { DiagBreak() ; } if (Gdiag_no == gcas[i].label) { DiagBreak() ; } if (i == Gdiag_no || (gcas[i].xp == Gxp && gcas[i].yp == Gyp && gcas[i].zp == Gzp)) { DiagBreak() ; } /////////////////////////////////////////////////////////// // get prior coordinates xp = gcas[i].xp ; yp = gcas[i].yp ; zp = gcas[i].zp ; // if it is inside the source voxel if (!GCApriorToSourceVoxel(gca, mri_inputs, transform, xp, yp, zp, &x, &y, &z)) { if (x == Gx && y == Gy && z == Gz) { DiagBreak() ; } // (x,y,z) is the source voxel position gcas[i].x = x ; gcas[i].y = y ; gcas[i].z = z ; // get values from all inputs load_vals(mri_inputs, x, y, z, vals, gca->ninputs) ; if (FZERO(vals[0]) && gcas[i].label == Gdiag_no) { DiagBreak() ; } if (gcas[i].tissue_class == GM_CLASS) { ngm++ ; gm += vals[0] ; } else if (gcas[i].tissue_class == WM_CLASS) { nwm++ ; wm += vals[0] ; } else if (gcas[i].tissue_class == FLUID_CLASS) { nfluid++ ; fluid += vals[0] ; } if (!FZERO(vals[0])) { DiagBreak() ; } if (gcas[i].label != Unknown) { DiagBreak() ; } if (i == Gdiag_no) { DiagBreak() ; } } else // outside the volume { countOutside++; } } if (nfluid == 0) { nfluid = 1 ; } if (ngm == 0) { ngm = 1 ; } if (nwm == 0) { nwm = 1 ; } wm /= nwm ; gm /= ngm ; fluid /= nfluid ; G_wm_mean = *pwm = wm ; G_gm_mean = *pgm = gm ; G_fluid_mean = *pfluid = fluid ; return(NO_ERROR) ; }
int main(int argc, char *argv[]) { char *gca_fname, *in_fname, **av, *xform_fname ; MRI *mri_in, *mri_tmp, *mri_orig = NULL ; GCA *gca ; int ac, nargs, input, ninputs ; TRANSFORM *transform = NULL ; char cmdline[CMD_LINE_LEN] ; double ll ; make_cmd_version_string (argc, argv, "$Id: mri_log_likelihood.c,v 1.4 2011/03/02 00:04:22 nicks Exp $", "$Name: stable5 $", cmdline); /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mri_log_likelihood.c,v 1.4 2011/03/02 00:04:22 nicks Exp $", "$Name: stable5 $"); if (nargs && argc - nargs == 1) exit (0); argc -= nargs; setRandomSeed(-1L) ; Progname = argv[0] ; DiagInit(NULL, NULL, NULL) ; ErrorInit(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) ErrorExit (ERROR_BADPARM, "usage: %s [<options>] <inbrain1> <inbrain2> ... " "<atlas> <transform file> ...\n", Progname) ; ninputs = (argc - 1) / 2 ; if (DIAG_VERBOSE_ON) printf("reading %d input volume%ss\n", ninputs, ninputs > 1 ? "s" : "") ; in_fname = argv[1] ; gca_fname = argv[1+ninputs] ; xform_fname = argv[2+ninputs] ; transform = TransformRead(xform_fname) ; if (!transform) ErrorExit(ERROR_NOFILE, "%s: could not read input transform from %s", Progname, xform_fname) ; if (DIAG_VERBOSE_ON) printf("reading atlas from '%s'...\n", gca_fname) ; gca = GCAread(gca_fname) ; if (!gca) ErrorExit(ERROR_NOFILE, "%s: could not read input atlas from %s", Progname, gca_fname) ; fflush(stdout) ; for (input = 0 ; input < ninputs ; input++) { in_fname = argv[1+input] ; if (DIAG_VERBOSE_ON) printf("reading input volume from %s...\n", in_fname) ; mri_tmp = MRIread(in_fname) ; if (!mri_tmp) ErrorExit(ERROR_NOFILE, "%s: could not read input MR volume from %s", Progname, in_fname) ; MRImakePositive(mri_tmp, mri_tmp) ; if (input == 0) { mri_in = MRIallocSequence(mri_tmp->width, mri_tmp->height, mri_tmp->depth, mri_tmp->type, ninputs) ; if (!mri_in) ErrorExit(ERROR_NOMEMORY, "%s: could not allocate input volume %dx%dx%dx%d", mri_tmp->width,mri_tmp->height,mri_tmp->depth,ninputs) ; MRIcopyHeader(mri_tmp, mri_in) ; } MRIcopyFrame(mri_tmp, mri_in, 0, input) ; MRIfree(&mri_tmp) ; } MRIaddCommandLine(mri_in, cmdline) ; TransformInvert(transform, mri_in) ; if (orig_fname) { mri_orig = MRIread(orig_fname) ; if (mri_orig == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read orig volume from %s", Progname, orig_fname) ; } ll = GCAimageLogLikelihood(gca, mri_in, transform, 1, mri_orig) ; printf("%2.0f\n", 10000*ll) ; MRIfree(&mri_in) ; if (gca) GCAfree(&gca) ; if (mri_in) MRIfree(&mri_in) ; exit(0) ; return(0) ; }
int main(int argc, char *argv[]) { char **av, fname[STRLEN], *out_fname, *subject_name, *cp, *tp1_name, *tp2_name ; char s1_name[STRLEN], s2_name[STRLEN], *sname ; int ac, nargs, i, n, options, max_index ; int msec, minutes, seconds, nsubjects, input ; struct timeb start ; MRI *mri_seg, *mri_tmp, *mri_in ; TRANSFORM *transform ; // int counts ; int t; RANDOM_FOREST *rf = NULL ; GCA *gca = NULL ; Progname = argv[0] ; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; TimerStart(&start) ; parms.width = parms.height = parms.depth = DEFAULT_VOLUME_SIZE ; parms.ntrees = 10 ; parms.max_depth = 10 ; parms.wsize = 1 ; parms.training_size = 100 ; parms.training_fraction = .5 ; parms.feature_fraction = 1 ; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mri_rf_long_train.c,v 1.5 2012/06/15 12:22:28 fischl Exp $", "$Name: $"); if (nargs && argc - nargs == 1) exit (0); argc -= nargs; // parse command line args ac = argc ; av = argv ; for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) { nargs = get_option(argc, argv) ; argc -= nargs ; argv += nargs ; } if (!strlen(subjects_dir)) /* hasn't been set on command line */ { cp = getenv("SUBJECTS_DIR") ; if (!cp) ErrorExit(ERROR_BADPARM, "%s: SUBJECTS_DIR not defined in environment", Progname); strcpy(subjects_dir, cp) ; } if (argc < 3) usage_exit(1) ; // options parsed. subjects, tp1 and tp2 and rf name remaining out_fname = argv[argc-1] ; nsubjects = (argc-2)/3 ; for (options = i = 0 ; i < nsubjects ; i++) { if (argv[i+1][0] == '-') { nsubjects-- ; options++ ; } } printf("training on %d subject and writing results to %s\n", nsubjects, out_fname) ; // rf_inputs can be T1, PD, ...per subject if (parms.nvols == 0) parms.nvols = ninputs ; /* gca reads same # of inputs as we read from command line - not the case if we are mapping to flash */ n = 0 ; ////////////////////////////////////////////////////////////////// // set up gca direction cosines, width, height, depth defaults gca = GCAread(gca_name) ; if (gca == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read GCA from %s", Progname, gca_name) ; ///////////////////////////////////////////////////////////////////////// // weird way options and subject name are mixed here ///////////////////////////////////////////////////////// // first calculate mean //////////////////////////////////////////////////////// // going through the subject one at a time max_index = nsubjects+options ; nargs = 0 ; mri_in = NULL ; #ifdef HAVE_OPENMP subject_name = NULL ; sname = NULL ; t = 0 ; // counts = 0 ; would be private input = 0 ; transform = NULL ; tp1_name = tp2_name = NULL ; mri_tmp = mri_seg = NULL ; #pragma omp parallel for firstprivate(tp1_name, tp2_name, mri_in,mri_tmp, input, xform_name, transform, subjects_dir, force_inputs, conform, Progname, mri_seg, subject_name, s1_name, s2_name, sname, t, fname) shared(mri_inputs, transforms, mri_segs,argv) schedule(static,1) #endif for (i = 0 ; i < max_index ; i++) { subject_name = argv[3*i+1] ; tp1_name = argv[3*i+2] ; tp2_name = argv[3*i+3] ; sprintf(s1_name, "%s_%s.long.%s_base", subject_name, tp1_name, subject_name) ; sprintf(s2_name, "%s_%s.long.%s_base", subject_name, tp2_name, subject_name) ; ////////////////////////////////////////////////////////////// printf("***************************************" "************************************\n"); printf("processing subject %s, %d of %d (%s and %s)...\n", subject_name,i+1-nargs, nsubjects, s1_name,s2_name); for (t = 0 ; t < 2 ; t++) { sname = t == 0 ? s1_name : s2_name; // reading this subject segmentation sprintf(fname, "%s/%s/mri/%s", subjects_dir, sname, seg_dir) ; if (Gdiag & DIAG_SHOW && DIAG_VERBOSE_ON) fprintf(stderr, "Reading segmentation from %s...\n", fname) ; mri_seg = MRIread(fname) ; if (!mri_seg) ErrorExit(ERROR_NOFILE, "%s: could not read segmentation file %s", Progname, fname) ; if ((mri_seg->type != MRI_UCHAR) && (make_uchar != 0)) { MRI *mri_tmp ; mri_tmp = MRIchangeType(mri_seg, MRI_UCHAR, 0, 1,1); MRIfree(&mri_seg) ; mri_seg = mri_tmp ; } if (wmsa_fname) { MRI *mri_wmsa ; sprintf(fname, "%s/%s/mri/%s", subjects_dir, sname, wmsa_fname) ; printf("reading WMSA labels from %s...\n", fname) ; mri_wmsa = MRIread(fname) ; if (mri_wmsa == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read WMSA file %s", fname) ; MRIbinarize(mri_wmsa, mri_wmsa, 1, 0, WM_hypointensities) ; MRIcopyLabel(mri_wmsa, mri_seg, WM_hypointensities) ; lateralize_hypointensities(mri_seg) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON ) { char s[STRLEN] ; sprintf(s, "%s/%s/mri/seg_%s", subjects_dir, subject_name, wmsa_fname) ; MRIwrite(mri_seg, s) ; } } if (binarize) { int j ; for (j = 0 ; j < 256 ; j++) { if (j == binarize_in) MRIreplaceValues(mri_seg, mri_seg, j, binarize_out) ; else MRIreplaceValues(mri_seg, mri_seg, j, 0) ; } } if (insert_fname) { MRI *mri_insert ; sprintf(fname, "%s/%s/mri/%s", subjects_dir, subject_name, insert_fname) ; mri_insert = MRIread(fname) ; if (mri_insert == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read volume from %s for insertion", Progname, insert_fname) ; MRIbinarize(mri_insert, mri_insert, 1, 0, insert_label) ; MRIcopyLabel(mri_insert, mri_seg, insert_label) ; MRIfree(&mri_insert) ; } replaceLabels(mri_seg) ; MRIeraseBorderPlanes(mri_seg, 1) ; //////////////////////////////////////////////////////////// if (DIAG_VERBOSE_ON) fprintf(stderr, "Gather all input volumes for the subject %s.\n", subject_name); // inputs must be coregistered // note that inputs are T1, PD, ... per subject (same TE, TR, FA) for (input = 0 ; input < ninputs ; input++) { //////////// set the gca type ////////////////////////////// // is this T1/PD training? // how can we allow flash data training ??????? // currently checks the TE, TR, FA to be the same for all inputs // thus we cannot allow flash data training. //////////////////////////////////////////////////////////// sprintf(fname, "%s/%s/mri/%s", subjects_dir, sname,input_names[input]); if (DIAG_VERBOSE_ON) printf("reading co-registered input from %s...\n", fname) ; fprintf(stderr, " reading input %d: %s\n", input, fname); mri_tmp = MRIread(fname) ; if (!mri_tmp) ErrorExit (ERROR_NOFILE, "%s: could not read image from file %s", Progname, fname) ; // input check 1 if (getSliceDirection(mri_tmp) != MRI_CORONAL) { ErrorExit (ERROR_BADPARM, "%s: must be in coronal direction, but it is not\n", fname); } // input check 2 if (conform && (mri_tmp->xsize != 1 || mri_tmp->ysize != 1 || mri_tmp->zsize != 1)) { ErrorExit (ERROR_BADPARM, "%s: must have 1mm voxel size, but have (%f, %f, %f)\n", fname, mri_tmp->xsize, mri_tmp->ysize, mri_tmp->ysize); } // input check 3 is removed. now we can handle c_(ras) != 0 case // input check 4 if (i == 0) { TRs[input] = mri_tmp->tr ; FAs[input] = mri_tmp->flip_angle ; TEs[input] = mri_tmp->te ; } else if ((force_inputs == 0) && (!FEQUAL(TRs[input],mri_tmp->tr) || !FEQUAL(FAs[input],mri_tmp->flip_angle) || !FEQUAL(TEs[input], mri_tmp->te))) ErrorExit (ERROR_BADPARM, "%s: subject %s input volume %s: sequence parameters " "(%2.1f, %2.1f, %2.1f)" "don't match other inputs (%2.1f, %2.1f, %2.1f)", Progname, subject_name, fname, mri_tmp->tr, DEGREES(mri_tmp->flip_angle), mri_tmp->te, TRs[input], DEGREES(FAs[input]), TEs[input]) ; // first time do the following if (input == 0) { int nframes = ninputs ; /////////////////////////////////////////////////////////// mri_in = MRIallocSequence(mri_tmp->width, mri_tmp->height, mri_tmp->depth, mri_tmp->type, nframes) ; if (!mri_in) ErrorExit (ERROR_NOMEMORY, "%s: could not allocate input volume %dx%dx%dx%d", mri_tmp->width, mri_tmp->height, mri_tmp->depth,nframes) ; MRIcopyHeader(mri_tmp, mri_in) ; } // -mask option //////////////////////////////////////////// if (mask_fname) { MRI *mri_mask ; sprintf(fname, "%s/%s/mri/%s", subjects_dir, subject_name, mask_fname); printf("reading volume %s for masking...\n", fname) ; mri_mask = MRIread(fname) ; if (!mri_mask) ErrorExit(ERROR_NOFILE, "%s: could not open mask volume %s.\n", Progname, fname) ; MRImask(mri_tmp, mri_mask, mri_tmp, 0, 0) ; MRIfree(&mri_mask) ; } MRIcopyFrame(mri_tmp, mri_in, 0, input) ; MRIfree(&mri_tmp) ; }// end of inputs per subject ///////////////////////////////////////////////////////// // xform_name is given, then we can use the consistent c_(r,a,s) for gca ///////////////////////////////////////////////////////// if (xform_name) { // we read talairach.xfm which is a RAS-to-RAS sprintf(fname, "%s/%s/mri/transforms/%s", subjects_dir, sname, xform_name) ; if (Gdiag & DIAG_SHOW && DIAG_VERBOSE_ON) printf("INFO: reading transform file %s...\n", fname); if (!FileExists(fname)) { fprintf(stderr,"ERROR: cannot find transform file %s\n",fname); exit(1); } transform = TransformRead(fname); if (!transform) ErrorExit(ERROR_NOFILE, "%s: could not read transform from file %s", Progname, fname); // modify_transform(transform, mri_in, gca); // Here we do 2 things // 1. modify gca direction cosines to // that of the transform destination (both linear and non-linear) // 2. if ras-to-ras transform, // then change it to vox-to-vox transform (linear case) // modify transform to store inverse also TransformInvert(transform, mri_in) ; } else { // GCAreinit(mri_in, gca); // just use the input value, since dst = src volume transform = TransformAlloc(LINEAR_VOXEL_TO_VOXEL, NULL) ; } ///////////////////////////////////////////////////////// if (do_sanity_check) { // conduct a sanity check of particular labels, most importantly // hippocampus, that such labels do not exist in talairach coords // where they are known not to belong (indicating a bad manual edit) int errs = check(mri_seg, subjects_dir, subject_name); if (errs) { printf( "ERROR: mri_ca_train: possible bad training data! subject:\n" "\t%s/%s\n\n", subjects_dir, subject_name); fflush(stdout) ; sanity_check_badsubj_count++; } } mri_segs[i][t] = mri_seg ; mri_inputs[i][t] = mri_in ; transforms[i][t] = transform ; } } rf = train_rforest(mri_inputs, mri_segs, transforms, nsubjects, gca, &parms, wm_thresh,wmsa_whalf, 2) ; printf("writing random forest to %s\n", out_fname) ; if (RFwrite(rf, out_fname) != NO_ERROR) ErrorExit (ERROR_BADFILE, "%s: could not write rf to %s", Progname, out_fname) ; msec = TimerStop(&start) ; seconds = nint((float)msec/1000.0f) ; minutes = seconds / 60 ; seconds = seconds % 60 ; printf("classifier array training took %d minutes and %d seconds.\n", minutes, seconds) ; exit(0) ; return(0) ; }