Ejemplo n.º 1
0
MRI *
MRIcropVolumeToLabel(MRI *mri_src, 
                     MRI *mri_dst, 
                     LABEL *area, 
                     MRI_SURFACE *mris_white, 
                     MRI_SURFACE *mris_pial)
{
  MHT    *mht_white, *mht_pial ;
  int    x, y, z ;
  VERTEX *v_white, *v_pial ;
  Real   xs, ys, zs ;

  mht_white = MHTfillVertexTableRes(mris_white, NULL, CURRENT_VERTICES, 5.0) ;
  mht_pial = MHTfillVertexTableRes(mris_pial, NULL, CURRENT_VERTICES, 5.0) ;
  if (mri_dst == NULL)
    mri_dst = MRIclone(mri_src, NULL) ;

  MRISclearMarks(mris_white) ; MRISclearMarks(mris_pial) ;
  LabelMarkSurface(area, mris_white) ; LabelMarkSurface(area, mris_pial) ;
  for (x = 0 ; x < mri_src->width ; x++)
  {
    for (y = 0 ; y < mri_src->height ; y++)
    {
      for (z = 0 ; z < mri_src->depth ; z++)
      {
        if (x == Gx && y == Gy && z == Gz)
          DiagBreak() ;
              
        if (MRIgetVoxVal(mri_src, x, y, z, 0) > 0)
        {
          MRISsurfaceRASFromVoxel(mris_white, mri_dst, 
                                  x, y, z, 
                                  &xs, &ys, &zs) ;
          v_white = MHTfindClosestVertexInTable(mht_white, mris_white, 
                                                xs, ys, zs, 1) ;
          v_pial = MHTfindClosestVertexInTable(mht_pial, mris_pial, 
                                               xs, ys, zs, 1) ;
          if ((v_white && v_white->marked == 1) ||
              (v_pial && v_pial->marked == 1))
          {
            MRIsetVoxVal(mri_dst, x, y, z, 0, 255) ;
          }
          else
            MRIsetVoxVal(mri_dst, x, y, z, 0, 0) ;
        }
      }
    }
  }

  MHTfree(&mht_white) ; MHTfree(&mht_pial) ;
  return(mri_dst) ;
}
Ejemplo n.º 2
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) ;
}
Ejemplo n.º 3
0
/*
  expects the two surfaces to have the CANONICAL_VERTICES field set to the 
  sphere.reg positions.
*/
int
MRISmapCuts(MRI_SURFACE *mris_in, MRI_SURFACE *mris_out)
{
  MHT    *mht_in, *mht_out ;
  int    vno_out /*, vno_in, fno_in, fno_out, n, ripflag*/ ;
  VERTEX *v_out, *v_in ;
#if 0
  FACE   *f_in, *f_out ;
#endif

  MRISstoreRipFlags(mris_in) ;
  MRISunrip(mris_in) ;

  mht_in = MHTfillVertexTable(mris_in, NULL, CANONICAL_VERTICES) ;
  mht_out = MHTfillVertexTable(mris_out, NULL, CANONICAL_VERTICES) ;

#if 0
  for (vno_in = 0 ; vno_in < mris_in->nvertices ; vno_in++)
  {
    if (vno_in == Gdiag_no)
      DiagBreak() ;
    v_in = &mris_in->vertices[vno_in] ;
    if (v_in->oripflag == 0)
      continue ;
    v_out = MHTfindClosestVertexInTable(mht_out, mris_out, v_in->cx, v_in->cy, v_in->cz, 1) ;
    if (v_out == NULL)
      DiagBreak() ;
    else
      v_out->ripflag = 1 ;
  }

  for (vno_out = 0 ; vno_out < mris_out->nvertices ; vno_out++)
  {
    if (vno_out == Gdiag_no)
      DiagBreak() ;
    v_out = &mris_out->vertices[vno_out] ;
    v_in = MHTfindClosestVertexInTable(mht_in, mris_in, v_out->cx, v_out->cy, v_out->cz, 1) ;
    if (v_in == NULL)
      DiagBreak() ;
    else if (v_in->oripflag)
      v_out->ripflag = 1 ;
  }

  for (fno_in = 0 ; fno_in < mris_in->nfaces ; fno_in++)
  {
    f_in = &mris_in->faces[fno_in] ;
    if (f_in->ripflag == 0)
      continue ;
    for (n = 0 ; n < VERTICES_PER_FACE ; n++)
    {
      vno_in = f_in->v[n] ;
      if (vno_in == Gdiag_no)
        DiagBreak() ;
      v_in = &mris_in->vertices[vno_in] ;
      v_out = MHTfindClosestVertexInTable(mht_out, mris_out, v_in->cx, v_in->cy, v_in->cz, 1) ;
      if (v_out == NULL)
        DiagBreak() ;
      else
        v_out->ripflag = 1 ;
    }
  }

  for (fno_out = 0 ; fno_out < mris_out->nfaces ; fno_out++)
  {
    f_out = &mris_out->faces[fno_out] ;
    ripflag = 0 ;
    for (n = 0 ; n < VERTICES_PER_FACE ; n++)
    {
      vno_out = f_out->v[n] ;
      if (vno_out == Gdiag_no)
        DiagBreak() ;
      v_out = &mris_out->vertices[vno_out] ;
      v_in = MHTfindClosestVertexInTable(mht_in, mris_in, v_out->cx, v_out->cy, v_out->cz, 1) ;
      if (v_in == NULL)
        DiagBreak() ;
      else
        if (v_in->ripflag)
          ripflag = 1 ;
    }
    f_out->ripflag = ripflag ;
  }

  for (fno_out = 0 ; fno_out < mris_out->nfaces ; fno_out++)
  {
    double cx, cy, cz ;
    int    n ;

    f_out = &mris_out->faces[fno_out] ;
    ripflag = 0 ;
    
    cx = cy = cz = 0.0 ;
    for (n = 0 ; n < VERTICES_PER_FACE ; n++)
    {
      vno_out = f_out->v[n] ;
      if (vno_out == Gdiag_no)
        DiagBreak() ;
      v_out = &mris_out->vertices[vno_out] ;
      cx += v_out->cx ; cy += v_out->cy ; cz += v_out->cz ;

    }
    cx /= VERTICES_PER_FACE ;
    cy /= VERTICES_PER_FACE ;
    cz /= VERTICES_PER_FACE ;
    v_in = MHTfindClosestVertexInTable(mht_in, mris_in, cx, cy, cz, 1) ;
    if (v_in == NULL)
      DiagBreak() ;
    else
      if (v_in->ripflag)
      {
        f_out->ripflag = 1 ;
        for (n = 0 ; n < VERTICES_PER_FACE ; n++)
          mris_out->vertices[f_out->v[n]].ripflag = 1 ;
      }
  }
#endif

#define STEP_SIZE 0.05
  for (vno_out = 0 ; vno_out < mris_out->nvertices ; vno_out++)
  {
    double d, dx, dy, dz ;
    int    n ;
    VERTEX *vn ;

    v_out = &mris_out->vertices[vno_out] ;
    for (n = 0 ; n < v_out->vnum ; n++)
    {
      vn = &mris_out->vertices[v_out->v[n]] ;
      dx = vn->cx - v_out->cx ; 
      dy = vn->cy - v_out->cy ; 
      dz = vn->cz - v_out->cz ; 
      for (d = 0.0 ; d <= 1.0 ; d+= STEP_SIZE)
      {
        v_in = MHTfindClosestVertexInTable(mht_in, mris_in, 
                                           v_out->cx+dx*d, 
                                           v_out->cy+dy*d, 
                                           v_out->cz+dz*d, 
                                           1) ;
        if (v_in == NULL)
          DiagBreak() ;
        else if (v_in->oripflag)
        {
          v_out->ripflag = 1 ;
          break ;
        }
      }
    }
  }

  MRISripFaces(mris_out) ;
  MRISrestoreRipFlags(mris_in) ;

  MHTfree(&mht_in) ; MHTfree(&mht_out) ;
  return(NO_ERROR) ;
}
static int
update_histograms(MRI_SURFACE *mris, MRI_SURFACE *mris_avg, float ***histograms, int nbins) {
  int    vno, vno2, vno_avg ;
  double volume_dist, surface_dist, circumference, angle ;
  VERTEX *v1, *v2 ;
  VECTOR *vec1, *vec2 ;
  MHT    *mht ;
  float  **histogram, min_dist ;

  mht = MHTfillVertexTableRes(mris_avg, NULL, CURRENT_VERTICES, 2.0) ;

  vec1 = VectorAlloc(3, MATRIX_REAL) ;
  vec2 = VectorAlloc(3, MATRIX_REAL) ;

  v1 = &mris->vertices[0] ;
  VECTOR_LOAD(vec1, v1->cx, v1->cy, v1->cz) ;  /* radius vector */
  circumference = M_PI * 2.0 * V3_LEN(vec1) ;
  MRISclearMarks(mris_avg) ;
#if 0
  for (vno = 0 ; vno < mris->nvertices ; vno++) {
    if ((vno % 1000) ==  0) {
      printf("\r%d of %d    ", vno, mris->nvertices) ;
      fflush(stdout) ;
    }
    v1 = &mris->vertices[vno] ;
    VECTOR_LOAD(vec1, v1->cx, v1->cy, v1->cz) ;  /* radius vector */
    vno_avg = MHTfindClosestVertexNo(mht, mris_avg, v1, &min_dist) ;  /* which histogram to increment */
    if (vno_avg < 0)
      continue ;
    if (vno_avg == Gdiag_no)
      DiagBreak() ;
    histogram = histograms[vno_avg] ;
    mris_avg->vertices[vno_avg].marked = 1 ;

    for (vno2 = 0 ; vno2 < mris->nvertices ; vno2++) {
      if (vno2 == vno)
        continue ;
      v2 = &mris->vertices[vno2] ;
      VECTOR_LOAD(vec2, v2->cx, v2->cy, v2->cz) ;  /* radius vector */
      volume_dist = sqrt(SQR(v1->origx-v2->origx)+SQR(v1->origy-v2->origy)+SQR(v1->origz-v2->origz)) ;
      if (nint(volume_dist) >= nbins || nint(volume_dist) < 0)
        continue ;
      angle = fabs(Vector3Angle(vec1, vec2)) ;
      surface_dist = circumference * angle / (2.0 * M_PI) ;
      if (surface_dist > nbins*MAX_SURFACE_SCALE)
        surface_dist = nbins*MAX_SURFACE_SCALE ;
      if (surface_dist < 1)
        surface_dist = 1 ;

      histogram[nint(volume_dist)][nint(surface_dist)]++ ;

      if (mht->buckets[0][0] != NULL)
        DiagBreak() ;
    }
  }
  MHTfree(&mht) ;
#endif

  /* map back ones that were missed */
  /* printf("\nfilling holes in mapping\n") ;*/
  mht = MHTfillVertexTableRes(mris, NULL, CURRENT_VERTICES, 2.0) ;
  for (vno_avg = 0 ; vno_avg < mris_avg->nvertices ; vno_avg++) {
    if (mris_avg->vertices[vno_avg].marked > 0)
      continue ;

    if ((vno_avg % 1000) ==  0) {
      printf("\r%d of %d    ", vno_avg, mris_avg->nvertices) ;
      fflush(stdout) ;
    }

    vno = MHTfindClosestVertexNo(mht, mris, &mris_avg->vertices[vno_avg], &min_dist) ;
    if (vno < 0)
      continue ;
    v1 = &mris->vertices[vno] ;
    VECTOR_LOAD(vec1, v1->cx, v1->cy, v1->cz) ;  /* radius vector */
    if (vno_avg < 0)
      continue ;
    if (vno_avg == Gdiag_no)
      DiagBreak() ;
    histogram = histograms[vno_avg] ;
    mris_avg->vertices[vno_avg].marked = 1 ;

    for (vno2 = 0 ; vno2 < mris->nvertices ; vno2++) {
      if (vno2 == vno)
        continue ;
      v2 = &mris->vertices[vno2] ;
      VECTOR_LOAD(vec2, v2->cx, v2->cy, v2->cz) ;  /* radius vector */
      volume_dist = sqrt(SQR(v1->origx-v2->origx)+SQR(v1->origy-v2->origy)+SQR(v1->origz-v2->origz)) ;
      if (nint(volume_dist) >= nbins || nint(volume_dist) < 0)
        continue ;
      angle = fabs(Vector3Angle(vec1, vec2)) ;
      surface_dist = circumference * angle / (2.0 * M_PI) ;
      if (surface_dist > nbins*MAX_SURFACE_SCALE)
        surface_dist = nbins*MAX_SURFACE_SCALE ;
      if (surface_dist < 1)
        surface_dist = 1 ;

      histogram[nint(volume_dist)][nint(surface_dist)]++ ;
    }
  }

  MHTfree(&mht) ;
  printf("\n") ;

  VectorFree(&vec1) ;
  VectorFree(&vec2) ;
  return(NO_ERROR) ;
}
Ejemplo n.º 5
0
MRI *
MRIflattenOverlay(MRI_SURFACE *mris, MRI *mri_overlay, MRI *mri_flat, double res, LABEL *label_overlay,
                  MRI **pmri_vertices)
{
  double   xmin, ymin, xmax, ymax, fdist, lambda[3], xf, yf, val0, val1, val2, val ;
  int      width, height, x, y, fno, ret, z ;
  MHT      *mht ;
  FACE     *face;
  MRI      *mri_vertices ;

  find_biggest_inscribed_rectangle(mris, &xmin, &ymin, &xmax, &ymax) ;
  width = (int)ceil((xmax-xmin)/res) ; width = (int)(floor(width/2.0)*2.0+1) ;   xmax=xmin+width;
  height = (int)ceil((ymax-ymin)/res) ;height = (int)(floor(height/2.0)*2.0+1) ; ymax=ymin+height;

  // 1st frame is correlations and 2nd is vertex #
  mri_vertices = MRIalloc(width, height, 1, MRI_FLOAT) ;
  MRIsetValues(mri_vertices, -1) ;
  mri_flat = MRIalloc(width, height, mri_overlay->nframes, MRI_FLOAT) ;
  mri_vertices->xstart = mri_flat->xstart = xmin ; mri_vertices->xend = mri_flat->xend = xmax ;
  mri_vertices->ystart = mri_flat->ystart = ymin ; mri_vertices->yend = mri_flat->yend = ymax ;
  mri_vertices->zstart = mri_flat->zstart = 0 ; 
  mri_vertices->zend = mri_flat->zend = mri_overlay->nframes-1 ;
  mri_vertices->c_r = mri_flat->c_r = xmin ;  mri_vertices->c_a = mri_flat->c_a = ymin ; 
  mri_vertices->c_s = mri_flat->c_s = 0 ;
  MRIsetResolution(mri_flat, res, res, 1) ;
  MRIsetResolution(mri_vertices, res, res, 1) ;
  if (label_overlay)  // constrain processing to only this label
    LabelRipRestOfSurface(label_overlay, mris) ;
  mht = MHTfillTableAtResolution(mris, NULL, CURRENT_VERTICES, 1.0) ;
  for (x = 0 ; x < width; x++)
    for (y = 0 ; y < height ; y++)
    {
      xf = x*res + xmin ;  yf = y*res + ymin ;   // back to flattened coords
      MHTfindClosestFaceGeneric(mht, mris, xf, yf, 0.0, 10*res, 2, 1, &face, &fno, &fdist) ;
      if (fno >= 0)  // otherwise this point is not in a face
      {
        ret = face_barycentric_coords(mris, fno, CURRENT_VERTICES, xf, yf, 0, &lambda[0], &lambda[1],&lambda[2]); 
        if (ret >= 0)
        {
          if (lambda[0] > lambda[1])
          {
            if (lambda[0] > lambda[2])
            {
              if (face->v[0] == Gdiag_no)
                DiagBreak() ;
              MRIsetVoxVal(mri_vertices, x, y, 0, 0, face->v[0]) ;
            }
            else
            {
              if (face->v[2] == Gdiag_no)
                DiagBreak() ;
              MRIsetVoxVal(mri_vertices, x, y, 0, 0, face->v[2]) ;
            }
          }
          else
          {
            if (lambda[1] > lambda[2])
            {
              if (face->v[1] == Gdiag_no)
                DiagBreak() ;
              MRIsetVoxVal(mri_vertices, x, y, 0, 0, face->v[1]) ;
            }
            else
            {
              if (face->v[2] == Gdiag_no)
                DiagBreak() ;
              MRIsetVoxVal(mri_vertices, x, y, 0, 0, face->v[2]) ;
            }
          }

          for (z = 0 ;z < mri_flat->depth ; z++)
          {
            val0 = MRIgetVoxVal(mri_overlay, face->v[0], 0, 0, z) ;
            val1 = MRIgetVoxVal(mri_overlay, face->v[1], 0, 0, z) ;
            val2 = MRIgetVoxVal(mri_overlay, face->v[2], 0, 0, z) ;
            val = lambda[0]*val0 + lambda[1]*val1 + lambda[2]*val2 ;
            MRIsetVoxVal(mri_flat, x, y, z, 0, val) ;
          }
        }
        else if (fabs(xf) < 10 && fabs(yf) < 10)
        {
          MHTfindClosestFaceGeneric(mht, mris, xf, yf, 0.0, 1000, -1, 1, &face, &fno, &fdist) ;
          printf("(%d, %d) --> %f %f unmapped (goes to face %d, v (%d, %d, %d) if projected\n",
                 x, y, xf, yf, fno, face->v[0], face->v[1], face->v[2]) ;
          DiagBreak() ;
        }
      }
    }

  if (pmri_vertices)
    *pmri_vertices = mri_vertices ;
  MHTfree(&mht) ;
  return(mri_flat) ;
}
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) ;
}