Exemplo n.º 1
0
static int
most_frequent_label(MRI *mri_seg, MRI_SEGMENT *mseg)
{
  int  label_counts[MAX_CMA_LABELS], i, max_count, max_label, label ;

  memset(label_counts, 0, sizeof(label_counts)) ;
  for (i = max_count = max_label = 0 ; i < mseg->nvoxels ; i++)
  {
    label = MRIgetVoxVal(mri_seg, 
                         mseg->voxels[i].x, 
                         mseg->voxels[i].y, 
                         mseg->voxels[i].z, 0) ;
    if (IS_WM(label) == 0 && IS_UNKNOWN(label) == 0)
    {
      label_counts[label]++ ;
    }
  }
  for (i = max_count = max_label = 0 ; i < MAX_CMA_LABELS ; i++)
  {
    if (label_counts[i] > max_count)
    {
      max_count = label_counts[i] ;
      max_label = i ;
    }
  }
  return(max_label) ;
}
Exemplo n.º 2
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) ;
}
MRI *
MRImarkTemporalWM(MRI *mri_seg, MRI *mri_dst) {
  int   x, y, z, yi, found_other, found_gray, nchanged, label, i,
  width, height, depth, left ;
  MRI   *mri_tmp ;


  width = mri_seg->width ;
  height = mri_seg->height ;
  depth = mri_seg->depth ;

  if (!mri_dst)
    mri_dst = MRIclone(mri_seg, NULL) ;

  mri_tmp = MRIcopy(mri_dst, NULL) ;

  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_seg, x, y, z) ;
        if (!IS_WM(label))
          continue ;
        left =
          (label == Left_Cerebral_White_Matter) ||
          (label == Left_Temporal_Cerebral_White_Matter) ;

        for (found_other = found_gray = 0, i = 1 ; i <= 3 ; i++) {
          yi = mri_seg->yi[y+i] ;
          label = MRIvox(mri_seg, x, yi, z) ;
          if (IS_CORTEX(label))
            found_gray = 1 ;   /* gray matter inferior */

          yi = mri_seg->yi[y-i] ;
          label = MRIvox(mri_seg, x, yi, z) ;
          if (IS_HIPPO(label) || IS_AMYGDALA(label))
            found_other = 1 ;
        }
        if (found_other && found_gray) {
          MRIvox(mri_dst, x, y, z) = left ?
                                     Left_Cerebral_White_Matter:
                                     Right_Cerebral_White_Matter ;
          MRIvox(mri_seg, x, y, z) = left ?
                                     Left_Temporal_Cerebral_White_Matter:
                                     Right_Temporal_Cerebral_White_Matter ;
        }
      }
    }
  }

  do {
    nchanged = 0 ;
    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() ;
          if (MRIvox(mri_dst, x, y, z) > 0)
            continue ;
          label = MRIvox(mri_seg, x, y, z) ;
          if (!IS_WM(label))
            continue ;
          left =
            (label == Left_Cerebral_White_Matter) ||
            (label == Left_Temporal_Cerebral_White_Matter) ;

          for (found_other = found_gray = 0, i = 1 ; i <= 3 ; i++) {
            yi = mri_seg->yi[y+i] ;
            label = MRIvox(mri_seg, x, yi, z) ;
            if (IS_CORTEX(label))
              found_gray = 1 ;   /* gray matter inferior */

            yi = mri_seg->yi[y-i] ;  /* lateral ventricle superior */
            label = MRIvox(mri_seg, x, yi, z) ;
            if (IS_LAT_VENT(label))
              found_other = 1 ;
          }
          if (found_other && found_gray && MRIneighborsOn(mri_dst, x, y,z,1)>0) {
            nchanged++ ;
            MRIvox(mri_dst, x, y, z) = left ?
                                       Left_Cerebral_White_Matter :
                                       Right_Cerebral_White_Matter ;
            MRIvox(mri_seg, x, y, z) = left ?
                                       Left_Temporal_Cerebral_White_Matter :
                                       Right_Temporal_Cerebral_White_Matter ;
          }
        }
      }
    }
  } while (nchanged > 0) ;

  for (i = 0 ; i < 3 ; i++) {
    MRIcopy(mri_dst, mri_tmp) ;
    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_seg, x, y, z) ;
          if (!IS_WM(label) || (MRIvox(mri_dst, x, y, z) > 0))
            continue ;
          left =
            (label == Left_Cerebral_White_Matter) ||
            (label == Left_Temporal_Cerebral_White_Matter) ;

          if (MRIneighborsOn(mri_dst, x, y,z, 1)>= 2) {
            nchanged++ ;
            MRIvox(mri_tmp, x, y, z) = left ?
                                       Left_Cerebral_White_Matter :
                                       Right_Cerebral_White_Matter ;
            MRIvox(mri_seg, x, y, z) = left ?
                                       Left_Temporal_Cerebral_White_Matter :
                                       Right_Temporal_Cerebral_White_Matter ;
          }
        }
      }
    }
    MRIcopy(mri_tmp, mri_dst) ;
  }
  /* now dilate twice to get stray voxels and a bit of main temporal lobe */
  for (i = 0 ; i < 2 ; i++) {
    MRIcopy(mri_dst, mri_tmp) ;
    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_seg, x, y, z) ;
          if (!IS_WM(label) || (MRIvox(mri_dst, x, y, z) > 0))
            continue ;
          left =
            (label == Left_Cerebral_White_Matter) ||
            (label == Left_Temporal_Cerebral_White_Matter) ;

          if (MRIneighborsOn(mri_dst, x, y,z, 1)>= 1) {
            nchanged++ ;
            MRIvox(mri_tmp, x, y, z) = left ?
                                       Left_Cerebral_White_Matter :
                                       Right_Cerebral_White_Matter ;
            MRIvox(mri_seg, x, y, z) = left ?
                                       Left_Temporal_Cerebral_White_Matter :
                                       Right_Temporal_Cerebral_White_Matter ;
          }
        }
      }
    }
    MRIcopy(mri_tmp, mri_dst) ;
  }

  MRIfree(&mri_tmp) ;
  return(mri_dst) ;
}
Exemplo n.º 4
0
int
FCDcomputeThicknessLabels(FCD_DATA *fcd,
                          double thickness_thresh,
                          double sigma,
                          int size_thresh)
{
  MRI    *mri_lh, *mri_rh, *mri_lh_diff, *mri_rh_diff ;
  int    niter, vno, s ;
  MRI_SEGMENTATION *mriseg ;

  fcdFreeLabels(fcd) ;  // free old ones if they exist
  niter = SIGMA_TO_SURFACE_SMOOTH_STEPS(sigma) ;

  // do LH
  mri_lh = MRIclone(fcd->lh_thickness_on_lh, NULL) ;
  mri_rh = MRIclone(fcd->lh_thickness_on_lh, NULL) ;

  exec_progress_callback(1, 8, 0, 1) ;
  MRISwriteFrameToValues(fcd->mris_lh, fcd->lh_thickness_on_lh, 0) ;
  MRISaverageVals(fcd->mris_lh, niter) ;
  MRISreadFrameFromValues(fcd->mris_lh, mri_lh, 0) ;

  exec_progress_callback(2, 8, 0, 1) ;
  MRISwriteFrameToValues(fcd->mris_lh, fcd->rh_thickness_on_lh, 0) ;
  MRISaverageVals(fcd->mris_lh, niter) ;
  MRISreadFrameFromValues(fcd->mris_lh, mri_rh, 0) ;
  mri_lh_diff = MRIsubtract(mri_lh, mri_rh, NULL) ;  // lh minus rh on lh
  MRIfree(&mri_lh);
  MRIfree(&mri_rh) ;

  // do RH
  mri_lh = MRIclone(fcd->lh_thickness_on_rh, NULL) ;
  mri_rh = MRIclone(fcd->lh_thickness_on_rh, NULL) ;

  exec_progress_callback(3, 8, 0, 1) ;
  MRISwriteFrameToValues(fcd->mris_rh, fcd->lh_thickness_on_rh, 0) ;
  MRISaverageVals(fcd->mris_rh, niter) ;
  MRISreadFrameFromValues(fcd->mris_rh, mri_lh, 0) ;

  exec_progress_callback(4, 8, 0, 1) ;
  MRISwriteFrameToValues(fcd->mris_rh, fcd->rh_thickness_on_rh, 0) ;
  MRISaverageVals(fcd->mris_rh, niter) ;
  MRISreadFrameFromValues(fcd->mris_rh, mri_rh, 0) ;
  mri_rh_diff = MRIsubtract(mri_rh, mri_lh, NULL) ;  // lh minus rh on rh
  MRIfree(&mri_lh);
  MRIfree(&mri_rh) ;

  MRIclear(fcd->mri_thickness_increase) ;
  MRIclear(fcd->mri_thickness_decrease) ;
  exec_progress_callback(5, 8, 0, 1) ;

  // process left hemisphere
#if 1
#ifdef HAVE_OPENMP
#pragma omp parallel for shared(fcd, mri_lh_diff, Gdiag_no, thickness_thresh) schedule(static,1)
#endif
#endif
  for (vno = 0 ; vno < fcd->mris_lh->nvertices ; vno++)
  {
    double d ;
    float val, val2, thickness;
    int base_label ;
    VERTEX *v ;

    v = &fcd->mris_lh->vertices[vno] ;
    if (v->ripflag)
    {
      continue ;
    }
    thickness = MRIgetVoxVal(fcd->lh_thickness_on_lh, vno, 0, 0, 0) ;
    if (vno == Gdiag_no)
    {
      DiagBreak() ;
    }
    val = MRIgetVoxVal(mri_lh_diff, vno, 0, 0, 0) ;
    if (fabs(val) < thickness_thresh)
    {
      continue ;
    }

    for (d = 0, base_label = 0 ; d < thickness ; d += 0.25)
    {
      double xv, yv, zv;
      double xs = v->x+d*v->nx ;
      double ys = v->y+d*v->ny ;
      double zs = v->z+d*v->nz ;
      MRISsurfaceRASToVoxel(fcd->mris_lh, 
                            fcd->mri_thickness_increase, 
                            xs, ys, zs, 
                            &xv, &yv, &zv) ;
      int xvi = nint(xv) ;
      int yvi = nint(yv) ;
      int zvi = nint(zv) ;
      int label = MRIgetVoxVal(fcd->mri_aparc, xvi, yvi, zvi, 0) ;
      if (IS_WM(label) == 0 && 
          label >= MIN_CORTICAL_PARCELLATION && 
          label != ctx_lh_unknown)
      {
        if (label != base_label)
        {
          if (base_label)
          {
            break ;
          }
        }
        else
        {
          base_label = label ;
        }
        if (val >= 0)
        {
          val2 = MRIgetVoxVal(fcd->mri_thickness_increase, xvi, yvi, zvi, 0) ;
          // check another thread already populated this voxel
          if (val > val2)
          {
            MRIsetVoxVal(fcd->mri_thickness_increase, xvi, yvi, zvi, 0, val) ;
          }
        }
        else
        {
          val2 = MRIgetVoxVal(fcd->mri_thickness_decrease, xvi, yvi, zvi, 0) ;
          // check if another thread already populated this voxel
          if (val < val2)
          {
            MRIsetVoxVal(fcd->mri_thickness_decrease, xvi, yvi, zvi, 0, val) ;
          }
        }
      }
    }
  }

  exec_progress_callback(6, 8, 0, 1) ;

  // now do right hemisphere
#if 1
#ifdef HAVE_OPENMP
  #pragma omp parallel for shared(fcd, mri_rh_diff, Gdiag_no, thickness_thresh) schedule(static,1)
#endif
#endif
  for (vno = 0 ; vno < fcd->mris_rh->nvertices ; vno++)
  {
    double d  ;
    float val, val2, thickness;
    int base_label ;
    VERTEX *v ;

    v = &fcd->mris_rh->vertices[vno] ;
    if (v->ripflag)
    {
      continue ;
    }
    if (vno == Gdiag_no)
    {
      DiagBreak() ;
    }
    val = MRIgetVoxVal(mri_rh_diff, vno, 0, 0, 0) ;
    if (fabs(val) < thickness_thresh)
    {
      continue ;
    }
    thickness = MRIgetVoxVal(fcd->rh_thickness_on_rh, vno, 0, 0, 0) ;

    for (d = 0, base_label = 0; d < thickness ; d += 0.25)
    {
      double xv, yv, zv;
      double xs = v->x+d*v->nx ;
      double ys = v->y+d*v->ny ;
      double zs = v->z+d*v->nz ;
      MRISsurfaceRASToVoxel(fcd->mris_rh, 
                            fcd->mri_thickness_increase,
                            xs, ys, zs,
                            &xv, &yv, &zv) ;
      int xvi = nint(xv) ;
      int yvi = nint(yv) ;
      int zvi = nint(zv) ;
      int label = MRIgetVoxVal(fcd->mri_aparc, xvi, yvi, zvi, 0) ;
      if (IS_WM(label) == 0 && 
          label >= MIN_CORTICAL_PARCELLATION && 
          label != ctx_rh_unknown)
      {
        if (label != base_label)
        {
          if (base_label)
          {
            break ;
          }
        }
        else
        {
          base_label = label ;
        }

        if (val >= 0)
        {
          val2 = MRIgetVoxVal(fcd->mri_thickness_increase, xvi, yvi, zvi, 0) ;
          if (val > val2)
          {
            MRIsetVoxVal(fcd->mri_thickness_increase, xvi, yvi, zvi, 0, val) ;
          }
        }
        else
        {
          val2 = MRIgetVoxVal(fcd->mri_thickness_decrease, xvi, yvi, zvi, 0) ;
          if (val < val2)
          {
            MRIsetVoxVal(fcd->mri_thickness_decrease, xvi, yvi, zvi, 0, val) ;
          }
        }
      }
    }
  }

  exec_progress_callback(7, 8, 0, 1) ;
  mriseg = MRIsegment(fcd->mri_thickness_increase, thickness_thresh, 1e10) ;
  MRIeraseSmallSegments(mriseg, fcd->mri_thickness_increase, thickness_thresh) ;
  MRIsegmentFree(&mriseg) ;
  MRIclose(fcd->mri_thickness_increase, fcd->mri_thickness_increase) ;
  mriseg = MRIsegment(fcd->mri_thickness_increase, thickness_thresh, 1e10) ;
  MRIremoveSmallSegments(mriseg, size_thresh) ;
  printf("segmenting volume at threshold %2.1f with %d "
         "smoothing iters yields %d segments\n",
         thickness_thresh, niter,mriseg->nsegments) ;
  fflush(stdout) ;

  exec_progress_callback(8, 8, 0, 1) ;
  fcd->nlabels = mriseg->nsegments ;
  for (s = 0 ; s < mriseg->nsegments ; s++)
  {
    int label ;

    fcd->labels[s] = MRIsegmentToLabel(mriseg, fcd->mri_thickness_increase, s) ;
    label = most_frequent_label(fcd->mri_aparc, &mriseg->segments[s]) ;
    strcpy(fcd->labels[s]->name, cma_label_to_name(label)) ;
  }
  sort_labels(fcd) ;

  MRIadd(fcd->mri_thickness_increase, fcd->mri_thickness_decrease, fcd->mri_thickness_difference);

  for (s = 0 ; s < mriseg->nsegments ; s++)
  {
    printf("%s: %2.3fmm\n", fcd->label_names[s], fcd->labels[s]->avg_stat) ;
    fflush(stdout) ;
  }
  MRIfree(&mri_lh_diff) ;
  MRIfree(&mri_rh_diff) ;
  MRIsegmentFree(&mriseg) ;

  return(fcd->nlabels) ;
}
Exemplo n.º 5
0
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) ;
}
Exemplo n.º 6
0
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) ;
}
Exemplo n.º 7
0
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) ;
}