Example #1
0
void
convert_vox_to_surf(MRI_SURFACE* mris,
                    MRI* vol)
{
  double cx, cy, cz;
  Real   vx, vy, vz;

  VERTEX* pvtx = &( mris->vertices[0] );
  unsigned int nvertices = (unsigned int)mris->nvertices;

  for (unsigned int ui=0;
       ui < nvertices;
       ++ui, ++pvtx )
  {
    cx = pvtx->x;
    cy = pvtx->y;
    cz = pvtx->z;

    MRIvoxelToSurfaceRAS( vol,
                          cx, cy, cz,
                          &vx, &vy, &vz );

    pvtx->x = vx;
    pvtx->y = vy;
    pvtx->z = vz;
  } // next ui, pvtx
}
static int
compute_rigid_gradient(MRI_SURFACE *mris, MRI *mri, double *pdx, double *pdy, double *pdz) {
  int    vno ;
  VERTEX *v ;
  Real   val, xw, yw, zw, dx, dy, dz, delV, x, y, z, Ix, Iy, Iz, xv, yv, zv ;

  dx = dy = dz = 0.0 ;
  for (vno = 0 ; vno < mris->nvertices ; vno++) {
    v = &mris->vertices[vno] ;
    if (v->ripflag)
      continue ;
    if (vno == Gdiag_no)
      DiagBreak() ;
    x = v->x ;
    y = v->y ;
    z = v->z ;

    MRISvertexToVoxel(mris, v, mri, &xw, &yw, &zw);
    MRIsampleVolume(mri, xw, yw, zw, &val) ;

    MRIsampleVolumeGradient(mri, xw, yw, zw,  &Ix, &Iy, &Iz) ;
    // convert back to surface coords
    xw += Ix ;
    yw += Iy ;
    zw += Iz ;
    if (mris->useRealRAS)
      MRIvoxelToWorld(mri, xw, yw, zw, &xv, &yv, &zv) ;
    else
      MRIvoxelToSurfaceRAS(mri, xw, yw, zw, &xv, &yv, &zv) ;
    Ix = xv-v->x ;
    Iy = yv-v->y;
    Iz = zv-v->z ;

    delV = v->val - val ;

    dx += delV * Ix ;
    dy += delV * Iy ;
    dz += delV * Iz ;
    if (!finitep((float)dx))
      DiagBreak() ;
    if (!finitep((float)dy))
      DiagBreak() ;
    if (!finitep((float)dz))
      DiagBreak() ;
  }
  dx /= mris->nvertices ;
  dy /= mris->nvertices ;
  dz /= mris->nvertices ;
  *pdx = dx ;
  *pdy = dy ;
  *pdz = dz ;
  return(NO_ERROR) ;
}
static MRI_REGION*mriFindLabel(MRI *mri,int label,int offset) {
  MRI_REGION *region;
  int i,j,k,nlabels;
  Real xmin,ymax,zmin,xmax,ymin,zmax;
  Real xw,yw,zw;

  region=(MRI_REGION*)calloc(1,sizeof(MRI_REGION));

  xmin=ymin=zmin=100000;
  xmax=ymax=zmax=-100000;
  for (nlabels=k=0;k<mri->depth;k++)
    for (j=0;j<mri->height;j++)
      for (i=0;i<mri->width;i++)
        if (MRIvox(mri,i,j,k)==label) {
          nlabels++;
          MRIvoxelToSurfaceRAS(mri, i, j, k, &xw, &yw, &zw) ;
          if (xmin>xw) xmin=xw;
          if (ymin>yw) ymin=yw;
          if (zmin>zw) zmin=zw;
          if (xmax<xw) xmax=xw;
          if (ymax<yw) ymax=yw;
          if (zmax<zw) zmax=zw;
        }

  if (nlabels==0) ErrorExit(1,"No labels %d could be found in the volume\n",nlabels);

  region->x=(int)floor(xmin-offset);
  region->y=(int)floor(ymin-offset);
  region->z=(int)floor(zmin-offset);

  region->dx=(int)ceil(xmax-xmin+2*offset);
  region->dy=(int)ceil(ymax-ymin+2*offset);
  region->dz=(int)ceil(zmax-zmin+2*offset);

  return region;
}
Example #4
0
int
MRIsampleParcellationToSurface(MRI_SURFACE *mris, MRI *mri_parc) {
  int             min_label, max_label, **label_histo, l, vno, nlabels, x, y, z, max_l ;
  float           fmin, fmax, max_count, d ;
  MRIS_HASH_TABLE *mht ;
  VERTEX          *v ;
  Real            xs, ys, zs, xv, yv, zv, val ;
  MRI             *mri_parc_unused ;

  mri_parc_unused = MRIcopy(mri_parc, NULL) ;
  MRIvalRange(mri_parc, &fmin, &fmax) ;
  min_label = (int)floor(fmin) ;
  max_label = (int)ceil(fmax) ;
  nlabels = max_label - min_label + 1 ;

  label_histo = (int **)calloc(mris->nvertices, sizeof(int *)) ;
  if (label_histo == NULL)
    ErrorExit(ERROR_NOMEMORY, "%s: could not create label frequency histo", Progname) ;
  for (vno = 0 ; vno < mris->nvertices ;  vno++) {
    label_histo[vno] = (int *)calloc(nlabels, sizeof(int)) ;
    if (label_histo[vno] == NULL)
      ErrorExit(ERROR_NOMEMORY, "%s: could not create label frequency histo[%d] with %d bins",
                Progname, vno, nlabels) ;
  }

  mht = MHTfillVertexTableRes(mris, NULL, CURRENT_VERTICES, 8.0) ;

  MRISclearMarks(mris) ;

  // build histograms at each vertex
  for (x = 0 ; x < mri_parc->width ; x++) {
    for (y = 0 ; y < mri_parc->height ; y++) {
      for (z = 0 ; z < mri_parc->depth ; z++) {
        if (x == Gx && y == Gy && z == Gz)
          DiagBreak() ;
        l = (int)MRIgetVoxVal(mri_parc, x, y, z, 0) ;
        if (l == 0)
          continue ;
        MRIvoxelToSurfaceRAS(mri_parc, x, y, z, &xs, &ys, &zs) ;
        v = MHTfindClosestVertexInTable(mht, mris, xs, ys, zs, 0) ;
        if (v == NULL)
          continue ;
        if (sqrt(SQR(v->x-xs) + SQR(v->y-ys) + SQR(v->z-zs)) > 3)
          continue ;
        MRIsetVoxVal(mri_parc_unused, x, y, z, 0, 0) ;
        vno = v-mris->vertices ;
        if (vno == Gdiag_no)
        {
          printf("v %d: sampling from (%d, %d, %d) - %d\n",
                 vno, x, y, z, l);
          DiagBreak() ;
        }
        label_histo[vno][l-min_label]++ ;
      }
    }
  }

  MRIwrite(mri_parc_unused, "pu.mgz") ;
  for (vno = 0 ; vno < mris->nvertices ;  vno++) {
    if (vno == Gdiag_no)
      DiagBreak() ;
    max_l = 0 ;
    max_count = 0 ;
    for (l = 0 ; l < nlabels ; l++) {
      if (label_histo[vno][l] > max_count) {
        max_count = label_histo[vno][l] ;
        max_l = l+min_label ;
      }
    }
    v = &mris->vertices[vno] ;
    v->val = v->annotation = max_l ;
    if (max_count > 0)
      v->marked = 1 ;
  }
  for (vno = 0 ; vno < mris->nvertices ;  vno++) {
    v = &mris->vertices[vno] ;
    if (vno == Gdiag_no)
      DiagBreak() ;
    if (v->marked)
      continue ;  // found something here

    for (d = 0 ; d <= 2 ; d += 0.25) {
      xs = v->x + d*v->nx;
      ys = v->y + d*v->ny;
      zs = v->z + d*v->nz;
      MRIsurfaceRASToVoxel(mri_parc, xs, ys, zs, &xv, &yv, &zv);
      MRIsampleVolumeType(mri_parc, xv, yv, zv, &val, SAMPLE_NEAREST) ;
      l = (int)nint(val) ;
      if (l > 0) {
        v->val = v->annotation = l ;
        break ;
      }
    }
  }

  MHTfree(&mht) ;
  for (vno = 0 ; vno < mris->nvertices ;  vno++)
    free(label_histo[vno]) ;
  free(label_histo) ;
  MRIfree(&mri_parc_unused) ;
  return(NO_ERROR) ;
}
Example #5
0
MRI*
MRIcomputeVolumeFractionFromSurface(MRI_SURFACE *mris, double acc, MRI *mri_src, MRI *mri_fractions)
{
  const int width = mri_src->width;
  const int height = mri_src->height;
  const int depth = mri_src->depth;
  int x,y,z, vno;
  double xs, ys, zs, dist; 
  MRIS_HASH_TABLE *mht;
  VERTEX *v; 
  
  /* preparing the output */
  printf("preparing the output\n");
  if (mri_fractions == NULL)
    {
      mri_fractions = MRIalloc(width,height,depth,MRI_FLOAT);
      MRIcopyHeader(mri_src, mri_fractions);
    }
  MRI *mri_shell, *mri_interior; 
  /* creating a shell from the surface */
  printf("computing the shell\n");
  mri_shell = MRIclone(mri_src, NULL);
  mri_shell = MRISshell(mri_src, mris, mri_shell, 1);
  /* creating an interior image from the surface */
  printf("computing an interior image\n");
  mri_interior = MRIclone(mri_src, NULL);
  MRIclear(mri_interior);
  mri_interior = MRISfillInterior(mris, 0.0, mri_interior);
  /* creating the hash table related to the surface vertices */
  printf("computing the hash table\n");
  mht = MHTfillVertexTableRes(mris, NULL, CURRENT_VERTICES, 10);
  /* looping over the nonzero elements of the shell */
  printf("computing the fractions\n");
  volFraction frac;
  octTreeVoxel V; 
  double vox[3], vsize[3];
  vsize[0] = mri_src->xsize; vsize[1] = mri_src->ysize; vsize[2] = mri_src->zsize; 
  for (x = 0; x < width; x++)
    {
      for (y = 0; y < height; y++)
	{
	  for (z = 0; z < depth; z++)
	    {	  
	      if (MRIgetVoxVal (mri_shell, x, y, z, 0) > 125.0)
		{	      
		  /* change of coordinates from image to surface domain */
		  MRIvoxelToSurfaceRAS(mri_shell, x, y, z, &xs, &ys, &zs);
		  /* find the closest vertex to the point */
		  MHTfindClosestVertexGeneric(mht, mris, xs, ys, zs, 10, 2, &v, &vno, &dist);	      
		  /* creating the oct tree voxel structure */
		  vox[0] = xs - vsize[0] / 2.0; 
		  vox[1] = ys - vsize[1] / 2.0; 
		  vox[2] = zs - vsize[2] / 2.0; 
		  V = octTreeVoxelCreate(vox,vsize);
		  /* compute the volume fraction of this voxel */	      
		  frac = MRIcomputeVoxelFractions( V, v, acc, 1, mris);
		  MRIsetVoxVal(mri_fractions,x,y,z,0,frac.frac);
		}
	      else if(MRIgetVoxVal(mri_interior,x,y,z,0) > 0.0)
		MRIsetVoxVal(mri_fractions,x,y,z,0,1.0);

	    }
	}

    }
  return mri_fractions;
}
static int
initialize_surface_position(MRI_SURFACE *mris, MRI *mri_masked, int outside, INTEGRATION_PARMS *parms) {
  MRI    *mri_dilated ;
  int    x, y, z, vno ;
  double x0, y0, z0, radius = 0, dist, num ;
  Real   xs, ys, zs ;
  VERTEX *v ;

  if (outside) {
    mri_dilated = MRIdilate(mri_masked, NULL) ;

    MRIsubtract(mri_dilated, mri_masked, mri_dilated) ;
    MRIwrite(mri_dilated, "outside.mgz") ;

    num = x0 = y0 = z0 = 0 ;
    for (x = 0 ; x < mri_dilated->width ; x++) {
      for (y = 0 ; y < mri_dilated->height ; y++) {
        for (z = 0 ; z < mri_dilated->depth ; z++) {
          if (MRIgetVoxVal(mri_dilated, x, y, z,0) > 0) {
            MRIvoxelToSurfaceRAS(mri_dilated, x, y, z, &xs, &ys, &zs) ;
            x0 += xs ;
            y0 += ys ;
            z0 += zs ;
            num++ ;
          }
        }
      }
    }
    x0 /= num ;
    y0 /= num ;
    z0 /= num ;
    printf("centroid at (%2.1f, %2.1f, %2.1f)\n", x0,  y0, z0) ;

    num = radius = 0 ;
    for (x = 0 ; x < mri_dilated->width ; x++) {
      for (y = 0 ; y < mri_dilated->height ; y++) {
        for (z = 0 ; z < mri_dilated->depth ; z++) {
          if (MRIgetVoxVal(mri_dilated, x, y, z,0) > 0) {
            MRIvoxelToSurfaceRAS(mri_dilated, x, y, z, &xs, &ys, &zs) ;
            dist = sqrt(SQR(xs-x0)+SQR(ys-y0)+SQR(zs-z0)) ;
            radius += dist ;
            num++ ;
          }
        }
      }
    }

    radius /= num ;
    printf("average radius = %2.3f\n", radius) ;


    MRIfree(&mri_dilated) ;
    MRISprojectOntoSphere(mris, mris, radius*1.25) ;
    for (vno = 0 ; vno < mris->nvertices ; vno++) {
      v = &mris->vertices[vno] ;
      v->x += x0 ;
      v->y += y0 ;
      v->z += z0 ;
    }
    MRIScomputeMetricProperties(mris) ;
  }
  parms->target_radius = radius ;
  MRISsaveVertexPositions(mris, ORIGINAL_VERTICES) ;
  return(NO_ERROR) ;
}
static int
relabel_hypointensities(MRI *mri, MRI_SURFACE *mris, int right)
{
  int   x, y, z, label, changed ;
  MRIS_HASH_TABLE *mht ;
  VERTEX           *v ;
  float            dx, dy, dz, dot, dist ;
  Real             xw, yw, zw ;
  MRI              *mri_dist ;

  mri_dist = MRIcloneDifferentType(mri, MRI_FLOAT) ;
  MRIScomputeDistanceToSurface(mris, mri_dist, mri_dist->xsize) ;

  mht = MHTfillVertexTableRes(mris,NULL, CURRENT_VERTICES, 8.0f) ;
  for (changed = 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() ;
        }
        label = MRIgetVoxVal(mri, x, y, z, 0) ;
        if (label == Left_WM_hypointensities) {
          MRIsetVoxVal(mri, x, y, z,0, WM_hypointensities) ;
        } else if (label == Right_WM_hypointensities) {
          MRIsetVoxVal(mri, x, y, z, 0,  WM_hypointensities) ;
        }
        if ((!right && (label != Left_Cerebral_Cortex)) ||
            (right && (label != Right_Cerebral_Cortex))) {
          continue ;
        }

        // MRIvoxelToWorld(mri, x, y, z, &xw, &yw, &zw) ;
        MRIvoxelToSurfaceRAS(mri, x, y, z, &xw, &yw, &zw);
        v = MHTfindClosestVertexInTable(mht, mris, xw, yw, zw, 0) ;
        if (v == NULL)  /* no vertices within range -
                           assume it is hypointensity */
        {
          dot = -1 ;
          dist = MRIgetVoxVal(mri_dist, x, y, z, 0) ;
          if (dist > 0) {
            dot = 1 ;
          }
        } else {
          dx = xw - v->x ;
          dy = yw - v->y ;
          dz = zw - v->z ;
          dot = v->nx*dx + v->ny*dy + v->nz*dz ;
          dist = sqrt(dx*dx+dy*dy+dz*dz) ;
        }
        if (dot < 0 && dist > 1) {
          changed++ ;
          MRIsetVoxVal(mri, x, y, z, 0, WM_hypointensities) ;
        }
      }
    }
  }

  printf("%d voxels changed to hypointensity...\n", changed) ;
  MHTfree(&mht) ;
  MRIfree(&mri_dist) ;
  return(NO_ERROR) ;
}