示例#1
0
static MRI *
add_interior_points(MRI *mri_src, MRI *mri_vals, float intensity_above,
                    float intensity_below, MRI_SURFACE *mris_white1,
                    MRI_SURFACE *mris_white2,
                    MRI *mri_aseg, MRI *mri_dst)
{
  int   x, y, z, ctrl, label, i ;
  float val ;
  MRI   *mri_core ;
  MRI   *mri_interior, *mri_tmp ;

  mri_interior = MRIclone(mri_src, NULL) ;
  MRISfillInterior(mris_white1, mri_src->xsize, mri_interior) ;
  mri_tmp = MRIclone(mri_src, NULL) ;
  MRISfillInterior(mris_white2, mri_src->xsize, mri_tmp) ;
  MRIcopyLabel(mri_tmp, mri_interior, 1) ;
  if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
  {
    MRIwrite(mri_interior, "i.mgz") ;
  }
  mri_core = MRIerode(mri_interior, NULL) ;
  for (i = 1 ; i < nint(1.0/mri_src->xsize) ; i++)
  {
    MRIcopy(mri_core, mri_tmp) ;
    MRIerode(mri_tmp, mri_core) ;
  }
  MRIfree(&mri_tmp) ;

  if (mri_aseg == NULL)
  {
    for (x = 0 ; x < mri_src->width ; x++)
      for (y = 0 ; y < mri_src->height ; y++)
        for (z = 0 ; z < mri_src->depth ; z++)
        {
          if (Gx == x && Gy == y && Gz == z)
          {
            DiagBreak() ;
          }
          ctrl = MRIgetVoxVal(mri_core, x, y, z, 0) ;
          if (ctrl > 0)
          {
            MRIsetVoxVal(mri_dst, x, y, z, 0, ctrl) ;
          }
        }
  }
  else
  {
    for (x = 0 ; x < mri_src->width ; x++)
      for (y = 0 ; y < mri_src->height ; y++)
        for (z = 0 ; z < mri_src->depth ; z++)
        {
          if (Gx == x && Gy == y && Gz == z)
          {
            DiagBreak() ;
          }
          ctrl = MRIgetVoxVal(mri_src, x, y, z, 0) ;
          if (ctrl == 0)  // add in some missed ones that are inside the surface
          {
            label = MRIgetVoxVal(mri_aseg, x, y, z, 0) ;

            if (IS_GM(label) || IS_WM(label))
            {
              val = MRIgetVoxVal(mri_vals, x, y, z, 0) ;
              if ((val >= 110-intensity_below && val <= 110 + intensity_above)&&
                  MRIgetVoxVal(mri_core, x, y, z, 0) > 0)
              {
                ctrl = 1 ;
              }
            }
          }
          MRIsetVoxVal(mri_dst, x, y, z, 0, ctrl) ;
        }
  }

  MRIfree(&mri_core) ;
  return(mri_dst) ;
}
static MRI *
edit_ventricular_unknowns(MRI *mri_in_labeled, MRI *mri_T1, MRI *mri_out_labeled) {
  int     label, x, y, z, xm1, xp1, ym1, yp1, zm1, zp1, lxp1, lxm1, lyp1, lym1, lzp1, lzm1, nchanged,
  l1 = 0, l2 = 0, change, i, total_changed, dwm, dhypo, dven, left ;
  MRI     *mri_in ;

  mri_in = MRIcopy(mri_in_labeled, NULL) ;
  mri_out_labeled = MRIcopy(mri_in_labeled, mri_out_labeled) ;

  total_changed = 0 ;

  /* first change unknowns near hypointensities to wm or hypo */
  do {
    nchanged = 0 ;
    for (x = 0 ; x < mri_T1->width ; x++) {
      for (y = 0 ; y < mri_T1->height ; y++) {
        for (z = 0 ; z < mri_T1->depth ; z++) {
          if (x == Gx && y == Gy && z == Gz)
            DiagBreak() ;
          change = 0 ;
          left = 0 ;
          label = MRIvox(mri_in, x, y, z) ;
          if ((IS_GM(label) == 0) && (IS_UNKNOWN(label) == 0))
            continue ;

          dhypo = distance_to_label(mri_in, WM_hypointensities, x, y, z, 0, 1, 0, 2) ; /* look inferior */
          if (dhypo > 2)
            dhypo = distance_to_label(mri_in, WM_hypointensities, x, y, z, 0, 0, -1, 2) ;  /* look inferior */
          if (dhypo > 2)
            dhypo = distance_to_label(mri_in, WM_hypointensities, x, y, z, 0, 0, 1, 2) ;  /* look anterior */
          if (dhypo > 2)
            dhypo = distance_to_label(mri_in, WM_hypointensities, x, y, z, 0, 0, -1, 2) ;  /* look inferior */
          if (dhypo > 2)
            continue ;

#define WM_DIST   4

          dwm = distance_to_label(mri_in, Left_Cerebral_White_Matter, x, y, z, 0, -1, 0, WM_DIST) ; /* superior */
          if (dwm > WM_DIST) {
            dwm = distance_to_label(mri_in, Right_Cerebral_White_Matter, x, y, z, 0, -1, 0, WM_DIST) ;
          } else
            left = 1 ;

          if (dwm > WM_DIST) /* not superior, look anterior */
          {
            dwm = distance_to_label(mri_in, Right_Cerebral_White_Matter, x, y, z, 0, 0, 1, WM_DIST) ;
            if (dwm > WM_DIST) {
              dwm = distance_to_label(mri_in, Left_Cerebral_White_Matter, x, y, z, 0, 0, 1, WM_DIST) ;
              if (dwm <= WM_DIST)
                left = 1 ;
            }
          }

          if (dwm > WM_DIST) /* not superior, or anterior look posterior */
          {
            dwm = distance_to_label(mri_in, Right_Cerebral_White_Matter, x, y, z, 0, 0, -1, WM_DIST) ;
            if (dwm > WM_DIST) {
              dwm = distance_to_label(mri_in, Left_Cerebral_White_Matter, x, y, z, 0, 0, -1, WM_DIST) ;
              if (dwm <= WM_DIST)
                left = 1 ;
            }
          }

          if (dwm > WM_DIST)    /* couldn't find wm anywhere (didn't look inferior), check for region of hypos */
          {
            dwm = distance_to_label(mri_in, WM_hypointensities, x, y, z, 0, -1, 0, WM_DIST) ;
            if (distance_to_label(mri_in, Left_Cerebral_White_Matter, x, y, z, 0, -1, 0, 30)  <= 30)
              left = 1 ;
          }
          if (dwm > WM_DIST)
            continue ;
          dven = distance_to_label(mri_in, left ? Left_Lateral_Ventricle : Right_Lateral_Ventricle, x, y, z, 0, 1, 0, 15) ;
          if (dven > 15) {
            dven = distance_to_label(mri_in, left ? Left_Lateral_Ventricle : Right_Lateral_Ventricle, x, y, z, 0, 0, -1, 3) ;
            if (dven > 3)
              distance_to_label(mri_in, left ? Left_Lateral_Ventricle : Right_Lateral_Ventricle, x, y, z, 0, 0, 1, 3) ;
            if (dven > 3)
              continue ;
          }

          nchanged++ ;
          mle_label(mri_T1, mri_out_labeled, x, y, z, 15, left ? Left_Cerebral_White_Matter : Right_Cerebral_White_Matter,
                    WM_hypointensities) ;
        }
      }
    }

    total_changed += nchanged ;
    MRIcopy(mri_out_labeled, mri_in) ;
  } while (nchanged > 0) ;

  for (i = 0 ; i < 2 ; i++) {
    for ( nchanged = x = 0 ; x < mri_T1->width ; x++) {
      for (y = 0 ; y < mri_T1->height ; y++) {
        for (z = 0 ; z < mri_T1->depth ; z++) {
          if (x == Gx && y == Gy && z == Gz)
            DiagBreak() ;
          change = 0 ;
          label = MRIvox(mri_in, x, y, z) ;
          if (IS_UNKNOWN(label) == 0)
            continue ;
          xm1 = mri_T1->xi[x-1] ;
          xp1 = mri_T1->xi[x+1] ;
          ym1 = mri_T1->yi[y-1] ;
          yp1 = mri_T1->yi[y+1] ;
          zm1 = mri_T1->zi[z-1] ;
          zp1 = mri_T1->zi[z+1] ;
          lxp1 = MRIvox(mri_in, xp1, y, z) ;
          lxm1 = MRIvox(mri_in, xm1, y, z) ;
          lyp1 = MRIvox(mri_in, x, yp1, z) ;
          lym1 = MRIvox(mri_in, x, ym1, z) ;
          lzp1 = MRIvox(mri_in, x, y, zp1) ;
          lzm1 = MRIvox(mri_in, x, y, zm1) ;
          /* if it has ventricle on one side and wm on the other, change it to wm or ventricle
            these are caused by slight discrepencies between the FreeSurfer ribbon and the
            CMA subcortical segs.
          */
          if ((IS_WMH(lxm1) && IS_LAT_VENT(lxp1)) ||
              (IS_WMH(lxp1) && IS_LAT_VENT(lxm1))) {
            change = 1 ;
            l1 = lxm1 ;
            l2 = lxp1 ;
          }
          if ((IS_WMH(lym1) && IS_LAT_VENT(lyp1)) ||
              (IS_WMH(lyp1) && IS_LAT_VENT(lym1))) {
            change = 1 ;
            l1 = lym1 ;
            l2 = lyp1 ;
          }
          if ((IS_WMH(lzm1) && IS_LAT_VENT(lzp1)) ||
              (IS_WMH(lzp1) && IS_LAT_VENT(lzm1))) {
            change = 1 ;
            l1 = lzm1 ;
            l2 = lzp1 ;
          }
          if (change) {
            nchanged++ ;
            mle_label(mri_T1, mri_out_labeled, x, y, z, 15, l1, l2) ;
          } else /* could be two unknowns in a row */
          {
            int yi, olabel, wm, un, ven ;
#define WLEN 4
            ven = un = wm = 0 ;
            change = 0 ;
            for (yi = y-1 ; yi >= MAX(0,y-WLEN) ; yi--) {
              olabel = MRIvox(mri_in, x, yi, z) ;
              /* should be only white matter and unkowns above it */
              if (IS_WMH(olabel)) {
                if (IS_WM(olabel))
                  l1 = olabel ;
                wm++ ;
              } else if (IS_UNKNOWN(olabel))
                un++ ;
              else
                change = -1 ;  /* something else there - don't change */
            }
            /* if there is some wm above and no other labels */
            if ((wm >= WLEN/2) && ((wm+un) >= (WLEN-1)) && change >= 0) {
              un = 0 ;
              for (yi = y+1 ; yi <= MIN(mri_in->height-1,y+WLEN) ; yi++) {
                olabel = MRIvox(mri_in, x, yi, z) ;
                /* should be only ventricle and unkowns below it */
                if (IS_LAT_VENT(olabel)) {
                  ven++ ;
                  l2 = olabel ;
                } else if (IS_UNKNOWN(olabel))
                  un++ ;
                else
                  change = -1 ;
              }
              if (change >= 0 && ((ven+un) >= WLEN) && (ven >= WLEN/2))
                change = 1 ;
              if (change > 0) {
                nchanged++ ;
                mle_label(mri_T1, mri_out_labeled, x, y, z, 15, l1, l2) ;
              }
            }
            if (change <= 0)  /* look in posterior/anterior direction. If everthing is wm and ven change it */
            {
              int zi ;

              change = wm = ven = un = 0 ;
              for (zi = z-WLEN ; zi <= z+WLEN ; zi++) {
                if (zi < 0 || zi >= mri_in->depth)
                  continue ;
                olabel = MRIvox(mri_in, x, y, zi) ;
                /* should be only white matter and unkowns above it */
                if (IS_WMH(olabel)) {
                  if (IS_WM(olabel))
                    l1 = olabel ;
                  wm++ ;
                } else if (IS_UNKNOWN(olabel))
                  un++ ;
                else if (IS_LAT_VENT(olabel))
                  ven++ ;
                else
                  change = -1 ;  /* something else there - don't change */
              }
              if (change >= 0 && ((ven+wm) >= WLEN) && (ven >= WLEN/2) && (wm >= WLEN/2))
                change = 1 ;
              if (change > 0) {
                nchanged++ ;
                mle_label(mri_T1, mri_out_labeled, x, y, z, 15, l1, l2) ;
              }
            }
            if (change <= 0)  /* look in medial/lateral direction. If everthing is wm and ven change it */
            {
              int xi ;

              change = wm = ven = un = 0 ;
              for (xi = x-WLEN ; xi <= x+WLEN ; xi++) {
                if (xi < 0 || xi >= mri_in->width)
                  continue ;
                olabel = MRIvox(mri_in, xi, y, z) ;
                /* should be only white matter and unkowns above it */
                if (IS_WMH(olabel)) {
                  if (IS_WM(olabel))
                    l1 = olabel ;
                  wm++ ;
                } else if (IS_UNKNOWN(olabel))
                  un++ ;
                else if (IS_LAT_VENT(olabel)) {
                  ven++ ;
                  l2 = olabel ;
                } else
                  change = -1 ;  /* something else there - don't change */
              }
              if (change >= 0 && ((ven+wm) >= WLEN) && (ven >= WLEN/2) && (wm >= WLEN/2))
                change = 1 ;
              if (change > 0) {
                nchanged++ ;
                mle_label(mri_T1, mri_out_labeled, x, y, z, 15, l1, l2) ;
              }
            }
          }
        }
      }
    }

    /* now relabel cortex that is between WM and hypointensity */
    for (x = 0 ; x < mri_T1->width ; x++) {
      for (y = 0 ; y < mri_T1->height ; y++) {
        for (z = 0 ; z < mri_T1->depth ; z++) {
          if (x == Gx && y == Gy && z == Gz)
            DiagBreak() ;
          change = 0 ;
          label = MRIvox(mri_in, x, y, z) ;
          if (IS_GM(label) == 0 && (IS_UNKNOWN(label) == 0))
            continue ;
          xm1 = mri_T1->xi[x-1] ;
          xp1 = mri_T1->xi[x+1] ;
          ym1 = mri_T1->yi[y-1] ;
          yp1 = mri_T1->yi[y+1] ;
          zm1 = mri_T1->zi[z-1] ;
          zp1 = mri_T1->zi[z+1] ;
          lxp1 = MRIvox(mri_in, xp1, y, z) ;
          lxm1 = MRIvox(mri_in, xm1, y, z) ;
          lyp1 = MRIvox(mri_in, x, yp1, z) ;
          lym1 = MRIvox(mri_in, x, ym1, z) ;
          lzp1 = MRIvox(mri_in, x, y, zp1) ;
          lzm1 = MRIvox(mri_in, x, y, zm1) ;
          if ((IS_WM(lxm1) && IS_HYPO(lxp1)) ||
              (IS_WM(lxp1) && IS_HYPO(lxm1))) {
            change = 1 ;
            l1 = lxm1 ;
            l2 = lxp1 ;
          }
          if ((IS_WM(lym1) && IS_HYPO(lyp1)) ||
              (IS_WM(lyp1) && IS_HYPO(lym1))) {
            change = 1 ;
            l1 = lym1 ;
            l2 = lyp1 ;
          }
          if ((IS_WM(lzm1) && IS_HYPO(lzp1)) ||
              (IS_WM(lzp1) && IS_HYPO(lzm1))) {
            change = 1 ;
            l1 = lzm1 ;
            l2 = lzp1 ;
          }


          if ((IS_HYPO(lxm1) && IS_HYPO(lxp1)) ||
              (IS_HYPO(lxp1) && IS_HYPO(lxm1))) {
            change = 1 ;
            l1 = lxm1 ;
            l2 = lxp1 ;
          }
          if ((IS_HYPO(lym1) && IS_HYPO(lyp1)) ||
              (IS_HYPO(lyp1) && IS_HYPO(lym1))) {
            change = 1 ;
            l1 = lym1 ;
            l2 = lyp1 ;
          }
          if ((IS_HYPO(lzm1) && IS_HYPO(lzp1)) ||
              (IS_HYPO(lzp1) && IS_HYPO(lzm1))) {
            change = 1 ;
            l1 = lzm1 ;
            l2 = lzp1 ;
          }
          if (change) {
            nchanged++ ;
            mle_label(mri_T1, mri_out_labeled, x, y, z, 15, l1, l2) ;
          }
        }
      }
    }
    MRIcopy(mri_out_labeled, mri_in) ;
    total_changed += nchanged ;
  }


  printf("%d unknown voxels changed to wm or ventricle\n", total_changed) ;
  MRIfree(&mri_in) ;
  return(mri_out_labeled) ;
}
static MRI *
edit_hippocampus(MRI *mri_in_labeled, MRI *mri_T1, MRI *mri_out_labeled) {
  int   width, height, depth, x, y, z, nchanged, dleft, label,
  dright, dpos, dant, dup, ddown, i, left, dgray, dhippo, dwhite, olabel ;
  MRI   *mri_tmp ;

  nchanged = 0 ;

  width = mri_T1->width ;
  height = mri_T1->height ;
  depth = mri_T1->depth ;

  mri_out_labeled = MRIcopy(mri_in_labeled, mri_out_labeled) ;

  /* change all gm within 2 mm of ventricle to wm */
  for (z = 0 ; z < depth ; z++) {
    for (y = 0 ; y < height ; y++) {
      for (x = 0 ; x < width ; x++) {
        if (x == Gx && y == Gy && z == Gz)
          DiagBreak() ;
        label = MRIvox(mri_out_labeled, x, y, z) ;
        if (IS_GM(label) == 0)
          continue ;
        left = label == Left_Cerebral_Cortex ;
        olabel = left ? Left_Lateral_Ventricle : Right_Lateral_Ventricle;
        if (MRIneighborsInWindow(mri_out_labeled, x, y, z, 5, olabel) >= 1) {
          nchanged++ ;
          MRIvox(mri_out_labeled, x, y, z) = left ? Left_Cerebral_White_Matter : Right_Cerebral_White_Matter;
        }
      }
    }
  }

  mri_tmp = MRIcopy(mri_out_labeled, NULL) ;

  /* change gray to hippocampus based on wm */
  for (i = 0 ; i < 3 ; i++) {
    for (z = 0 ; z < depth ; z++) {
      for (y = 0 ; y < height ; y++) {
        for (x = 0 ; x < width ; x++) {
          if (x == Gx && y == Gy && z == Gz)
            DiagBreak() ;
          label = MRIvox(mri_tmp, x, y, z) ;
          if (x == 160 && y == 127 && z == 118)
            DiagBreak() ;

          left = 0 ;
          switch (label) {
          case Left_Cerebral_White_Matter:
            left = 1 ;
          case Right_Cerebral_White_Matter:
            dgray = distance_to_label(mri_out_labeled,
                                      left ? Left_Cerebral_Cortex :
                                      Right_Cerebral_Cortex,
                                      x,y,z,0,1,0,3);

            dwhite = distance_to_label(mri_out_labeled,
                                       left ? Left_Cerebral_White_Matter :
                                       Right_Cerebral_White_Matter,
                                       x,y,z,0,-1,0,1);

            dhippo = distance_to_label(mri_out_labeled,
                                       left ? Left_Hippocampus :
                                       Right_Hippocampus,
                                       x,y,z,0,-1,0,3);
            /* change bright hippocampus that borders white matter to white matter */
            if (dgray <= 2 && dwhite <= 1 && dhippo <= 3) {
              mle_label(mri_T1, mri_tmp, x, y, z, 9,
                        left ? Left_Cerebral_Cortex : Right_Cerebral_Cortex,
                        left ? Left_Cerebral_White_Matter : Right_Cerebral_White_Matter) ;
            }
          case Left_Hippocampus:
            left = 1 ;
          case Right_Hippocampus:
            dgray = distance_to_label(mri_out_labeled,
                                      left ? Left_Cerebral_Cortex :
                                      Right_Cerebral_Cortex,
                                      x,y,z,0,1,0,3);

            dwhite = distance_to_label(mri_out_labeled,
                                       left ? Left_Cerebral_White_Matter :
                                       Right_Cerebral_White_Matter,
                                       x,y,z,0,1,0,1);

            dhippo = distance_to_label(mri_out_labeled,
                                       left ? Left_Hippocampus :
                                       Right_Hippocampus,
                                       x,y,z,0,-1,0,1);
            /* change bright hippocampus that borders white matter to white matter */
            if (dgray <= 3 && dwhite <= 1 && dhippo <= 1) {
              change_label(mri_T1, mri_tmp, x, y, z, 9, left) ;
            }
            break ;
          case Unknown: {
            int dhippo, dl, dr, dgray, dwhite ;

            if (x == 160 && y == 129 && z == 121)
              DiagBreak() ;

            /*
             if the current label is unknown, and there is white matter above
             and hippocampus above and gray matter below, change to gray matter.
            */
            dl = distance_to_label(mri_out_labeled,
                                   Left_Hippocampus,
                                   x,y,z,0,-1,0,4);
            dr = distance_to_label(mri_out_labeled,
                                   Right_Hippocampus,
                                   x,y,z,0,-1,0,4);
            if (dl > 4 && dr > 4) /* could be inferior to inf-lat-ven also */
            {
              dl = distance_to_label(mri_out_labeled,
                                     Left_Inf_Lat_Vent,
                                     x,y,z,0,-1,0,4);
              dr = distance_to_label(mri_out_labeled,
                                     Right_Inf_Lat_Vent,
                                     x,y,z,0,-1,0,4);
            }

            if (dl < dr) {
              left = 1 ;
              dhippo = dl ;
              dgray = distance_to_label(mri_out_labeled,
                                        Left_Cerebral_Cortex,
                                        x,y,z,0,1,0,2);
              dwhite = distance_to_label(mri_out_labeled,
                                         Left_Cerebral_White_Matter,
                                         x,y,z,0,-1,0,2);
            } else {
              left = 0 ;
              dhippo = dr ;
              dwhite = distance_to_label(mri_out_labeled,
                                         Right_Cerebral_White_Matter,
                                         x,y,z,0,-1,0,2);
              dgray = distance_to_label(mri_out_labeled,
                                        Right_Cerebral_Cortex,
                                        x,y,z,0,1,0,2);
            }
            if (dhippo <= 4 && dwhite <= 2 && dgray <= 2) {
              MRIvox(mri_tmp, x, y, z) =
                left ? Left_Cerebral_Cortex : Right_Cerebral_Cortex ;
              nchanged++ ;
              continue ;
            }

            break ;
          }
          case Left_Cerebral_Cortex:
            left = 1 ;
          case Right_Cerebral_Cortex:
            dup = distance_to_label(mri_out_labeled,
                                    left ?  Left_Hippocampus :
                                    Right_Hippocampus,x,y,z,0,-1,0,2);
            if (dup <= 1) {
              label = left ?
                      Left_Cerebral_White_Matter : Right_Cerebral_White_Matter;
              MRIvox(mri_tmp, x, y, z) = label ;
              nchanged++ ;
              continue ;
            }

            /*
              if the current label is gray, and there is white matter below
              and hippocampus above, change to hippocampus.
            */
            ddown = distance_to_label(mri_out_labeled,
                                      left ? Left_Cerebral_White_Matter :
                                      Right_Cerebral_White_Matter,
                                      x,y,z,0,1,0,3);
            dup = distance_to_label(mri_out_labeled,
                                    left ?  Left_Hippocampus :
                                    Right_Hippocampus,x,y,z,0,-1,0,2);
            if (dup <= 2 && ddown <= 2) {
              change_label(mri_T1, mri_tmp, x, y, z, 9, left) ;
              nchanged++ ;
              continue ;
            }

            /*
              if the current label is gray, and there is white matter above
              and hippocampus below, change to hippocampus.
            */
            ddown = distance_to_label(mri_out_labeled,
                                      left ? Left_Hippocampus :
                                      Right_Hippocampus,
                                      x,y,z,0,1,0,3);
            dup = distance_to_label(mri_out_labeled,
                                    left ?  Left_Cerebral_White_Matter :
                                    Right_Cerebral_White_Matter,
                                    x,y,z,0,-1,0,2);
            if (dup <= 2 && ddown <= 2) {
              change_label(mri_T1, mri_tmp, x, y, z, 9, left) ;
              nchanged++ ;
              continue ;
            }

            ddown = distance_to_label(mri_out_labeled,
                                      left ? Left_Hippocampus :
                                      Right_Hippocampus,
                                      x,y,z,0,1,0,3);
            dup = distance_to_label(mri_out_labeled,
                                    left ?  Left_Hippocampus :
                                    Right_Hippocampus,
                                    x,y,z,0,-1,0,2);
            if (dup <= 2 && ddown <= 2) {
              change_label(mri_T1, mri_tmp, x, y, z, 9, left) ;
              nchanged++ ;
              continue ;
            }

            dleft = distance_to_label(mri_out_labeled, left ?
                                      Left_Cerebral_White_Matter :
                                      Right_Cerebral_White_Matter,
                                      x,y,z,-1,0,0,3);
            dright = distance_to_label(mri_out_labeled, left ?
                                       Left_Cerebral_White_Matter :
                                       Right_Cerebral_White_Matter,
                                       x,y,z,1,0,0,3);
            dup = distance_to_label(mri_out_labeled,
                                    left ?  Left_Hippocampus :
                                    Right_Hippocampus,x,y,z,0,-1,0,2);
            if (dleft <= 2 && dright <= 2 && dup <= 1) {
              label = left ?
                      Left_Cerebral_White_Matter : Right_Cerebral_White_Matter;
              MRIvox(mri_tmp, x, y, z) = label ;
              nchanged++ ;
              continue ;
            }
            dright = distance_to_label(mri_out_labeled, left ?
                                       Left_Cerebral_White_Matter :
                                       Right_Cerebral_White_Matter,
                                       x,y,z,1,0,0,3);
            dleft = distance_to_label(mri_out_labeled, left ?
                                      Left_Hippocampus :
                                      Right_Hippocampus,
                                      x,y,z,-1,0,0,3);
            if (dleft <= 1 && dright <= 1) {
              change_label(mri_T1, mri_tmp, x, y, z, 9, left) ;
              nchanged++ ;
              continue ;
            }

            dleft = distance_to_label(mri_out_labeled, left ?
                                      Left_Cerebral_White_Matter :
                                      Right_Cerebral_White_Matter,
                                      x,y,z,-1,0,0,3);
            dright = distance_to_label(mri_out_labeled, left ?
                                       Left_Hippocampus :
                                       Right_Hippocampus,
                                       x,y,z,1,0,0,3);
            if (dleft <= 1 && dright <= 1) {
              change_label(mri_T1, mri_tmp, x, y, z, 9, left) ;
              nchanged++ ;
              continue ;
            }

            dright = distance_to_label(mri_out_labeled, left ?
                                       Left_Hippocampus :
                                       Right_Hippocampus,
                                       x,y,z,1,0,0,3);
            dleft = distance_to_label(mri_out_labeled, left ?
                                      Left_Hippocampus :
                                      Right_Hippocampus,
                                      x,y,z,-1,0,0,3);
            if (dleft <= 1 && dright <= 1) {
              label = left ?
                      Left_Hippocampus : Right_Hippocampus;
              MRIvox(mri_tmp, x, y, z) = label ;
              nchanged++ ;
              continue ;
            }

            dpos = distance_to_label(mri_out_labeled,
                                     Right_Cerebral_White_Matter,x,y,z,0,0,-1,3);
            dant = distance_to_label(mri_out_labeled,
                                     Right_Cerebral_White_Matter,x,y,z,0,0,1,3);


            /* if the current label is gray and the is white matter directly above,
              and hippocampus within 3 mm, then change label to MLE of either gray or
              white
            */

            if (x == 156 && y == 128 && z == 115)
              DiagBreak() ;
            dgray = distance_to_label(mri_out_labeled,
                                      left ? Left_Cerebral_Cortex :
                                      Right_Cerebral_Cortex,
                                      x,y,z,0,1,0,1);

            dwhite = distance_to_label(mri_out_labeled,
                                       left ? Left_Cerebral_White_Matter :
                                       Right_Cerebral_White_Matter,
                                       x,y,z,0,-1,0,1);

            dhippo = distance_to_label(mri_out_labeled,
                                       left ? Left_Hippocampus :
                                       Right_Hippocampus,
                                       x,y,z,0,-1,0,3);
            /* change bright hippocampus that borders white matter to white matter */
            if (dgray <= 1 && dwhite <= 1 && dhippo <= 3) {
              mle_label(mri_T1, mri_tmp, x, y, z, 9,
                        left ? Left_Cerebral_Cortex : Right_Cerebral_Cortex,
                        left ? Left_Cerebral_White_Matter : Right_Cerebral_White_Matter) ;
            }
            break ;
          default:
            break ;
          }
        }
      }
    }
    MRIcopy(mri_tmp, mri_out_labeled) ;
  }

  /* make gray matter that is superior to hippocampus into hippocampus */
  for (z = 0 ; z < depth ; z++) {
    for (y = 0 ; y < height ; y++) {
      for (x = 0 ; x < width ; x++) {
        int yi ;

        if (x == Gx && y == Gy && z == Gz)
          DiagBreak() ;
        label = MRIvox(mri_out_labeled, x, y, z) ;
        if (!IS_HIPPO(label))
          continue ;
        left = label == Left_Hippocampus ;

        /* search for first non-hippocampal voxel */
        for (yi = y-1 ; yi >= 0 ; yi--) {
          label = MRIvox(mri_out_labeled, x, yi, z) ;
          if (!IS_HIPPO(label))
            break ;
        }
        i = 0 ;
        while (IS_GM(label) && yi >= 0) {
          nchanged++ ;
          MRIvox(mri_out_labeled, x, yi, z) = left ? Left_Hippocampus : Right_Hippocampus;
          yi-- ;
          label = MRIvox(mri_out_labeled, x, yi, z) ;
          if (++i >= 4)
            break ;  /* don't let it go too far */
        }

      }
    }
  }


  /* go through and change wm labels that have hippo both above and below them to hippo */
  for (z = 0 ; z < depth ; z++) {
    for (y = 0 ; y < height ; y++) {
      for (x = 0 ; x < width ; x++) {
        if (x == Gx && y == Gy && z == Gz)
          DiagBreak() ;
        label = MRIvox(mri_tmp, x, y, z) ;
        if (x == 160 && y == 127 && z == 118)
          DiagBreak() ;

        if (!IS_WM(label))
          continue ;
        left = label == Left_Cerebral_White_Matter ;
        if (IS_HIPPO(MRIvox(mri_out_labeled, x, mri_out_labeled->yi[y-1], z)) &&
            IS_HIPPO(MRIvox(mri_out_labeled, x, mri_out_labeled->yi[y+1], z))) {
          nchanged++ ;
          MRIvox(mri_out_labeled, x, y, z) = left ? Left_Hippocampus : Right_Hippocampus;
        }
      }
    }
  }

  MRIfree(&mri_tmp) ;
  printf("%d hippocampal voxels changed.\n", nchanged) ;
  return(mri_out_labeled) ;
}
static MRI *
edit_lateral_ventricles(MRI *mri_in_labeled, MRI *mri_T1, MRI *mri_out_labeled) {
  int   width, height, depth, x, y, z, nchanged, label, total_changed,
  left, niter, change, dvent, dwhite, olabel ;
  MRI   *mri_tmp ;

  mri_out_labeled = MRIcopy(mri_in_labeled, mri_out_labeled) ;
  mri_tmp = MRIcopy(mri_out_labeled, NULL) ;

  width = mri_T1->width ;
  height = mri_T1->height ;
  depth = mri_T1->depth ;

  niter = total_changed = 0 ;
  do {
    nchanged = 0 ;

    /* change gray to wm if near amygdala */
    for (z = 0 ; z < depth ; z++) {
      for (y = 0 ; y < height ; y++) {
        for (x = 0 ; x < width ; x++) {
          if (x == Gx && y == Gy && z == Gz)
            DiagBreak() ;
          label = MRIvox(mri_tmp, x, y, z) ;

          change = left = 0 ;
          switch (label) {
          case Left_Inf_Lat_Vent:
            left = 1 ;
          case Right_Inf_Lat_Vent:
            dwhite = distance_to_label(mri_out_labeled,
                                       left ? Left_Cerebral_White_Matter :
                                       Right_Cerebral_White_Matter,
                                       x,y,z,0,1,0,3);
            dvent = distance_to_label(mri_out_labeled,
                                      left ? Left_Inf_Lat_Vent :
                                      Right_Inf_Lat_Vent,
                                      x,y,z,0,-1,0,3);
            if (dvent <= 1 && dwhite <= 1)  /* borders ventricle superior and wm inferior */
            {
              mle_label(mri_T1, mri_tmp, x, y, z, 9,
                        left ? Left_Inf_Lat_Vent : Right_Inf_Lat_Vent,
                        left ? Left_Cerebral_White_Matter : Right_Cerebral_White_Matter) ;
            }
            break ;
          case Unknown:
            if (neighborLabel(mri_tmp, x, y, z, 1, Left_Lateral_Ventricle) &&
                neighborLabel(mri_tmp, x, y, z,1,Left_Cerebral_White_Matter))
              change = left = 1 ;
            if (neighborLabel(mri_tmp, x, y, z, 1, Right_Lateral_Ventricle) &&
                neighborLabel(mri_tmp, x, y, z,1,Right_Cerebral_White_Matter))
              change = 1 ;

            if (change) {
#if 0
              label = left ?
                      Left_Cerebral_White_Matter : Right_Cerebral_White_Matter;
              /*              MRIvox(mri_tmp, x, y, z) = label ;*/
#else
              mle_label(mri_T1, mri_tmp, x, y, z, 9,
                        left ? Left_Lateral_Ventricle : Right_Lateral_Ventricle,
                        left ? Left_Cerebral_White_Matter : Right_Cerebral_White_Matter) ;
#endif
              nchanged++ ;
              continue ;
            }
          default:
            break ;
          }
        }
      }
    }
    MRIcopy(mri_tmp, mri_out_labeled) ;
    total_changed += nchanged ;
  } while ((nchanged > 0) && (++niter < 1)) ;

  /* change all gm within 2 mm of ventricle to wm */
  for (z = 0 ; z < depth ; z++) {
    for (y = 0 ; y < height ; y++) {
      for (x = 0 ; x < width ; x++) {
        if (x == Gx && y == Gy && z == Gz)
          DiagBreak() ;
        label = MRIvox(mri_out_labeled, x, y, z) ;
        if (IS_GM(label) == 0)
          continue ;
        left = label == Left_Cerebral_Cortex ;
        olabel = left ? Left_Lateral_Ventricle : Right_Lateral_Ventricle;
        if (MRIneighborsInWindow(mri_out_labeled, x, y, z, 5, olabel) >= 1) {
          total_changed++ ;
          MRIvox(mri_out_labeled, x, y, z) = left ? Left_Cerebral_White_Matter : Right_Cerebral_White_Matter;
        }
      }
    }
  }

#if 0
  /* change all unknown within 1 mm of ventricle and 1mm of  wm  to one of them */
  for (z = 0 ; z < depth ; z++) {
    for (y = 0 ; y < height ; y++) {
      for (x = 0 ; x < width ; x++) {
        if (x == Gx && y == Gy && z == Gz)
          DiagBreak() ;
        label = MRIvox(mri_out_labeled, x, y, z) ;
        if (IS_UNKNOWN(label) == 0)
          continue ;
        left = label == Left_Cerebral_Cortex ;
        olabel = left ? Left_Lateral_Ventricle : Right_Lateral_Ventricle;
        if (MRIneighborsInWindow(mri_out_labeled, x, y, z, 5, olabel) >= 1) {
          total_changed++ ;
          MRIvox(mri_out_labeled, x, y, z) = left ? Left_Cerebral_White_Matter : Right_Cerebral_White_Matter;
        }
      }
    }
  }
#endif


  MRIfree(&mri_tmp) ;
  printf("%d unknown voxels bordering ventricles changed to wm.\n",
         total_changed) ;
  return(mri_out_labeled) ;
}
static MRI *
edit_border_voxels(MRI *mri_in_labeled, MRI *mri_T1, MRI *mri_out_labeled) {
  int     label, x, y, z, xm1, xp1, ym1, yp1, zm1, zp1, lxp1, lxm1, lyp1, lym1, lzp1, lzm1, nchanged,
  change, olabel ;
  float   means[MAX_CMA_LABELS], xp1d, xm1d, yp1d, ym1d, zp1d, zm1d, val, ld ;
  MRI     *mri_tmp ;

  if (mri_in_labeled == mri_out_labeled) {
    mri_tmp = MRIcopy(mri_in_labeled, NULL) ;
    mri_in_labeled = mri_tmp;
  } else
    mri_tmp = NULL ;

  mri_out_labeled = MRIcopy(mri_in_labeled, mri_out_labeled) ;
  for (nchanged = x = 0 ; x < mri_T1->width ; x++) {
    for (y = 0 ; y < mri_T1->height ; y++) {
      for (z = 0 ; z < mri_T1->depth ; z++) {
        if (x == Gx && y == Gy && z == Gz)
          DiagBreak() ;
        change = 0 ;
        olabel = label = MRIvox(mri_in_labeled, x, y, z) ;
        if (IS_UNKNOWN(label))
          continue ;
        xm1 = mri_T1->xi[x-1] ;
        xp1 = mri_T1->xi[x+1] ;
        ym1 = mri_T1->yi[y-1] ;
        yp1 = mri_T1->yi[y+1] ;
        zm1 = mri_T1->zi[z-1] ;
        zp1 = mri_T1->zi[z+1] ;
        lxp1 = MRIvox(mri_in_labeled, xp1, y, z) ;
        lxm1 = MRIvox(mri_in_labeled, xm1, y, z) ;
        lyp1 = MRIvox(mri_in_labeled, x, yp1, z) ;
        lym1 = MRIvox(mri_in_labeled, x, ym1, z) ;
        lzp1 = MRIvox(mri_in_labeled, x, y, zp1) ;
        lzm1 = MRIvox(mri_in_labeled, x, y, zm1) ;
        if (label == lxm1 &&
            label == lxp1 &&
            label == lym1 &&
            label == lyp1 &&
            label == lzm1 &&
            label == lzp1)
          continue ;  /* it's not a border label */
        if (!(IS_WM(label) || IS_HIPPO(label) || IS_GM(label) || IS_UNKNOWN(label) || IS_LAT_VENT(label)))
          continue ;


        val = MRIgetVoxVal(mri_T1, x, y, z, 0) ;
        means[label] = label_mean(mri_T1, mri_in_labeled, x, y, z, 15, label) ;
        ld = fabs(means[label] - val) ;

        if (ld/means[label] < 0.1)
          continue ;

        ld *= 0.5 ;  /* bias towards keeping same label */


        if (lxm1 != label)
          means[lxm1] = label_mean(mri_T1, mri_in_labeled, x, y, z, 15, lxm1) ;
        if (lxp1 != label)
          means[lxp1] = label_mean(mri_T1, mri_in_labeled, x, y, z, 15, lxp1) ;
        if (lym1 != label)
          means[lym1] = label_mean(mri_T1, mri_in_labeled, x, y, z, 15, lym1) ;
        if (lyp1 != label)
          means[lyp1] = label_mean(mri_T1, mri_in_labeled, x, y, z, 15, lyp1) ;
        if (lzm1 != label)
          means[lzm1] = label_mean(mri_T1, mri_in_labeled, x, y, z, 15, lzm1) ;
        if (lzp1 != label)
          means[lzp1] = label_mean(mri_T1, mri_in_labeled, x, y, z, 15, lzp1) ;
        xp1d = fabs(means[lxp1] - val) ;
        if (xp1d < ld) {
          ld = xp1d ;
          olabel = lxp1 ;
        }
        xm1d = fabs(means[lxm1] - val) ;
        if (xm1d < ld) {
          ld = xm1d ;
          olabel = lxm1 ;
        }
        yp1d = fabs(means[lyp1] - val) ;
        if (yp1d < ld) {
          olabel = lyp1 ;
          ld = yp1d ;
        }
        ym1d = fabs(means[lym1] - val) ;
        if (ym1d < ld) {
          olabel = lym1 ;
          ld = ym1d ;
        }
        zp1d = fabs(means[lzp1] - val) ;
        if (zp1d < ld) {
          olabel = lzp1 ;
          ld = zp1d ;
        }
        zm1d = fabs(means[lzm1] - val) ;
        if (zp1d < ld) {
          olabel = lzp1 ;
          ld = zp1d ;
        }

        /* only let certain labels change */
        if (!(IS_WM(olabel) || IS_HIPPO(olabel) || IS_GM(olabel) || IS_UNKNOWN(olabel) || IS_LAT_VENT(olabel)))
          continue ;
        if ((IS_GM(label) && IS_HIPPO(olabel)) ||
            (IS_GM(olabel) && IS_HIPPO(label)))
          continue ;  /* don't change hippo to gm based on intensity - too similar */
        if ((label != olabel) && MRIneighborsInWindow(mri_in_labeled, x, y, z, 3, olabel) > 5) {
          nchanged++ ;
          MRIvox(mri_out_labeled, x, y, z) = olabel ;
        }
      }
    }
  }

  if (mri_tmp)
    MRIfree(&mri_tmp) ;
  printf("%d border voxels changed\n", nchanged) ;
  return(mri_out_labeled) ;
}