Ejemplo n.º 1
0
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()  */
Ejemplo n.º 3
0
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) ;
}