int insert_ribbon_into_aseg(MRI *mri_src_aseg, MRI *mri_aseg, MRI_SURFACE *mris_white, MRI_SURFACE *mris_pial, int hemi) { MRI *mri_ribbon, *mri_white ; int x, y, z, gm_label, wm_label, label, nbr_label, dont_change ; if (mri_src_aseg != mri_aseg) mri_aseg = MRIcopy(mri_src_aseg, mri_aseg) ; gm_label = hemi == LEFT_HEMISPHERE ? Left_Cerebral_Cortex : Right_Cerebral_Cortex ; wm_label = hemi == LEFT_HEMISPHERE ? Left_Cerebral_White_Matter : Right_Cerebral_White_Matter ; mri_white = MRIclone(mri_aseg, NULL) ; mri_ribbon = MRISribbon(mris_white, mris_pial, mri_aseg, NULL) ; MRISfillInterior(mris_white, mri_aseg->xsize, mri_white) ; for (x = 0 ; x < mri_aseg->width ; x++) for (y = 0 ; y < mri_aseg->height ; y++) for (z = 0 ; z < mri_aseg->depth ; z++) { if (x == Gx && y == Gy && z == Gz) DiagBreak() ; label = nint(MRIgetVoxVal(mri_aseg, x, y, z, 0)) ; if (nint(MRIgetVoxVal(mri_ribbon, x, y, z, 0)) == 255) // in ribbon, set to GM { if (IS_CORTEX(label) || IS_WHITE_CLASS(label)) { int xi, yi, zi, xk, yk, zk ; // check to make sure we are really in cortex for (dont_change = 0, xk = -1 ; xk <= 1 ; xk++) { xi = mri_aseg->xi[xk+x] ; for (yk = -1 ; yk <= 1 ; yk++) { yi = mri_aseg->yi[yk+y] ; for (zk = -1 ; zk <= 1 ; zk++) { zi = mri_aseg->zi[zk+z] ; nbr_label = (int)MRIgetVoxVal(mri_aseg, xi, yi, zi, 0) ; switch (nbr_label) { default: break ; case Left_Hippocampus: case Right_Hippocampus: case Left_Amygdala: case Right_Amygdala: case Left_VentralDC: case Right_VentralDC: case Brain_Stem: case Left_Lateral_Ventricle: case Right_Lateral_Ventricle: case Left_Inf_Lat_Vent: case Right_Inf_Lat_Vent: case Left_Thalamus_Proper: case Right_Thalamus_Proper: case Left_choroid_plexus: case Right_choroid_plexus: case CC_Posterior: case CC_Mid_Posterior: case CC_Central: case CC_Mid_Anterior: case CC_Anterior: dont_change = 1 ; break ; } } } } if (dont_change == 0) MRIsetVoxVal(mri_aseg, x, y, z, 0, gm_label) ; } } else // not in ribbon { if (MRIgetVoxVal(mri_white, x, y, z, 0) > 0) // inside white surface - disambiguate { if (label == gm_label) // gm inside white surface should be wm MRIsetVoxVal(mri_aseg, x, y, z, 0, wm_label) ; } else if (label == gm_label) // gm outside ribbon should be unknown MRIsetVoxVal(mri_aseg, x, y, z, 0, Unknown) ; } } if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_ribbon, "r.mgz") ; MRIwrite(mri_white, "w.mgz"); } MRIfree(&mri_ribbon) ; MRIfree(&mri_white) ; return(NO_ERROR) ; }
int main(int argc, char *argv[]) { MRI *mri_seg1, *mri_seg2; int nargs, ac; char **av; int width, height, depth, x, y, z, f, nframes; int v1, v2; int i, skipped; FILE *log_fp; int Volume_union[MAX_CLASSES]; int Volume_from1[MAX_CLASSES]; int Volume_from2[MAX_CLASSES]; int Volume_overlap[MAX_CLASSES]; int subcorvolume1, subcorvolume2; int subcorvolume_overlap; double mean1, std1, mean2, std2; float correct_ratio[MAX_CLASSES]; float correct_ratio2[MAX_CLASSES]; Progname = argv[0]; nargs = handle_version_option (argc, argv, "$Id: mri_compute_seg_overlap.c,v 1.18 2015/08/28 18:05:30 greve Exp $", "$Name: $"); if (nargs && argc - nargs == 1) { exit (0); } argc -= nargs; 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(1); } mri_seg1 = MRIread(argv[1]) ; if (!mri_seg1) ErrorExit(ERROR_BADPARM, "%s: could not read label volume1 %s", Progname, argv[1]) ; mri_seg2 = MRIread(argv[2]) ; if (!mri_seg2) ErrorExit(ERROR_BADPARM, "%s: could not read label volume2 %s", Progname, argv[2]) ; if ((mri_seg1->width != mri_seg2->width) || (mri_seg1->height != mri_seg2->height) || (mri_seg1->depth != mri_seg2->depth)) ErrorExit(ERROR_BADPARM, "%s: two input label volumes have different sizes \n", Progname); for (i=0; i < MAX_CLASSES; i++) { Volume_union[i] = 0; Volume_overlap[i] = 0; Volume_from1[i] = 0; Volume_from2[i] = 0; } width = mri_seg1->width ; height = mri_seg1->height ; depth = mri_seg1->depth ; nframes = mri_seg1->nframes ; if (nframes == 0) { nframes = 1; } subcorvolume_overlap = 0; subcorvolume1 = 0; subcorvolume2 = 0; for (f = 0 ; f < nframes ; f++) { for (z = 0 ; z < depth ; z++) { for (y = 0 ; y < height ; y++) { for (x = 0 ; x < width ; x++) { v1 = (int) MRIgetVoxVal(mri_seg1,x,y,z,f); v2 = (int) MRIgetVoxVal(mri_seg2,x,y,z,f); if (v1 > MAX_CLASS_NUM || v1 <= 0 || v2 > MAX_CLASS_NUM || v2 <= 0) continue; /* do not include these in the overall Dice coefficient calculations: Left/Right-Cerebral-White-Matter (labels 2 and 41), Left/Right-Cerebral-Cortex (labels 3 and 42), Left/Right-Accumbens-area (labels 26 and 58) Notice that these labels are not included in the 'if' checks: */ if (v1 == v2){ if (all_labels_flag) subcorvolume_overlap++; else if (isOverallDiceLabel(v1)) subcorvolume_overlap++; } if(all_labels_flag) subcorvolume1++; else if (isOverallDiceLabel(v1)) subcorvolume1++; if (all_labels_flag) subcorvolume2++; else if (isOverallDiceLabel(v2)) subcorvolume2++; Volume_from1[v1]++; Volume_from2[v2]++; if (v1 == v2) { Volume_overlap[v1]++; Volume_union[v1]++; } else { Volume_union[v1]++; Volume_union[v2]++; } } } } } for (i=0; i < MAX_CLASSES; i++) { correct_ratio[i] = (double)Volume_overlap[i]/((double)Volume_union[i] + 1e-10); correct_ratio2[i] = (double)Volume_overlap[i]*2.0/ ((double)Volume_from1[i] + (double)Volume_from2[i] + 1e-10); } printf("Jaccard Coefficients:\n"); mean1 = 0; std1 = 0; if (all_labels_flag) { num_all_labels = 0; for (i=0; i < MAX_CLASSES; i++) { if(correct_ratio[i] > 0.0) // This will include zero overlap areas as well (not just non-existing labels. If it is a problem, should flag existing labels.... { printf("correct ratio for label %d = %g\n",i, correct_ratio[i]); mean1 += correct_ratio[i]; std1 += correct_ratio[i] * correct_ratio[i]; num_all_labels++; } } mean1 /= num_all_labels; std1 /= num_all_labels; std1 = sqrt(std1 - mean1*mean1); printf("mean +/- std = %6.4f +/- %6.4f\n", mean1, std1); } else { for (skipped = i=0; i < num_labels; i++) { if (do_cortex == 0 && IS_CORTEX(labels_of_interest[i])) { skipped++ ; continue ; } if (do_wm == 0 && IS_WHITE_CLASS(labels_of_interest[i])) { skipped++ ; continue ; } printf("correct ratio for label %d = %g\n", labels_of_interest[i], correct_ratio[labels_of_interest[i]]); mean1 += correct_ratio[labels_of_interest[i]]; std1 += correct_ratio[labels_of_interest[i]] * correct_ratio[labels_of_interest[i]]; } mean1 /= (num_labels-skipped); std1 /= (num_labels-skipped); std1 = sqrt(std1 - mean1*mean1); printf("mean +/- std = %6.4f +/- %6.4f\n", mean1, std1); } if(table_fname) tablefp = fopen(table_fname, "w") ; printf("Dice Coefficients:\n"); // printf("ratio of overlap to volume of input1:\n"); mean2 = 0; std2 = 0; if (all_labels_flag) { num_all_labels = 0; for (i=0; i < MAX_CLASSES; i++) { if(correct_ratio2[i] > 0.0) // This will include zero overlap areas as well (not just non-existing labels. If it is a problem, should flag existing labels.... { all_labels_of_interest[num_all_labels] = i; if(ctab == NULL) printf("label %d = %g\n",i, correct_ratio2[i]); else printf("%4d %s %8.6lf\n",i, ctab->entries[i]->name,correct_ratio2[i]); mean2 += correct_ratio2[i]; std2 += correct_ratio2[i]*correct_ratio2[i]; num_all_labels++; } } mean2 /= num_all_labels; std2 /= num_all_labels; std2 = sqrt(std2 - mean2*mean2); printf("mean +/- std = %6.4f +/- %6.4f \n", mean2, std2); } else { for (skipped=i=0; i < num_labels; i++) { if (do_cortex == 0 && IS_CORTEX(labels_of_interest[i])) { skipped++ ; continue ; } if (do_wm == 0 && IS_WHITE_CLASS(labels_of_interest[i])) { skipped++ ; continue ; } int j = labels_of_interest[i]; double voldiff; voldiff = 100*(Volume_from1[j]-Volume_from2[j])/(0.5*((Volume_from1[j]+Volume_from2[j]))); if(ctab == NULL) printf("label %d = %g\n",j, correct_ratio2[j]); else printf("%4d %-30s %8.6lf %8.6lf %6d %6d %6d %9.4lf\n", j,ctab->entries[j]->name,correct_ratio[j],correct_ratio2[j], Volume_from1[j],Volume_from2[j],Volume_overlap[j],voldiff); if(table_fname) fprintf(tablefp,"%4d %-30s %8.6lf %8.6lf %6d %6d %6d %9.4lf\n", j,ctab->entries[j]->name,correct_ratio[j],correct_ratio2[j], Volume_from1[j],Volume_from2[j],Volume_overlap[j],voldiff); mean2 += correct_ratio2[labels_of_interest[i]]; std2 += correct_ratio2[labels_of_interest[i]] * correct_ratio2[labels_of_interest[i]]; } mean2 /= (num_labels-skipped); std2 /= (num_labels-skipped); std2 = sqrt(std2 - mean2*mean2); printf("mean +/- std = %6.4f +/- %6.4f \n", mean2, std2); } if(table_fname) fclose(tablefp); if (log_fname != NULL) { log_fp = fopen(log_fname, "a+") ; if (!log_fp) ErrorExit(ERROR_BADFILE, "%s: could not open %s for writing", Progname, log_fname) ; if (all_labels_flag) { for (i=0; i < num_all_labels; i++) { fprintf(log_fp, "%6.4f ", correct_ratio2[all_labels_of_interest[i]]); } } else { for (i=0; i < num_labels; i++) { if (do_cortex == 0 && IS_CORTEX(labels_of_interest[i])) continue ; if (do_wm == 0 && IS_WHITE_CLASS(labels_of_interest[i])) continue ; fprintf(log_fp, "%6.4f ", correct_ratio2[labels_of_interest[i]]); } } fprintf(log_fp, "%6.4f ", mean2); fprintf(log_fp, "%6.4f ", std2); fprintf(log_fp, "%6.4f \n", subcorvolume_overlap*2.0/(float)(subcorvolume1 + subcorvolume2)); fclose(log_fp); } if (mlog_fname != NULL) { log_fp = fopen(mlog_fname, "a+") ; if (!log_fp) ErrorExit(ERROR_BADFILE, "%s: could not open %s for writing", Progname, mlog_fname) ; fprintf(log_fp, "%6.4f \n", mean2); fclose(log_fp); } if (slog_fname != NULL) { log_fp = fopen(slog_fname, "a+") ; if (!log_fp) ErrorExit(ERROR_BADFILE, "%s: could not open %s for writing", Progname, slog_fname) ; fprintf(log_fp, "%6.4f \n", std2); fclose(log_fp); } if (olog_fname != NULL) { log_fp = fopen(olog_fname, "a+") ; if (!log_fp) ErrorExit(ERROR_BADFILE, "%s: could not open %s for writing", Progname, olog_fname) ; fprintf(log_fp, "%6.4f \n", subcorvolume_overlap*2.0/(float)(subcorvolume1 + subcorvolume2)); fclose(log_fp); } printf("Overall subcortical dice = %6.4f \n", subcorvolume_overlap*2.0/(float)(subcorvolume1 + subcorvolume2)); exit(0); } /* end main() */
static MRI * build_distance_by_intensity_histo(MRI *mri_norm, MRI *mri_dist, MRI *mri_aseg, double dist_spacing, double max_dist) { HISTOGRAM2D *h_dist_by_int ; int x, y, z, b1, b2, label ; float val, dist ; double total, unlikely, pval ; MRI *mri_pvals ; h_dist_by_int = HISTO2Dalloc((int)ceil(max_dist/dist_spacing), 256) ; HISTO2Dinit(h_dist_by_int, h_dist_by_int->nbins1, h_dist_by_int->nbins2, 0, MAX_DIST, 0, 255) ; for (x = 0 ; x < mri_dist->width ; x++) for (y = 0 ; y < mri_dist->height ; y++) for (z = 0 ; z < mri_dist->depth ; z++) { if (x == Gx && y == Gy && z == Gz) { DiagBreak() ; } dist = MRIgetVoxVal(mri_dist, x, y, z, 0) ; if (dist < 0 || dist > MAX_DIST) // in interior or too far away { continue ; } label = MRIgetVoxVal(mri_aseg, x, y, z, 0) ; if (IS_WHITE_CLASS(label) == 0 && IS_CORTEX(label) == 0 && label < MIN_CORTICAL_PARCELLATION) { continue ; } val = MRIgetVoxVal(mri_norm, x, y, z, 0) ; HISTO2DaddSample(h_dist_by_int, dist, val, 0, max_dist, 0, 255) ; } // normalize the counts for each distance for (b1 = 0 ; b1 < h_dist_by_int->nbins1 ; b1++) { for (total = 0.0, b2 = 0 ; b2 < h_dist_by_int->nbins2 ; b2++) { total += h_dist_by_int->counts[b1][b2] ; } if (total > 0) { unlikely = 1.0/(10*total) ; for (b2 = 0 ; b2 < h_dist_by_int->nbins2 ; b2++) { h_dist_by_int->counts[b1][b2]/=total ; if (DZERO(h_dist_by_int->counts[b1][b2])) { h_dist_by_int->counts[b1][b2] = unlikely ; } } } } mri_pvals = MRIclone(mri_dist, NULL) ; for (x = 0 ; x < mri_dist->width ; x++) for (y = 0 ; y < mri_dist->height ; y++) for (z = 0 ; z < mri_dist->depth ; z++) { if (x == Gx && y == Gy && z == Gz) { DiagBreak() ; } dist = MRIgetVoxVal(mri_dist, x, y, z, 0) ; if (dist < 0 || dist > MAX_DIST) // in interior { continue ; } label = MRIgetVoxVal(mri_aseg, x, y, z, 0) ; if (IS_WHITE_CLASS(label) == 0 && IS_CORTEX(label) == 0 && label < MIN_CORTICAL_PARCELLATION) { continue ; } val = MRIgetVoxVal(mri_norm, x, y, z, 0) ; pval = HISTO2DgetCount(h_dist_by_int, dist, val) ; if (pval > 0) { pval = -log10(pval) ; } else { pval = -10000 ; } MRIsetVoxVal(mri_pvals, x, y, z, 0, pval) ; } HISTO2Dfree(&h_dist_by_int) ; return(mri_pvals) ; }