Пример #1
0
/*!
  \fn int CCSegment(MRI *seg, int segid, int segidunknown)
  Constraints a sementation ID to consist of voxels that
  are spatially contiguous (6 face neighbors, not edge
  or corner). The voxels in the largest cluster are not
  changed. The voxels in the other clusters are set to
  segidunknown.
*/
int CCSegment(MRI *seg, int segid, int segidunknown)
{
    MRI_SEGMENTATION *sgmnt;
    int k,kmax,index,c,r,s;

    sgmnt = MRIsegment(seg,segid-.5,segid+.5);
    printf("  Found %d clusters\n",sgmnt->nsegments);

    kmax = 0;
    for (k=0; k < sgmnt->nsegments; k++)
        if (sgmnt->segments[k].nvoxels > sgmnt->segments[kmax].nvoxels)
        {
            kmax = k;
        }

    for (k=0; k < sgmnt->nsegments; k++)
    {
        printf("     %d k %f\n",k,sgmnt->segments[k].area);
        if (k==kmax)
        {
            continue;
        }
        for (index = 0; index < sgmnt->segments[k].nvoxels; index++)
        {
            c = sgmnt->segments[k].voxels[index].x;
            r = sgmnt->segments[k].voxels[index].y;
            s = sgmnt->segments[k].voxels[index].z;
            MRIsetVoxVal(seg,c,r,s,0,segidunknown);
        }
    }
    MRIsegmentFree(&sgmnt);
    return(0);
}
Пример #2
0
MRI_SEGMENTATION *
MRIsegment(MRI *mri, float low_val, float hi_val)
{
  MRI_SEGMENTATION  *mriseg ;
  MRI_SEGMENT       *mseg, *mseg2 ;
  int               x, y, z, width, height, depth, xi, yi, zi, xk, yk, zk,
  border_labels[NBR_VOX], nlabels, label, nvox ;
  MRI               *mri_labeled ;
  float             voxel_size, val ;
  int max;
  int count =0;

  voxel_size = mri->xsize * mri->ysize * mri->zsize ;
  width = mri->width ;
  height = mri->height ;
  depth = mri->depth ;
  mriseg = MRIsegmentAlloc(MAX_SEGMENTS, MAX_VOXELS) ;
  mriseg->mri = mri ;

  /* mri_labeled will contain the label number for each voxel (if it
     has been assigned to a segment).
  */
  mri_labeled = MRIalloc(width, height, depth, MRI_SHORT) ;
  for (z = 0 ; z < depth ; z++)
  {
    for (y = 0 ; y < height ; y++)
    {
      for (x = 0 ; x < width ; x++)
        MRISvox(mri_labeled, x, y, z) = -1 ;
    }
  }

  for (z = 0 ; z < depth ; z++)
  {
    for (y = 0 ; y < height ; y++)
    {
      for (x = 0 ; x < width ; x++)
      {
        val = MRIgetVoxVal(mri, x, y, z, 0) ;
        // if within the range
        if (val >= low_val && val <= hi_val)
        {
          count++;

          // initializer for border_labels
          memset(border_labels, -1, NBR_VOX*sizeof(int)) ;
          for (nvox = 0, zk = -1 ; zk <= 1 ; zk++)
          {
            zi = z+zk ;
            if ((zi < 0) || (zi >= depth))
              continue ;
            for (yk = -1 ; yk <= 1 ; yk++)
            {
              yi = y+yk ;
              if ((yi < 0) || (yi >= height))
                continue ;
              // increment nvox count here
              for (xk = -1 ; xk <= 1 ; xk++, nvox++)
              {
#if 1
                if ((abs(xk) + abs(yk) + abs(zk)) > 1)
                  continue ;  /* only allow 4 (6 in 3-d) connectivity */
#endif

                xi = x+xk ;
                if ((xi < 0) || (xi >= width))
                  continue ;
                // get the neighbor label
                label = MRISvox(mri_labeled, xi, yi, zi) ;
                if (label >= 0)
                  border_labels[nvox] = label ;
              }
            }
          }
          // count nonzero labels in nbrs
          for (nlabels = nvox = 0 ; nvox < NBR_VOX ; nvox++)
          {
            label = border_labels[nvox] ;
            if ((label >= 0) && (!mriseg->segments[label].found))
            {
              mriseg->segments[label].found = 1 ;
              nlabels++ ;
            }
          }
          // reset found
          for (nvox = 0 ; nvox < NBR_VOX ; nvox++)
          {
            label = border_labels[nvox] ;
            if (label >= 0)
              mriseg->segments[label].found = 0 ; /* for next time */
          }
          //
          label = 0 ;
          // create labels for those points which are not connected
          switch (nlabels)
          {
          case 0:          /* allocate a new segment */
            label = mriSegmentNew(mriseg) ;
            // returns this added segment position
            mseg = &mriseg->segments[label] ;
            if (DIAG_VERBOSE_ON && 0)
              fprintf(stdout, "allocating new label %d (%d total)\n",
                      label, mriseg->nsegments) ;
            break ;
          case 1:          /* assign this voxel to the one that it borders */
            for (nvox = 0 ; nvox < NBR_VOX ; nvox++)
              if (border_labels[nvox] >= 0)
              {
                label = border_labels[nvox] ;
                break ;
              }
            // points to the same label position
            mseg = &mriseg->segments[label] ;
            break ;
          default:         /* merge segments and assign to lowest number */
            mseg = NULL ;
            for (nvox = 0 ; nvox < NBR_VOX ; nvox++)
            {
              if (border_labels[nvox] >= 0)
              {
                // the 1st encountered label case
                if (!mseg)
                {
                  // set the first index position
                  label = border_labels[nvox] ;
                  mseg = &mriseg->segments[label] ;
                  mseg->found = 1 ;
                }
                // the rest
                else
                {
                  mseg2 =
                    &mriseg->segments[border_labels[nvox]] ;
                  if (mseg2->found == 0)
                  {
                    mseg2->found = 1 ;  /* prevent merging more than once */
                    // merge to the label position
                    if (mriSegmentMerge(mriseg,
                                        label,
                                        border_labels[nvox],
                                        mri_labeled)
                        != NO_ERROR)
                    {
                      // nsegments decreased by one
                      MRIsegmentFree(&mriseg) ;
                      return(NULL) ;
                    }
                  }
                }
              }
            }
            // reset found
            for (nvox = 0 ; nvox < NBR_VOX ; nvox++)
              if (border_labels[nvox] >= 0)
                mriseg->segments[border_labels[nvox]].found = 0 ;
            break ;
          }
          /* add it to the existing list */
          if (mseg->nvoxels >= mseg->max_voxels)
          {
            // this max could be the same as mseg->max_voxels
            // this is taken care in mriSegmentReallocateVoxels()
            max = nint(mseg->max_voxels*VOX_INCREASE);
            // if (mriSegmentReallocateVoxels(mriseg, label,
            //            nint(mseg->max_voxels*VOX_INCREASE))
            //    != NO_ERROR)
            if (mriSegmentReallocateVoxels(mriseg, label, max)
                != NO_ERROR)
            {
              MRIsegmentFree(&mriseg) ;
              return(NULL) ;
            }
          }
          mseg->voxels[mseg->nvoxels].x = x ;
          mseg->voxels[mseg->nvoxels].y = y ;
          mseg->voxels[mseg->nvoxels].z = z ;
          mseg->nvoxels++ ;
          mseg->area += voxel_size ; // voxel_size = volume
#if 0
          // this is for only 1mm voxel case
          if (mseg->nvoxels != (int)mseg->area)
            DiagBreak() ;
#endif
          MRISvox(mri_labeled, x, y, z) = label ;
        }
      }
    }
  }
  MRIcompactSegments(mriseg) ;

  if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON && 0)
    MRIwrite(mri_labeled, "labeled.mgh") ;
  MRIfree(&mri_labeled) ;
  mriComputeSegmentStatistics(mriseg) ;
  return(mriseg) ;
}
Пример #3
0
// the following only cares about finding the max segments
// ignoring the rest
MRI_SEGMENTATION *
MRImaxsegment(MRI *mri, float low_val, float hi_val)
{
  MRI_SEGMENTATION  *mriseg ;
  MRI_SEGMENT       *mseg, *mseg2 ;
  int               x, y, z, width, height, depth, xi, yi, zi, xk, yk, zk,
  val, border_labels[NBR_VOX], nlabels, label, nvox ;
  MRI               *mri_labeled ;
  float             voxel_size ;
  int max;
  int count =0;
  int totcount = 0;
  int mem =0;
  int maxarea=0;

  voxel_size = mri->xsize * mri->ysize * mri->zsize ;
  width = mri->width ;
  height = mri->height ;
  depth = mri->depth ;
  mriseg = MRIsegmentAlloc(MAX_SEGMENTS, MAX_VOXELS) ;
  mriseg->mri = mri ;

  for (z =0; z < depth; z++)
    for (y=0; y < height; y++)
      for (x=0; x < width; x++)
      {
        val = MRIgetVoxVal(mri, x, y, z, 0) ;
        if (val >= low_val && val <= hi_val)
          totcount++;
      }

  /* mri_labeled will contain the label number for each voxel (if it
     has been assigned to a segment).
  */
  mri_labeled = MRIalloc(width, height, depth, MRI_SHORT) ;
  for (z = 0 ; z < depth ; z++)
  {
    for (y = 0 ; y < height ; y++)
    {
      for (x = 0 ; x < width ; x++)
        MRISvox(mri_labeled, x, y, z) = -1 ;
    }
  }

  for (z = 0 ; z < depth ; z++)
  {
    for (y = 0 ; y < height ; y++)
    {
      for (x = 0 ; x < width ; x++)
      {
        val = MRIgetVoxVal(mri, x, y, z, 0) ;
        // if within the range
        if (val >= low_val && val <= hi_val)
        {
          count++;

          // initializer for border_labels
          memset(border_labels, -1, NBR_VOX*sizeof(int)) ;
          for (nvox = 0, zk = -1 ; zk <= 1 ; zk++)
          {
            zi = z+zk ;
            if ((zi < 0) || (zi >= depth))
              continue ;
            for (yk = -1 ; yk <= 1 ; yk++)
            {
              yi = y+yk ;
              if ((yi < 0) || (yi >= height))
                continue ;
              // increment nvox count here
              for (xk = -1 ; xk <= 1 ; xk++, nvox++)
              {
#if 1
                if ((abs(xk) + abs(yk) + abs(zk)) > 1)
                  continue ;  /* only allow 4 (6 in 3-d) connectivity */
#endif

                xi = x+xk ;
                if ((xi < 0) || (xi >= width))
                  continue ;
                // get the neighbor label
                label = MRISvox(mri_labeled, xi, yi, zi) ;
                if (label >= 0)
                  border_labels[nvox] = label ;
              }
            }
          }
          // count nonzero labels in nbrs
          for (nlabels = nvox = 0 ; nvox < NBR_VOX ; nvox++)
          {
            label = border_labels[nvox] ;
            if ((label >= 0) && (!mriseg->segments[label].found))
            {
              mriseg->segments[label].found = 1 ;
              nlabels++ ;
            }
          }
          // reset found
          for (nvox = 0 ; nvox < NBR_VOX ; nvox++)
          {
            label = border_labels[nvox] ;
            if (label >= 0)
              mriseg->segments[label].found = 0 ; /* for next time */
          }
          //
          label = 0 ;
          // create labels for those points which are not connected
          switch (nlabels)
          {
          case 0:          /* allocate a new segment */
            if (mriseg->nsegments >= mriseg->max_segments)
            {
              mem = getMemoryUsed();
              // only Linux gives the correct value
              // (the rest returns -1
              // mem > 800*1024) // 800 Mbytes virtual memory usage
              if (mriseg->max_segments >
                  MAX_SEGMENTS*VOX_INCREASE)
              {
                if (mem > 0) // only Linux can do this
                  fprintf(stdout, "\n             "
                          "heap usage = %d Kbytes.", mem);
                // find the region with the largest area
                maxarea = MRImaxSegmentArea(mriseg);
                fprintf
                (stdout,
                 "\n             current max segment has "
                 "%d voxels", maxarea);
                // the second max area can have area up to
                // (current - maxarea) + (total - maxarea)
                //  = total + current - 2*maxarea
                // if this value is less than maxarea,
                // then the second candidate never
                // becomes the top. Thus I can remove
                // small segments
                // if (count+totcount < 3*maxarea)
                //
                // For those which has < 100*N % of maxarea,
                // the possible max count is
                //    = maxarea*N + remaining voxels
                //    = maxarea*N + (total - count)
                // Thus I can remove those when
                // maxarea*N + (total-count) < maxarea
                // or total - count < maxarea*(1 - N)
                //
                // Note that if you remove too much,
                // then possbile merging voxels will be lost
                //
                if (totcount - count < maxarea*0.99)
                {
                  int i,j,k;
                  fprintf(stdout, "\n             removing "
                          "small segments (less than 1 "
                          "percent of maxarea).");
                  MRIremoveSmallSegments(mriseg, maxarea*0.01);
                  // this does compactify
                  // go through mri_labeled to
                  // remove this label value s
                  for (k=0; k < mri_labeled->depth; ++k)
                    for (j=0; j < mri_labeled->height; ++j)
                      for (i=0; i < mri_labeled->width; ++i)
                      {
                        if (MRISvox(mri_labeled, i,j,k)
                            >= mriseg->nsegments)
                          MRISvox(mri_labeled, i,j,k) = -1;
                      }
                }
              }
            }
            label = mriSegmentNew(mriseg) ;
            // returns this added segment position
            mseg = &mriseg->segments[label] ;
            if (DIAG_VERBOSE_ON && 0)
              fprintf(stdout, "allocating new label %d (%d total)\n",
                      label, mriseg->nsegments) ;
            break ;
          case 1:          /* assign this voxel to the one that it borders */
            for (nvox = 0 ; nvox < NBR_VOX ; nvox++)
              if (border_labels[nvox] >= 0)
              {
                label = border_labels[nvox] ;
                break ;
              }
            // points to the same label position
            mseg = &mriseg->segments[label] ;
            break ;
          default:         /* merge segments and assign to lowest number */
            mseg = NULL ;
            for (nvox = 0 ; nvox < NBR_VOX ; nvox++)
            {
              if (border_labels[nvox] >= 0)
              {
                // the 1st encountered label case
                if (!mseg)
                {
                  // set the first index position
                  label = border_labels[nvox] ;
                  mseg = &mriseg->segments[label] ;
                  mseg->found = 1 ;
                }
                // the rest
                else
                {
                  mseg2 =
                    &mriseg->segments[border_labels[nvox]] ;
                  if (mseg2->found == 0)
                  {
                    mseg2->found = 1 ;  /* prevent merging more than once */
                    // merge to the label position
                    if (mriSegmentMerge(mriseg,
                                        label,
                                        border_labels[nvox],
                                        mri_labeled)
                        != NO_ERROR)
                    {
                      // nsegments decreased by one
                      MRIsegmentFree(&mriseg) ;
                      return(NULL) ;
                    }
                  }
                }
              }
            }
            // reset found
            for (nvox = 0 ; nvox < NBR_VOX ; nvox++)
              if (border_labels[nvox] >= 0)
                mriseg->segments[border_labels[nvox]].found = 0 ;
            break ;
          }
          /* add it to the existing list */
          if (mseg->nvoxels >= mseg->max_voxels)
          {
            // this max could be the same as mseg->max_voxels
            // this is taken care in mriSegmentReallocateVoxels()
            max = nint(mseg->max_voxels*VOX_INCREASE);
            // if (mriSegmentReallocateVoxels(mriseg, label,
            //            nint(mseg->max_voxels*VOX_INCREASE))
            //    != NO_ERROR)
            if (mriSegmentReallocateVoxels(mriseg, label, max)
                != NO_ERROR)
            {
              MRIsegmentFree(&mriseg) ;
              return(NULL) ;
            }
          }
          mseg->voxels[mseg->nvoxels].x = x ;
          mseg->voxels[mseg->nvoxels].y = y ;
          mseg->voxels[mseg->nvoxels].z = z ;
          mseg->nvoxels++ ;
          mseg->area += voxel_size ; // voxel_size = volume
#if 0
          // this is for only 1mm voxel case
          if (mseg->nvoxels != (int)mseg->area)
            DiagBreak() ;
#endif
          MRISvox(mri_labeled, x, y, z) = label ;
        }
      }
    }
  }
  mem = getMemoryUsed();
  if (mem > 0) // only Linux can do this
    fprintf(stdout, "\n             heap usage = %d Kbytes.", mem);
  maxarea = MRImaxSegmentArea(mriseg);
  fprintf(stdout, "\n             removing small segments (less "
          "than 1 percent of maxarea).");
  MRIremoveSmallSegments(mriseg, 0.01*maxarea);
  // MRIcompactSegments(mriseg) ;

  if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON && 0)
    MRIwrite(mri_labeled, "labeled.mgh") ;
  MRIfree(&mri_labeled) ;
  mriComputeSegmentStatistics(mriseg) ;
  return(mriseg) ;
}
Пример #4
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) ;
}
Пример #5
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) ;
}
Пример #6
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 */
}
Пример #7
0
static int
augment_thicknesses(FCD_DATA *fcd, 
                    MRI *mri_pvals,
                    double min_dist,
                    double max_dist,
                    double thresh)
{
  int         h, vno ;
  VERTEX      *v ;
  MRI_SURFACE *mris ;
  MRI         *mri_thickness ;
  double      nx, ny, nz, x0, y0, z0, d, x, y, z, val ;
  MRI_SEGMENTATION *mriseg ;

  mriseg = MRIsegment(mri_pvals, thresh, 1e10) ;
  MRIeraseSmallSegments(mriseg, mri_pvals, 20) ;
  MRIremoveSmallSegments(mriseg, 100) ;
  if (Gdiag & DIAG_WRITE)
  {
    MRIwrite(mri_pvals, "pvals.mgz") ;
  }
  MRIsegmentFree(&mriseg) ;

  for (h = 0 ; h <= 1 ; h++)  // do each hemi
  {
    if (h == 0)  // left hemi
    {
      mri_thickness = fcd->lh_thickness_on_lh ;
      mris = fcd->mris_lh ;
    }
    else   // right hemi
    {
      mri_thickness = fcd->rh_thickness_on_rh ;
      mris = fcd->mris_rh ;
    }
    for (vno = 0 ; vno < mris->nvertices ; vno++)
    {
      if (vno == Gdiag_no)
      {
        DiagBreak() ;
      }
      v = &mris->vertices[vno] ;
      if (v->ripflag)
      {
        continue ;
      }
      MRISvertexNormalInVoxelCoords(mris, mri_pvals, vno, &nx, &ny, &nz) ;
      MRISvertexToVoxel(mris, v, mri_pvals, &x0, &y0, &z0) ;

      for (d = 0 ; d <= max_dist ; d += 0.5)
      {
        x = x0+d*nx ;
        y = y0+d*ny ;
        z = z0+d*nz ;
        MRIsampleVolume(mri_pvals, x, y, z, &val) ;
        if (val < thresh)
        {
          break ;
        }
      }
	
      if (d > min_dist)   // a string of unlikely values
      {
        val = MRIgetVoxVal(mri_thickness, vno, 0, 0, 0) ;
        MRIsetVoxVal(mri_thickness, vno, 0, 0, 0, val+d) ;
      }
    }
  }
  return(NO_ERROR) ;
}
Пример #8
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) ;
}