示例#1
0
static int
normalize_timepoints_with_samples(MRI *mri, GCA_SAMPLE *gcas, int nsamples, int nsoap)
{
  int   frame, i, x, y, z ;
  double target, val ;
  MRI    *mri_ctrl, *mri_bias, *mri_target, *mri_frame ;

  mri_ctrl = MRIcloneDifferentType(mri, MRI_UCHAR) ;
  mri_bias = MRIcloneDifferentType(mri, MRI_FLOAT) ;
  mri_target = MRIcloneDifferentType(mri, MRI_FLOAT) ;

  for (i = 0 ; i < nsamples ; i++)
  {
    if (i == Gdiag_no)
      DiagBreak() ;
    x = nint(gcas[i].x)  ; y = nint(gcas[i].y) ; z = nint(gcas[i].z) ;
    MRIsetVoxVal(mri_ctrl, x, y, z, 0, CONTROL_MARKED) ;
    for (target = 0.0, frame = 0 ; frame < mri->nframes ; frame++)
      target += MRIgetVoxVal(mri, x, y, z, frame) ;
    target /= mri->nframes ;
    MRIsetVoxVal(mri_target, x, y, z, 0, target) ;
  }

  // build a bias correction for each time point (which each has its own frame)
  for (frame = 0 ; frame < mri->nframes ; frame++)
  {
    MRIclear(mri_bias) ; 
    for (i = 0 ; i < nsamples ; i++)
    {
      if (i == Gdiag_no)
        DiagBreak() ;
      x = nint(gcas[i].x)  ; y = nint(gcas[i].y) ; z = nint(gcas[i].z) ;
      target = MRIgetVoxVal(mri_target, x, y, z, 0) ;
      val = MRIgetVoxVal(mri, x, y, z, frame) ;
      if (FZERO(val))
        val = 1.0 ;
      MRIsetVoxVal(mri_bias, x, y, z, 0, target/val) ;
    }
    MRIbuildVoronoiDiagram(mri_bias, mri_ctrl, mri_bias) ;
    MRIsoapBubble(mri_bias, mri_ctrl, mri_bias, nsoap) ;
    mri_frame = MRIcopyFrame(mri, NULL, frame, 0) ;
    MRImultiply(mri_frame, mri_bias, mri_frame) ;
    if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
    {
      char fname[STRLEN] ;
      sprintf(fname, "frame%d.mgz", frame) ;
      MRIwrite(mri_frame, fname) ;
      sprintf(fname, "bias%d.mgz", frame) ;
      MRIwrite(mri_bias, fname) ;
      sprintf(fname, "target%d.mgz", frame) ;
      MRIwrite(mri_target, fname) ;
    }
    MRIcopyFrame(mri_frame, mri, 0, frame) ;
  }
  MRIfree(&mri_bias) ; MRIfree(&mri_target) ; MRIfree(&mri_ctrl) ;
  return(NO_ERROR) ;
}
static int
normalize_timepoints(MRI *mri, double thresh, double cross_time_sigma)
{
  int   frame, x, y, z, skip, nvox ;
  double target, val ;
  MRI    *mri_ctrl, *mri_bias, *mri_target, *mri_frame, *mri_kernel ;

  mri_ctrl = MRIcloneDifferentType(mri, MRI_UCHAR) ;
  mri_bias = MRIcloneDifferentType(mri, MRI_FLOAT) ;
  mri_target = MRIcloneDifferentType(mri, MRI_FLOAT) ;
  mri_kernel = MRIgaussian1d(cross_time_sigma, -1) ;

  for (nvox = x = 0 ; x < mri->width ; x++)
    for (y = 0 ; y < mri->height ; y++)
      for (z = 0 ; z < mri->depth ; z++)
      {
        if (x == Gx && y == Gy && z == Gz)
          DiagBreak() ;
        for (target = 0.0, frame = 0 ; frame < mri->nframes ; frame++)
          target += MRIgetVoxVal(mri, x, y, z, frame) ;
        target /= mri->nframes ;
        if (FZERO(target))
          continue ;  // both vals  0
        skip = 0 ;
        for (frame = 0 ; frame < mri->nframes ; frame++)
        {
          val = MRIgetVoxVal(mri, x, y, z, frame) ;
          if (fabs(val-target) > thresh)
          {
            skip = 1 ;
            break ;
          }
        }
        if (skip)
          continue ;
        nvox++ ;
        MRIsetVoxVal(mri_ctrl, x, y, z, 0, CONTROL_MARKED) ;
        MRIsetVoxVal(mri_target, x, y, z, 0, target) ;
      }

  printf("%d voxels found to base intensity correction on\n", nvox) ;

  // build a bias correction for each time point (which each has its own frame)
  for (frame = 0 ; frame < mri->nframes ; frame++)
  {
    MRIclear(mri_bias) ; 
    for (x = 0 ; x < mri->width ; x++)
      for (y = 0 ; y < mri->height ; y++)
        for (z = 0 ; z < mri->depth ; z++)
        {
          target = MRIgetVoxVal(mri_target, x, y, z, 0) ;
          val = MRIgetVoxVal(mri, x, y, z, frame) ;
          if (FZERO(val))
            val = 1.0 ;
          MRIsetVoxVal(mri_bias, x, y, z, 0, target/val) ;
        }
    MRIbuildVoronoiDiagram(mri_bias, mri_ctrl, mri_bias) ;
    MRIconvolveGaussian(mri_bias, mri_bias, mri_kernel) ;
    //    MRIsoapBubble(mri_bias, mri_ctrl, mri_bias, nsoap) ;
    mri_frame = MRIcopyFrame(mri, NULL, frame, 0) ;
    MRImultiply(mri_frame, mri_bias, mri_frame) ;
    if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
    {
      char fname[STRLEN] ;
      sprintf(fname, "frame%d.mgz", frame) ;
      MRIwrite(mri_frame, fname) ;
      sprintf(fname, "bias%d.mgz", frame) ;
      MRIwrite(mri_bias, fname) ;
      sprintf(fname, "target%d.mgz", frame) ;
      MRIwrite(mri_target, fname) ;
    }
    MRIcopyFrame(mri_frame, mri, 0, frame) ;
  }
  MRIfree(&mri_bias) ; MRIfree(&mri_kernel) ; MRIfree(&mri_target) ; MRIfree(&mri_ctrl) ;
  return(NO_ERROR) ;
}
static int
write_surface_warp_into_volume(MRI_SURFACE *mris, MRI *mri, int niter)
{
  int    vno, xvi, yvi, zvi, frame ;
  VERTEX *v ;
  double  dx, dy, dz, xv, yv, zv, xv1, yv1, zv1 ;
  MRI     *mri_weights, *mri_ctrl, *mri_frame ;
  float    wt ;

  mri_weights = MRIallocSequence(mri->width, mri->height, mri->depth, MRI_FLOAT, 1) ;
  mri_ctrl = MRIallocSequence(mri->width, mri->height, mri->depth, MRI_UCHAR, 1) ;
  MRIcopyHeader(mri, mri_weights) ; MRIcopyHeader(mri, mri_ctrl) ;
  //   build a 3 frame volume with the voxel-coords warp (dx, dy, dz) in frames 0, 1 and 2 respectively
  for (vno = 0 ; vno < mris->nvertices ; vno++)
  {
    v = &mris->vertices[vno] ;
    if (v->ripflag)
      continue ;

    MRISsurfaceRASToVoxelCached(mris, mri, v->origx, v->origy, v->origz, &xv, &yv, &zv) ;
    MRISsurfaceRASToVoxelCached(mris, mri, v->x, v->y, v->z, &xv1, &yv1, &zv1) ;
    dx = xv1-xv ; dy = yv1-yv ; dz = zv1-zv ;
    xvi = nint(xv) ; yvi = nint(yv) ; zvi = nint(zv) ;
    if (vno == Gdiag_no)
    {
      printf("surface vertex %d: inflated (%2.0f, %2.0f, %2.0f), orig (%2.0f, %2.0f, %2.0f), "
	     "dx=(%2.0f, %2.0f, %2.0f)\n", vno, xv1, yv1, zv1, xv, yv, zv, dx, dy, dz) ;
      DiagBreak() ;
    }
    if (xvi < 0 || xvi >= mri->width || yv < 0 || yv >= mri->height || zv < 0 || zv >= mri->depth)
    {
      continue ;
    }
    MRIinterpolateIntoVolumeFrame(mri, xv, yv, zv, 0, dx) ;
    MRIinterpolateIntoVolumeFrame(mri, xv, yv, zv, 1, dy) ;
    MRIinterpolateIntoVolumeFrame(mri, xv, yv, zv, 2, dz) ;
    MRIinterpolateIntoVolume(mri_weights, xv, yv, zv, 1.0) ;
  }

#if 0
  // set boundary conditions in the edge planes to be 0 warping
  for (xvi = 0 ; xvi < mri->width ; xvi++)
    for (yvi = 0 ; yvi < mri->height ; yvi++)
    {
      MRIsetVoxVal(mri_ctrl, xvi, yvi, 0, 0, CONTROL_MARKED) ;
      MRIsetVoxVal(mri, xvi, yvi, 0, 0, 0) ;
      MRIsetVoxVal(mri, xvi, yvi, 0, 1, 0) ;
      MRIsetVoxVal(mri, xvi, yvi, 0, 2, 0) ;

      MRIsetVoxVal(mri_ctrl, xvi, yvi, mri->depth-1, 0, CONTROL_MARKED) ;
      MRIsetVoxVal(mri, xvi, yvi, mri->depth-1, 0, 0) ;
      MRIsetVoxVal(mri, xvi, yvi, mri->depth-1, 1, 0) ;
      MRIsetVoxVal(mri, xvi, yvi, mri->depth-1, 2, 0) ;
    }

  for (xvi = 0 ; xvi < mri->width ; xvi++)
    for (zvi = 0 ; zvi < mri->depth ; zvi++)
    {
      MRIsetVoxVal(mri_ctrl, xvi, 0, zvi, 0, CONTROL_MARKED) ;
      MRIsetVoxVal(mri, xvi, 0, zvi, 0, 0) ;
      MRIsetVoxVal(mri, xvi, 0, zvi, 1, 0) ;
      MRIsetVoxVal(mri, xvi, 0, zvi, 2, 0) ;

      MRIsetVoxVal(mri_ctrl, xvi, mri->height-1, zvi, 0, CONTROL_MARKED) ;
      MRIsetVoxVal(mri, xvi, mri->height-1, zvi, 0, 0) ;
      MRIsetVoxVal(mri, xvi, mri->height-1, zvi, 1, 0) ;
      MRIsetVoxVal(mri, xvi, mri->height-1, zvi, 2, 0) ;
    }

  for (yvi = 0 ; yvi < mri->width ; yvi++)
    for (zvi = 0 ; zvi < mri->depth ; zvi++)
    {
      MRIsetVoxVal(mri_ctrl, 0, yvi, zvi, 0, CONTROL_MARKED) ;
      MRIsetVoxVal(mri, 0, yvi, zvi, 0, 0) ;
      MRIsetVoxVal(mri, 0, yvi, zvi, 1, 0) ;
      MRIsetVoxVal(mri, 0, yvi, zvi, 2, 0) ;

      MRIsetVoxVal(mri_ctrl, mri->width-1, yvi, zvi, 0, CONTROL_MARKED) ;
      MRIsetVoxVal(mri, mri->width-1, yvi, zvi, 0, 0) ;
      MRIsetVoxVal(mri, mri->width-1, yvi, zvi, 1, 0) ;
      MRIsetVoxVal(mri, mri->width-1, yvi, zvi, 2, 0) ;

    }
#endif

  // normalize the warp field using a weighted average of all vertices that map to every voxel
  for (xvi = 0 ; xvi < mri->width ; xvi++)
    for (yvi = 0 ; yvi < mri->height ; yvi++)
      for (zvi = 0 ; zvi < mri->depth ; zvi++)
      {
        if (xvi == Gx && yvi == Gy && zvi == Gz)
          DiagBreak() ;

        wt = MRIgetVoxVal(mri_weights, xvi, yvi, zvi, 0) ;
        dx = MRIgetVoxVal(mri, xvi, yvi, zvi, 0) ;
        dy = MRIgetVoxVal(mri, xvi, yvi, zvi, 1) ;
        dz = MRIgetVoxVal(mri, xvi, yvi, zvi, 2) ;
        if (FZERO(wt))
          continue ;

        dx /= wt ; dy /= wt ; dz /= wt ;
        MRIsetVoxVal(mri, xvi, yvi, zvi, 0, dx) ;
        MRIsetVoxVal(mri, xvi, yvi, zvi, 1, dy) ;
        MRIsetVoxVal(mri, xvi, yvi, zvi, 2, dz) ;
        MRIsetVoxVal(mri_ctrl, xvi, yvi, zvi, 0, CONTROL_MARKED) ;  // it is a control point
      }

  if (Gdiag & DIAG_WRITE)
  {
    MRIwrite(mri, "warp0.mgz") ;
    MRIwrite(mri_ctrl, "ctrl.mgz") ;
  }

  for (frame = 0 ; frame < mri->nframes ; frame++)
  {
    printf("interpolating frame %d\n", frame+1) ;
    mri_frame = MRIcopyFrame(mri, NULL, frame, 0) ;
    MRIbuildVoronoiDiagram(mri_frame, mri_ctrl, mri_frame) ;
    MRIsoapBubble(mri_frame, mri_ctrl, mri_frame, niter, mri_frame->xsize*.05) ;
#if 0
    {
      int x, y, z ;
      float val ;
      for (x  = 0 ; x < mri_frame->width ; x++)
        for (y  = 0 ; y < mri_frame->height ; y++)
          for (z  = 0 ; z < mri_frame->depth ; z++)
          {
            val = MRIgetVoxVal(mri_frame, x, y, z, 0) ;
            switch (frame)
            {
            default:
            case 0:
              val += x ;
              break ;
            case 1:
              val += y ;
              break ;
            case 2:
              val += z ;
              break ;
            }

            MRIsetVoxVal(mri_frame, x, y, z, 0, val) ;
          }
    }
#endif
    MRIcopyFrame(mri_frame, mri, 0, frame) ;
    MRIfree(&mri_frame) ;
  }
  MRIfree(&mri_weights) ;
  MRIfree(&mri_ctrl) ;
  return(NO_ERROR) ;
}