Пример #1
0
/*-----------------------------------------------------
  Parameters:

  Returns value:

  Description
  ------------------------------------------------------*/
int
MRIsegmentDilate(MRI_SEGMENTATION *mriseg, MRI *mri)
{
  int         x, y, z, xk, yk, zk, xi, yi, zi, segno, v, nvox ;
  MRI_SEGMENT *mseg ;
  MRI         *mri_segments ;
  float       voxel_size ;

  voxel_size = mri->xsize * mri->ysize * mri->zsize ;

  mri_segments = MRIclone(mri, NULL) ;

  /* build image of all other segments to prevent dilation from
     expanding into other segments */
  for (segno = 0 ; segno < mriseg->nsegments ; segno++)
    MRIsegmentToImage(mri, mri_segments, mriseg, segno) ;

  for (segno = 0 ; segno < mriseg->nsegments ; segno++)
  {
    mseg = &mriseg->segments[segno] ;

    nvox = mseg->nvoxels ;
    for (v = 0 ; v < nvox ; v++)
    {
      x = mseg->voxels[v].x ;
      y = mseg->voxels[v].y ;
      z = mseg->voxels[v].z ;

      for (xk = -1 ; xk <= 1 ; xk++)
      {
        xi = mri->xi[x+xk] ;
        for (yk = -1 ; yk <= 1 ; yk++)
        {
          yi = mri->yi[y+yk] ;
          for (zk = -1 ; zk <= 1 ; zk++)
          {
            if ((fabs(xk) + fabs(yk) + fabs(zk)) != 1)
              continue ;
            zi = mri->zi[z+zk] ;
            if (MRIgetVoxVal(mri, xi, yi, zi,0) &&
                !MRIgetVoxVal(mri_segments,xi,yi,zi,0))
            {
              if (mseg->nvoxels >= mseg->max_voxels)
              {
                if (mriSegmentReallocateVoxels
                    (mriseg, segno,
                     mseg->max_voxels*VOX_INCREASE)
                    != NO_ERROR)
                {
                  /*              MRIsegmentFree(&mseg) ;*/
                  return(Gerror) ;
                }
              }
              mseg->voxels[mseg->nvoxels].x = xi ;
              mseg->voxels[mseg->nvoxels].y = yi ;
              mseg->voxels[mseg->nvoxels].z = zi ;
              MRIsetVoxVal(mri_segments,xi,yi,zi, 0, MRIgetVoxVal(mri, xi, yi, zi,0)) ;
              mseg->nvoxels++ ;
              mseg->area += voxel_size ;
            }
          }
        }
      }
    }
  }
  MRIfree(&mri_segments) ;
  return(NO_ERROR) ;
}
Пример #2
0
MRI *
MRIfillVentricles(MRI *mri_src, MRI *mri_dst)
{
    int     width, height, depth, x, y, z, xk, yk, xi, yi, nfilled, total, s ;
    MRI     *mri_filled, *mri_ventricles = NULL ;
    MRI_SEGMENTATION *mriseg ;
    MRI_SEGMENT      *mseg ;
    Real    xt, yt, zt ;

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

    width = mri_src->width ;
    height = mri_src->height ;
    depth = mri_src->depth ;

    MRIcopy(mri_src, mri_dst) ;
    mri_filled = MRIcopy(mri_src, NULL) ;

    MRIreplaceValues(mri_filled, mri_filled, VENTRICLE_FILL,
                     VENTRICLE_FILL-1) ;

    /* first fill each coronal slice starting from a background seed */
    for (z = 0 ; z < depth ; z++)
    {
        total = 0 ;
        do
        {
            nfilled = 0 ;
            MRIsetVoxVal(mri_filled, 0, 0, z, 0, VENTRICLE_FILL) ;
            for (y = 0 ; y < height ; y++)
            {
                for (x = 0 ; x < width ; x++)
                {
                    if (MRIgetVoxVal(mri_filled, x, y, z, 0) == VENTRICLE_FILL)
                    {
                        for (yk = -1 ; yk <= 1 ; yk++)
                        {
                            yi = mri_src->yi[y+yk] ;
                            for (xk = -1 ; xk <= 1 ; xk++)
                            {
                                xi = mri_src->xi[x+xk] ;
                                if (!MRIgetVoxVal(mri_filled, xi, yi, z, 0))
                                {
                                    nfilled++ ;
                                    MRIsetVoxVal(mri_filled, xi, yi, z, 0, VENTRICLE_FILL) ;
                                }
                            }
                        }
                    }
                }
            }
            total += nfilled ;
        }
        while (nfilled > 0) ;
    }

    MRIcomplement(mri_filled, mri_filled) ;
    MRIreplaceValues(mri_filled, mri_filled, 1, VENTRICLE_FILL) ;
    mriseg = MRIsegment(mri_filled, 1, 255) ;
    fprintf(stderr, "%d segments found...\n", mriseg->nsegments) ;
    if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
    {
        MRIwrite(mri_filled, "exterior_filled.mgh") ;
    }
    for (s = 0 ; s < mriseg->nsegments ; s++)
    {
        mseg = &mriseg->segments[s] ;
        if (mseg->nvoxels < 100 ||
                mseg->z1-mseg->z0 < 7)
        {
            continue ;
        }
        MRIvoxelToTalairach(mri_src, mseg->cx, mseg->cy, mseg->cz, &xt, &yt, &zt);
        fprintf(stderr, "added segment %d, nvox=%d, bbox [%d:%d, %d:%d, %d:%d]\n"
                "\tc = %2.1f, %2.1f, %2.1f (tal = %2.1f, %2.1f, %2.1f)\n",
                s, mseg->nvoxels, mseg->x0, mseg->x1, mseg->y0,mseg->y1,mseg->z0,
                mseg->z1, mseg->cx, mseg->cy, mseg->cz, xt, yt, zt) ;
        mri_ventricles = MRIsegmentToImage(mri_filled, mri_ventricles, mriseg, s) ;
    }

    MRIfree(&mri_filled) ;
    MRIsegmentFree(&mriseg) ;

    /* remove voxels close to the midline so that the cc can still be found */
    for (z = 0 ; z < depth ; z++)
    {
        for (y = 0 ; y < height ; y++)
        {
            for (x = 0 ; x < width ; x++)
            {
                MRIvoxelToTalairach(mri_src, x, y, z, &xt, &yt, &zt);
                if (fabs(xt) < 5)
                {
                    MRIsetVoxVal(mri_ventricles, x, y, z, 0, 0) ;
                }
            }
        }
    }

    if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
    {
        MRIwrite(mri_ventricles, "ventricles.mgh") ;
    }
    MRIunion(mri_ventricles, mri_dst, mri_dst) ;

    MRIfree(&mri_ventricles) ;
    return(mri_dst) ;
}
Пример #3
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) ;
}
Пример #4
0
int
main(int argc, char *argv[]) {
  char          **av, fname[STRLEN], *T1_fname, *PD_fname, *output_dir, *mdir ;
  int           ac, nargs, msec, s ;
  MRI_SURFACE   *mris ;
  MRI           *mri_flash1, *mri_flash2, *mri_masked, *mri_masked_smooth, *mri_kernel,
  *mri_mean, *mri_dif, *mri_binary, *mri_distance ;
  MRI *mri_smooth, *mri_grad, *mri_inner ;
  struct timeb  then ;
  double        l_spring ;
  MRI_SEGMENTATION *mriseg ;


  /* rkt: check for and handle version tag */
  nargs = handle_version_option (argc, argv, "$Id: mris_AA_shrinkwrap.c,v 1.5 2011/03/02 00:04:34 nicks Exp $", "$Name: stable5 $");
  if (nargs && argc - nargs == 1)
    exit (0);
  argc -= nargs;

  Gdiag |= DIAG_SHOW ;
  Progname = argv[0] ;
  ErrorInit(NULL, NULL, NULL) ;
  DiagInit(NULL, NULL, NULL) ;

  memset(&parms, 0, sizeof(parms)) ;

  parms.projection = NO_PROJECTION ;
  parms.tol = 0.05 ;
  parms.check_tol = 1 ;
  parms.ignore_energy = 1 ;
  parms.dt = 0.5f ;
  parms.base_dt = BASE_DT_SCALE*parms.dt ;

  parms.l_spring_norm = 1 ;
  parms.l_shrinkwrap = 0 ;
  parms.l_intensity = 1 ;

  parms.niterations = 0 ;
  parms.write_iterations = 0 /*WRITE_ITERATIONS */;
  parms.integration_type = INTEGRATE_MOMENTUM ;
  parms.momentum = 0.0 /*0.8*/ ;
  parms.l_intensity = 1 ;
  parms.dt_increase = 1.0 /* DT_INCREASE */;
  parms.dt_decrease = 0.50 /* DT_DECREASE*/ ;
  parms.error_ratio = 50.0 /*ERROR_RATIO */;
  /*  parms.integration_type = INTEGRATE_LINE_MINIMIZE ;*/
  parms.l_surf_repulse = 0.0 ;
  parms.l_repulse = 0 /*1*/ ;

  ac = argc ;
  av = argv ;
  for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) {
    nargs = get_option(argc, argv) ;
    argc -= nargs ;
    argv += nargs ;
  }

  mdir = getenv("FREESURFER_HOME") ;
  if (!mdir)
    ErrorExit(ERROR_BADPARM, "FREESURFER_HOME not defined in environment") ;

  if (argc < 4)
    usage_exit() ;

  /* set default parameters for white and gray matter surfaces */
  parms.niterations = 1000 ;
  if (parms.momentum < 0.0)
    parms.momentum = 0.0 /*0.75*/ ;

  TimerStart(&then) ;
  T1_fname = argv[1] ;
  PD_fname = argv[2] ;
  output_dir = argv[3] ;
  fprintf(stderr, "reading volume %s...\n", T1_fname) ;
  mri_flash1 = MRIread(T1_fname) ;
  if (!mri_flash1)
    ErrorExit(ERROR_NOFILE, "%s: could not read input volume %s", Progname, T1_fname) ;

  mri_flash2 = MRIread(PD_fname) ;
  if (!mri_flash2)
    ErrorExit(ERROR_NOFILE, "%s: could not read input volume %s", Progname, T1_fname) ;

  //  setMRIforSurface(mri_flash1);
  sprintf(fname, "%s/lib/bem/ic%d.tri", mdir, ic_init) ;
  mris = MRISread(fname) ;
  if (!mris)
    ErrorExit(ERROR_NOFILE, "%s: could not read icosahedron %s", Progname, fname) ;

  mri_mean = MRImean(mri_flash1, NULL, 5) ;
  MRIwrite(mri_mean, "mean.mgz") ;

  mri_dif = MRIabsdiff(mri_flash1, mri_flash2, NULL) ;
  MRIwrite(mri_dif, "dif.mgz") ;

  mriseg = MRIsegment(mri_mean, 30, 100000) ;
  s = MRIsegmentMax(mriseg) ;
  mri_masked = MRIsegmentToImage(mri_flash1, NULL, mriseg, s) ;
  MRIwrite(mri_masked, "mask.mgz") ;
  MRIsegmentFree(&mriseg) ;

  // MRIthresholdMask(mri_dif, mri_masked, mri_dif, 1, 0) ;
  // MRIwrite(mri_dif, "dif_masked.mgz") ;


  mri_kernel = MRIgaussian1d(2, 0) ;
  mri_smooth = MRIconvolveGaussian(mri_dif, NULL, mri_kernel) ;
  MRIwrite(mri_smooth, "smooth.mgz") ;
  MRIScopyVolGeomFromMRI(mris, mri_smooth) ;
  mris->useRealRAS = 1 ;

  initialize_surface_position(mris, mri_dif, 1, &parms) ;
  MRISwrite(mris, "init") ;
  MRISrepositionToInnerSkull(mris, mri_smooth, &parms) ;

  exit(0) ;
  mri_grad = MRIsobel(mri_smooth, NULL, NULL) ;
  MRIwrite(mri_grad, "grad.mgz") ;
  mri_inner = MRIfindInnerBoundary(mri_dif, mri_grad, NULL, 5.0) ;
  MRIwrite(mri_inner, "inner.mgz") ;
  MRIbinarize(mri_inner, mri_inner, 10, 0, 128) ;

  MRISpositionOptimalSphere(mris, mri_inner, 6) ;
  MRISwrite(mris, "optimal") ;
  exit(0) ;
  parms.sigma = 4 / mri_flash1->xsize ;
  // mri_dist = create_distance_map(mri_masked, NULL, BORDER_VAL, OUTSIDE_BORDER_STEP) ;
  MRISsetVals(mris,parms.sigma) ;
  MRIScopyValToVal2(mris) ;
  MRISsetVals(mris, 0) ;
  sprintf(parms.base_name, "%s_inner_skull%s%s", "test", output_suffix, suffix) ;
  parms.mri_brain = mri_masked ;
  l_spring = parms.l_spring_norm ;
  mri_kernel = MRIgaussian1d(parms.sigma, 0) ;


  mri_binary = MRIbinarize(mri_dif, mri_binary, 40, 0, 128) ;
  MRIwrite(mri_binary, "bin.mgz") ;
  mri_distance = MRIdistanceTransform(mri_binary, NULL, 128, 100, DTRANS_MODE_SIGNED, NULL) ;
  MRIwrite(mri_distance, "dist.mgz") ;
  mri_masked_smooth = MRIconvolveGaussian(mri_distance, NULL, mri_kernel) ;
  MRIfree(&mri_kernel) ;
  MRIwrite(mri_masked_smooth, "dif_smooth.mgz") ;

  MRISwrite(mris, "inner_skull.tri") ;

  msec = TimerStop(&then) ;
  fprintf(stderr,"positioning took %2.1f minutes\n", (float)msec/(60*1000.0f));
  exit(0) ;
  return(0) ;  /* for ansi */
}