Exemplo n.º 1
0
MRI *
MRIfindBrightNonWM(MRI *mri_T1, MRI *mri_wm)
{
    int     width, height, depth, x, y, z, nlabeled, nwhite,
            xk, yk, zk, xi, yi, zi;
    BUFTYPE val, wm ;
    MRI     *mri_labeled, *mri_tmp ;

    mri_labeled = MRIclone(mri_T1, NULL) ;
    width = mri_T1->width ;
    height = mri_T1->height ;
    depth = mri_T1->depth ;

    for (z = 0 ; z < depth ; z++)
    {
        for (y = 0 ; y < height ; y++)
        {
            for (x = 0 ; x < width ; x++)
            {
                val = MRIgetVoxVal(mri_T1, x, y, z, 0) ;
                wm = MRIgetVoxVal(mri_wm, x, y, z, 0) ;

                if (x == 110 && y == 125 && z == 172)  /* T1=148 */
                {
                    DiagBreak() ;
                }
                /* not white matter and bright (e.g. eye sockets) */
                if ((wm < WM_MIN_VAL) && (val > 125))
                {
                    nwhite = 0 ;
                    for (xk = -1 ; xk <= 1 ; xk++)
                    {
                        xi = mri_T1->xi[x+xk] ;
                        for (yk = -1 ; yk <= 1 ; yk++)
                        {
                            yi = mri_T1->yi[y+yk] ;
                            for (zk = -1 ; zk <= 1 ; zk++)
                            {
                                zi = mri_T1->zi[z+zk] ;
                                if (MRIgetVoxVal(mri_wm, xi, yi, zi, 0) >= WM_MIN_VAL)
                                {
                                    nwhite++ ;
                                }
                            }
                        }
                    }
#define MIN_WHITE  ((3*3*3-1)/2)
                    if (nwhite < MIN_WHITE)
                    {
                        MRIsetVoxVal(mri_labeled, x, y, z, 0, BRIGHT_LABEL) ;
                    }
                }
            }
        }
    }

    /* find all connected voxels that are above 115 */
    MRIdilateThreshLabel(mri_labeled, mri_T1, NULL, BRIGHT_LABEL, 10,115);
    MRIclose(mri_labeled, mri_labeled) ;

    /* expand once more to all neighboring voxels that are bright. At
       worst we will erase one voxel of white matter.
    */
    mri_tmp =
        MRIdilateThreshLabel(mri_labeled, mri_T1, NULL, BRIGHT_LABEL,1,100);
    MRIxor(mri_labeled, mri_tmp, mri_tmp, 1, 255) ;
    MRIreplaceValues(mri_tmp, mri_tmp, 1, BRIGHT_BORDER_LABEL) ;
    MRIunion(mri_tmp, mri_labeled, mri_labeled) ;
#if 0
    fprintf(stderr, "selectively smoothing volume....\n") ;
    MRIsoapBubbleLabel(mri_T1, mri_labeled, mri_T1, BRIGHT_LABEL, 200) ;
#endif
    if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
    {
        MRIwrite(mri_labeled, "label.mgh") ;
    }
    /*    MRIwrite(mri_tmp, "tmp.mgh") ;*/
    nlabeled = MRIvoxelsInLabel(mri_labeled, BRIGHT_LABEL) ;
    fprintf(stderr, "%d bright non-wm voxels segmented.\n", nlabeled) ;

    MRIfree(&mri_tmp) ;
    return(mri_labeled) ;
}
Exemplo n.º 2
0
MRI *
MRIfillBasalGanglia(MRI *mri_src, MRI *mri_dst)
{
    float  low_thresh, hi_thresh ;
    int    total_filled, depth, height, width, x, y, z,
           xi, yi, zi, xk, yk, zk, fill, val0, val, i ;
    MRI    *mri_bg ;
    Real   tx, ty, tz ;
    MRI_SEGMENTATION  *mriseg ;
    MRI_SEGMENT       *mseg ;
    float  dx_left, dx_right, dy, dz, dist_left, dist_right ;

    if (!mri_dst)
    {
        mri_dst = MRIcopy(mri_src, NULL) ;
    }
    mri_bg = MRIclone(mri_src, NULL) ;

    width = mri_src->width ;
    height = mri_src->height ;
    depth = mri_src->depth ;
    low_thresh = 85 ;
    hi_thresh =  105 ;
    total_filled = 0 ;
    for (z = 0 ; z < depth ; z++)
    {
        for (y = 0 ; y < height ; y++)
        {
            for (x = 0 ; x < width ; x++)
            {
                if (x == 152 && y == 117 && z == 132)  /* 93 */
                {
                    DiagBreak() ;
                }
                val0 = MRIgetVoxVal(mri_src, x, y, z, 0) ;
#if 0
                if (val0 >= low_thresh && val0 <= hi_thresh &&
                        MRIvox(mri_dst,x,y,z) < WM_MIN_VAL)
#else
                if (val0 >= 85 && val0 <= 105)
#endif
                {
#undef WHALF
#undef WSIZE
#define WSIZE   7
#define WHALF  ((WSIZE-1)/2)
                    fill = 1 ;
                    for (zk = -WHALF ; fill && zk <= WHALF ; zk++)
                    {
                        zi = mri_src->zi[z+zk] ;
                        for (yk = -WHALF ; fill && yk <= WHALF ; yk++)
                        {
                            yi = mri_src->yi[y+yk] ;
                            for (xk = -WHALF ; fill && xk <= WHALF ; xk++)
                            {
                                xi = mri_src->xi[x+xk] ;
                                val = MRIgetVoxVal(mri_src, xi, yi, zi, 0) ;
                                if (val < 85 || val > 110)
                                {
                                    fill = 0 ;  /* not homogeneous enough */
                                }
                            }
                        }
                    }
                }
                else
                {
                    fill = 0 ;
                }
                if (fill)
                {
                    total_filled++ ;
                }
                if (fill)
                {
                    MRIsetVoxVal(mri_bg, x, y, z, 0, BASAL_GANGLIA_FILL) ;
                }
            }
        }
    }

    MRIclose(mri_bg, mri_bg) ;  /* remove small holes */

    /* segment into connected components */
    mriseg = MRIsegment(mri_bg, 1, 255) ;
    fprintf(stderr, "segmenting thick gray regions: %d %d mm segments found\n",
            mriseg->nsegments, WSIZE) ;

    /* dilate into regions that are not on */
    for (i = 0 ; i < 2*WSIZE ; i++)
    {
        MRIsegmentDilateThreshold(mriseg, mri_src, mri_src, 80, 100) ;
    }

    /* fill basal ganglia components */
    MRIclear(mri_bg) ;
    for (total_filled = i = 0 ; i < mriseg->nsegments ; i++)
    {
#define TAL_BG_LEFT_X    -30
#define TAL_BG_RIGHT_X   30
#define TAL_BG_Y         5
#define TAL_BG_Z         5
#define MAX_DIST         25

        mseg = &mriseg->segments[i] ;
        MRIvoxelToTalairach(mri_src, mseg->cx, mseg->cy, mseg->cz,&tx, &ty,&tz);
        dx_left = tx - TAL_BG_LEFT_X ;
        dx_right = tx - TAL_BG_RIGHT_X ;
        dy = ty - TAL_BG_Y ;
        dz = tz - TAL_BG_Z ;
        dist_left = sqrt(dx_left*dx_left+dy*dy+dz*dz) ;
        dist_right = sqrt(dx_right*dx_right+dy*dy+dz*dz) ;
        if (dist_left > MAX_DIST && dist_right > MAX_DIST)
        {
            continue ;
        }
        fprintf(stderr, "filling segment %d with %d voxels\n\tc = "
                "(%2.1f,%2.1f,%2.1f) tal (%2.1f,%2.1f,%2.1f), dist %2.1f,%2.1f\n",
                i, mseg->nvoxels, mseg->cx, mseg->cy, mseg->cz,
                tx, ty, tz, dist_left, dist_right) ;
        MRIsegmentToImage(mri_src, mri_bg, mriseg, i) ;
        total_filled += mseg->nvoxels ;
    }

#if 1
    /*  MRIremoveIslands(mri_bg, mri_bg, 3, .56) ;*/
    MRIbinarize(mri_bg, mri_bg, WM_MIN_VAL, 0, BASAL_GANGLIA_FILL) ;
#endif
    MRIsegmentFree(&mriseg) ;

    MRIunion(mri_dst, mri_bg, mri_dst) ;
    MRIfree(&mri_bg) ;
    if (Gdiag & DIAG_SHOW)
    {
        fprintf(stderr, "%d basal ganglia points filled\n", total_filled);
    }

    return(mri_dst) ;
}
Exemplo n.º 3
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) ;
}