コード例 #1
0
MRI *
MRIScomputeDistanceMap(MRI_SURFACE *mris, MRI *mri_distance, int ref_vertex_no)
{
  int    vno ;
  VERTEX *v ;
  double circumference, angle, distance ;
  VECTOR *v1, *v2 ;

  if (mri_distance == NULL)
    mri_distance = MRIalloc(mris->nvertices, 1, 1, MRI_FLOAT) ;

  v1 = VectorAlloc(3, MATRIX_REAL) ; v2 = VectorAlloc(3, MATRIX_REAL) ;
  v = &mris->vertices[ref_vertex_no] ;
  VECTOR_LOAD(v1, v->x, v->y, v->z) ;  /* radius vector */
  circumference = M_PI * 2.0 * V3_LEN(v1) ;
  for (vno = 0 ; vno < mris->nvertices ; vno++)
  {
    v = &mris->vertices[vno] ;
    if (vno == Gdiag_no)
      DiagBreak() ;
    VECTOR_LOAD(v2, v->x, v->y, v->z) ;  /* radius vector */
    angle = fabs(Vector3Angle(v1, v2)) ;
    distance = circumference * angle / (2.0 * M_PI) ;
    MRIsetVoxVal(mri_distance, vno, 0, 0, 0, distance) ;
  }

  VectorFree(&v1) ; VectorFree(&v2) ;
  return(mri_distance) ;
}
コード例 #2
0
ファイル: matrix.c プロジェクト: dkogan/PDL
void InversMatrix(const int n, double **b, double **ib) {

  double  **a;
  double   *e;
  int	    i,j;
  int  	   *p;

  a=MatrixAlloc(n);
  e=VectorAlloc(n);
  p=IntVectorAlloc(n);
  MatrixCopy(n, a, b);
  LUfact(n, a, p);
  for(i=0; i<n; i++) {
    for(j=0; j<n; j++)
      e[j]=0.0;
    e[i]=1.0;
    LUsubst(n, a, p, e);
    for(j=0; j<n; j++)
      ib[j][i]=e[j];
  } /* for i=1..n */

  MatrixFree(n, a);
  VectorFree(n, e);
  IntVectorFree(n, p);
} /* InversMatrix */
コード例 #3
0
static int
compute_cluster_statistics(MRI_SURFACE *mris, MRI *mri_profiles, CLUSTER *ct, int k) {
  int    i, vno, cluster, nsamples, num[MAX_CLUSTERS];
  VECTOR *v1 ;

  memset(num, 0, sizeof(num)) ;
  nsamples = mri_profiles->nframes ;

  v1 = VectorAlloc(nsamples, MATRIX_REAL) ;

  for (cluster = 0 ; cluster < k ; cluster++)
    VectorClear(ct[cluster].v_mean) ;

  // compute means
  for (vno = 0 ; vno < mris->nvertices ; vno++) {
    cluster = mris->vertices[vno].curv ;
    for (i = 0 ; i < nsamples ; i++) {
      VECTOR_ELT(v1, i+1) = MRIgetVoxVal(mri_profiles, vno, 0, 0, i) ;
    }
    num[cluster]++ ;
    VectorAdd(ct[cluster].v_mean, v1, ct[cluster].v_mean) ;
  }

  for (cluster = 0 ; cluster < k ; cluster++)
    if (num[cluster] > 0)
      VectorScalarMul(ct[cluster].v_mean, 1.0/(double)num[cluster], ct[cluster].v_mean) ;

  VectorFree(&v1) ;
  return(NO_ERROR) ;
}
コード例 #4
0
ファイル: matrix.c プロジェクト: dkogan/PDL
void GaussSeidel(const int n, double **a, double *b, double *x, double eps, 
		 int max_iter) {

  int      iter, i, j;       /* counter        */
  double   sum;              /* temporary real */
  double  *x_old;            /* old solution   */ 
  double   norm;             /* L1-norm        */

  x_old=VectorAlloc(n);

  iter=0;
  do {                       /* repeat until safisfying sol. */
    iter++;
    for(i=0; i<n; i++)       /* copy old solution */
      x_old[i]=x[i];
    norm=0.0;                /* do an iteration */
    for(i=0; i<n; i++) {     
      sum=-a[i][i]*x[i];     /* don't include term i=j */
      for(j=0; j<n; j++) 
	sum+=a[i][j]*x[j];   
      x[i]=(b[i]-sum)/a[i][i];
      norm+=fabs(x_old[i]-x[i]);
    } /* for i */
  } while ((iter<=max_iter) && (norm>=eps));

  VectorFree(n, x_old);
} /* GaussSeidel */
コード例 #5
0
CLUSTER *
MRISclusterKMeans(MRI_SURFACE *mris, MRI *mri_profiles, int k, char *start_fname, MRI_SURFACE *mris_ico) {
  int    i, nsamples, iter, done, nchanged ;
  char   fname[STRLEN] ;
  CLUSTER *ct ;

  nsamples = mri_profiles->nframes ;
  ct = calloc(k, sizeof(CLUSTER)) ;
  for (i = 0 ; i < k ; i++) {
    ct[i].v_mean = VectorAlloc(nsamples, MATRIX_REAL) ;
    ct[i].m_cov = MatrixIdentity(nsamples, NULL) ;
    ct[i].npoints = 0 ;
  }

  initialize_kmeans_centers(mris, mri_profiles, ct, k) ;

  done = iter = 0 ;
  do {
    nchanged = mark_clusters(mris, mri_profiles, ct, k) ;
    if (nchanged == 0)
      done = 1 ;
    compute_cluster_statistics(mris, mri_profiles, ct, k) ;
    sprintf(fname, "%s.clusters%6.6d.annot",
            mris->hemisphere == LEFT_HEMISPHERE ? "lh" : "rh", iter) ;
    printf("%6.6d: writing %s\n", iter, fname) ;
    MRISwriteAnnotation(mris, fname) ;
    sprintf(fname, "./%s.clusters%6.6d.indices",
            mris->hemisphere == LEFT_HEMISPHERE ? "lh" : "rh", iter) ;
    MRISwriteCurvature(mris, fname) ;
    if (iter++ > max_iterations)
      done = 1 ;
  } while (!done) ;

  return(ct) ;
}
コード例 #6
0
static MRI *
apply_bias(MRI *mri_orig, MRI *mri_norm, MRI *mri_bias) {
  MATRIX   *m_vox2vox;
  VECTOR   *v1, *v2;
  int      x, y, z ;
  double   xd, yd, zd, bias, val_orig, val_norm ;

  if (mri_norm == NULL)
    mri_norm = MRIclone(mri_orig, NULL) ;

  m_vox2vox = MRIgetVoxelToVoxelXform(mri_orig, mri_bias) ;
  v1 = VectorAlloc(4, MATRIX_REAL);
  v2 = VectorAlloc(4, MATRIX_REAL);
  VECTOR_ELT(v1, 4) = 1.0 ;
  VECTOR_ELT(v2, 4) = 1.0 ;

  for (x = 0 ; x < mri_orig->width ; x++) {
    V3_X(v1) = x ;
    for (y = 0 ; y < mri_orig->height ; y++) {
      V3_Y(v1) = y ;
      for (z = 0 ; z < mri_orig->depth ; z++) {
        V3_Z(v1) = z ;
        if (x == Gx && y == Gy && z == Gz)
          DiagBreak() ;
        val_orig = MRIgetVoxVal(mri_orig, x, y, z, 0) ;
        MatrixMultiply(m_vox2vox, v1, v2) ;
        xd = V3_X(v2) ;
        yd = V3_Y(v2) ;
        zd = V3_Z(v2);
        MRIsampleVolume(mri_bias, xd, yd, zd, &bias) ;
        val_norm = val_orig * bias ;
        if (mri_norm->type == MRI_UCHAR) {
          if (val_norm > 255)
            val_norm = 255 ;
          else if (val_norm < 0)
            val_norm = 0 ;
        }
        MRIsetVoxVal(mri_norm, x, y, z, 0, val_norm) ;
      }
    }
  }

  MatrixFree(&m_vox2vox) ;
  VectorFree(&v1) ;
  VectorFree(&v2) ;
  return(mri_norm) ;
}
コード例 #7
0
static int
test(MRI *mri1, MRI *mri2, MRI *mri3, MATRIX *m_vol1_to_vol2_ras) {
  VECTOR *v_test, *v_vox ;
  float  x_ras1, y_ras1, z_ras1, x_ras2, y_ras2, z_ras2, x_vox1, y_vox1,
  z_vox1, x_vox2, y_vox2, z_vox2 ;
  MATRIX  *m_vol2_vox2ras, *m_vol2_ras2vox, *m_vol1_ras2vox, *m_vol1_vox2ras,
  *m_vol3_ras2vox, *m_vol3_vox2ras ;
  int     val ;


  v_test = VectorAlloc(4, MATRIX_REAL) ;
  m_vol1_vox2ras = MRIgetVoxelToRasXform(mri1) ;
  m_vol2_vox2ras = MRIgetVoxelToRasXform(mri2) ;
  m_vol1_ras2vox = MRIgetRasToVoxelXform(mri1) ;
  m_vol2_ras2vox = MRIgetRasToVoxelXform(mri2) ;
  m_vol3_vox2ras = MRIgetVoxelToRasXform(mri3) ;
  m_vol3_ras2vox = MRIgetRasToVoxelXform(mri3) ;

  x_ras1 = 126.50 ;
  y_ras1 = -125.500 ;
  z_ras1 = 127.50 ;
  V3_X(v_test) = x_ras1 ;
  V3_Y(v_test) = y_ras1 ;
  V3_Z(v_test) = z_ras1 ;
  *MATRIX_RELT(v_test, 4, 1) = 1.0 ;
  v_vox = MatrixMultiply(m_vol1_ras2vox, v_test, NULL) ;
  x_vox1 = V3_X(v_vox) ;
  y_vox1 = V3_Y(v_vox) ;
  z_vox1 = V3_Z(v_vox) ;
  val = MRISvox(mri1, nint(x_vox1), nint(y_vox1), nint(z_vox1)) ;
  printf("VOL1: ras (%1.1f, %1.1f, %1.1f) --> VOX (%1.1f, %1.1f, %1.1f) = %d\n",
         x_ras1, y_ras1, z_ras1, x_vox1, y_vox1, z_vox1, val) ;


  x_ras2 = 76.5421 ;
  y_ras2 = 138.5352 ;
  z_ras2 = 96.0910 ;
  V3_X(v_test) = x_ras2 ;
  V3_Y(v_test) = y_ras2 ;
  V3_Z(v_test) = z_ras2 ;
  *MATRIX_RELT(v_test, 4, 1) = 1.0 ;
  v_vox = MatrixMultiply(m_vol2_ras2vox, v_test, NULL) ;
  x_vox2 = V3_X(v_vox) ;
  y_vox2 = V3_Y(v_vox) ;
  z_vox2 = V3_Z(v_vox) ;
  val = MRISvox(mri2, nint(x_vox2), nint(y_vox2), nint(z_vox2)) ;
  printf("VOL2: ras (%2.1f, %2.1f, %2.1f) --> VOX (%2.1f, %2.1f, %2.1f) = %d\n",
         x_ras2, y_ras2, z_ras2, x_vox2, y_vox2, z_vox2, val) ;



  MatrixFree(&v_test) ;
  return(NO_ERROR) ;
}
コード例 #8
0
static int
find_most_likely_unmarked_vertex(MRI_SURFACE *mris, MRI *mri_profiles, CLUSTER *ct, int k, int *pcluster_no) {
  double   dist, min_dist ;
  int      vno, c, min_cluster, min_vno, n, okay ;
  VECTOR   *v_vals ;
  VERTEX   *v, *vn ;

  v_vals = VectorAlloc(mri_profiles->nframes, MATRIX_REAL) ;

  min_dist = -1 ;
  min_vno = -1 ;
  min_cluster = -1 ;
  for (vno = 0 ; vno < mris->nvertices ; vno++) {
    v = &mris->vertices[vno] ;
    if (v->ripflag)
      continue ;
    if (v->curv < 0)   // not in a cluster yet
      continue ;

    c = v->curv ;
    for (n = 0 ; n < v->vnum ; n++) {
      vn = &mris->vertices[v->v[n]] ;
      if (vn->curv >= 0)
        continue ;
      if (vn->ripflag)
        continue ;
      load_vals(mri_profiles, v_vals, v->v[n]) ;
      dist = MatrixMahalanobisDistance(ct[c].v_mean, ct[c].m_cov, v_vals);
      if (min_vno < 0 || dist < min_dist) {
        if (ct[c].npoints == 1)
          okay = 1 ;
        else // check to make sure it has at least 2 nbrs of the right class
        {
          int n2, nc ;
          for (n2 = nc = 0 ; n2 < vn->vnum ; n2++)
            if (mris->vertices[vn->v[n2]].curv == c)
              nc++ ;
          okay = nc > 1 ;
        }
        if (okay) {
          min_cluster = c ;
          min_dist = dist ;
          min_vno = v->v[n] ;
        }
      }
    }
  }

  v = &mris->vertices[min_vno] ;
  *pcluster_no = min_cluster ;
  VectorFree(&v_vals) ;
  return(min_vno) ;
}
コード例 #9
0
ファイル: matrix.c プロジェクト: dkogan/PDL
void Jacobi(const int n, double **a, double *b, double *x, double eps, 
	    int max_iter) {

  double    d;              /* temporary real */
  int       i, j, iter;     /* counters       */
  double  **a_new;          /* a is altered   */
  double   *b_new;          /* b is altered   */
  double   *u;              /* new solution   */
  double    norm;           /* L1-norm        */

  a_new=MatrixAlloc(3);
  b_new=VectorAlloc(3);
  u=VectorAlloc(3);

  for(i=0; i<n; i++) {       /* the trick */
    d=1.0/a[i][i];
    b_new[i]=d*b[i];
    for(j=0; j<n; j++)
      a_new[i][j]=d*a[i][j];
  } /* for i */

  iter=0;
  do {
    iter++;
    norm=0.0;
    for(i=0; i<n; i++) {       /* update process */
      d=-a_new[i][i]*x[i];     /* don't include term i=j */
      for(j=0; j<n; j++)
	d+=a_new[i][j]*x[j];   
      u[i]=b_new[i]-d;
      norm=fabs(u[i]-x[i]);
    } /* for i */
    for(i=0; i<n; i++)           /* copy solution */
      x[i]=u[i];
  } while ((iter<=max_iter) && (norm>=eps));
  
  MatrixFree(3, a_new);
  VectorFree(3, b_new);
  VectorFree(3, u);
} /* Jacobi */
コード例 #10
0
static int
find_most_likely_vertex_to_swap(MRI_SURFACE *mris, MRI *mri_profiles, CLUSTER *ct,
                                int k, int *pcluster_no) {
  double   dist_current, dist_changed, dist_dec, max_dist_dec;
  int      vno, c1, c2, min_cluster, min_vno, n ;
  static VECTOR   *v_vals = NULL ;
  VERTEX   *v, *vn ;

  if (v_vals == NULL)
    v_vals = VectorAlloc(mri_profiles->nframes, MATRIX_REAL) ;

  // search for the vertex that has the biggest distance diff
  max_dist_dec = -1 ;
  min_vno = -1 ;
  min_cluster = -1 ;
  for (vno = 0 ; vno < mris->nvertices ; vno++) {
    v = &mris->vertices[vno] ;
    if (v->ripflag)
      continue ;
    if (v->curv < 0)   // not in a cluster yet
      continue ;

    c1 = v->curv ;
    load_vals(mri_profiles, v_vals, vno) ;
    dist_current = MatrixMahalanobisDistance(ct[c1].v_mean, ct[c1].m_cov, v_vals);
    for (n = 0 ; n < v->vnum ; n++) {
      vn = &mris->vertices[v->v[n]] ;
      if (vn->curv < 0)
        continue ;
      if (vn->ripflag)
        continue ;
      c2 = vn->curv ;
      if (c2 == c1)
        continue ;
      // distance to putative new cluster
      dist_changed = MatrixMahalanobisDistance(ct[c2].v_mean, ct[c2].m_cov, v_vals);
      dist_dec = (dist_current-dist_changed) ;
      if (min_vno < 0 || dist_dec > max_dist_dec) {
        if (okay_to_swap(mris, vno, c1, c2)) {
          min_cluster = c2 ;  // change it to new cluster
          max_dist_dec = dist_dec ;
          min_vno = vno ;
        }
      }
    }
  }

  v = &mris->vertices[min_vno] ;
  *pcluster_no = min_cluster ;
  return(min_vno) ;
}
コード例 #11
0
ファイル: matrix.c プロジェクト: dkogan/PDL
void LUfact(const int n, double **a, int *p) {

  int      i, j, k;             /* counters           */
  double   z;                   /* temporary real     */
  double  *s;                   /* pivot elements     */
  int      not_finished;        /* loop control var.  */
  int      i_swap;              /* swap var.          */
  double   temp;                /* another temp. real */

  s=VectorAlloc(n);
  for(i=0; i<n; i++) {
    p[i]=i;
    s[i]=0.0;
    for(j=0; j<n; j++) {
      z=fabs(a[i][j]);
      if (s[i]<z)
	s[i]=z;
    } /* for j */
  } /* for i */

  for(k=0; k<(n-1); k++) {
    j=k-1;           /* select j>=k so ... */
    not_finished=1;
    while (not_finished) {
      j++;
      temp=fabs(a[p[j]][k]/s[p[j]]);
      for(i=k; i<n; i++)  
	if (temp>=(fabs(a[p[i]][k])/s[p[i]]))
	  not_finished=0;          /* end loop */
    } /* while */
    i_swap=p[k];
    p[k]=p[j];
    p[j]=i_swap;
    temp=1.0/a[p[k]][k];
    for(i=(k+1); i<n; i++) {
      z=a[p[i]][k]*temp;
      a[p[i]][k]=z;
      for(j=(k+1); j<n; j++) 
	a[p[i]][j]-=z*a[p[k]][j];
    } /* for i */
  } /* for k */

  VectorFree(n, s);
} /* LUfact */
コード例 #12
0
static int
mark_clusters(MRI_SURFACE *mris, MRI *mri_profiles, CLUSTER *ct, int k) {
  int    i, vno, min_i, nsamples, num[MAX_CLUSTERS], nchanged ;
  double min_dist, dist ;
  VECTOR *v1 ;
  VERTEX *v ;

  memset(num, 0, sizeof(num)) ;
  nsamples = mri_profiles->nframes ;
  v1 = VectorAlloc(nsamples, MATRIX_REAL) ;
  for (nchanged = vno = 0 ; vno < mris->nvertices ; vno++) {
    v = &mris->vertices[vno] ;
    if (v->ripflag)
      continue ;
    if (vno == Gdiag_no)
      DiagBreak() ;

    for (i = 0 ; i < nsamples ; i++)
      VECTOR_ELT(v1, i+1) = MRIgetVoxVal(mri_profiles, vno, 0, 0, i) ;
    min_dist = MatrixMahalanobisDistance(ct[0].v_mean, ct[0].m_cov, v1) ;
    min_i = 0 ;
    for (i = 1 ; i < k ; i++) {
      if (i == Gdiag_no)
        DiagBreak() ;
      dist = MatrixMahalanobisDistance(ct[i].v_mean, ct[i].m_cov, v1) ;
      if (dist < min_dist) {
        min_dist = dist ;
        min_i = i ;
      }
    }
    CTABannotationAtIndex(mris->ct, min_i, &v->annotation) ;
    if (v->curv != min_i)
      nchanged++ ;
    v->curv = min_i ;
    num[min_i]++ ;
  }
  for (i = 0 ; i < k ; i++)
    if (num[i] == 0)
      DiagBreak() ;
  VectorFree(&v1) ;
  printf("%d vertices changed clusters...\n", nchanged) ;
  return(nchanged) ;
}
コード例 #13
0
ファイル: matrix.c プロジェクト: dkogan/PDL
void Tridiag(const int n, double *a, double *d, double *c, double *b) {

  int        i;            /* counter */
  double    *x;            /* solution */

  x=VectorAlloc(n);

  for(i=1; i<n; i++) {
    d[i]-=(a[i-1]/d[i-1])*c[i-1];
    b[i]-=(a[i-1]/d[i-1])*b[i-1];
  } /* for i */
  x[n-1]=b[n-1]/d[n-1];
  for(i=(n-2); i>=0; i--) 
    x[i]=(b[i]-c[i]*b[i+1])/d[i];

  for(i=0; i<n; i++)
    b[i]=x[i];
  VectorFree(n, x);
} /* Tridiag */
コード例 #14
0
ファイル: test_matrix.cpp プロジェクト: guo2004131/freesurfer
void
MatrixTest::TestMatrixSVDPseudoInverse()
{
    float tolerance = 1e-5;

    std::cout << "\rMatrixTest::TestMatrixSVDPseudoInverse()\n";

    // check the low-level routine first
    MATRIX *Ux = MatrixRead( (char*) ( SVD_U_MATRIX.c_str() ) );
    MATRIX *Vx = MatrixRead( (char*) ( SVD_V_MATRIX.c_str() ) );
    VECTOR *Sx = MatrixRead( (char*) ( SVD_S_VECTOR.c_str() ) );
    CPPUNIT_ASSERT (Ux != NULL);
    CPPUNIT_ASSERT (Vx != NULL);
    CPPUNIT_ASSERT (Sx != NULL);

    MATRIX *U=MatrixCopy(mSquareMatrix,NULL);
    MATRIX *V=MatrixAlloc(U->cols, U->cols, MATRIX_REAL) ;
    VECTOR *S=VectorAlloc(U->cols, MATRIX_REAL) ;
    OpenSvdcmp( U, S, V ) ;
    CPPUNIT_ASSERT (U != NULL);
    CPPUNIT_ASSERT (V != NULL);
    CPPUNIT_ASSERT (S != NULL);
    CPPUNIT_ASSERT ( AreMatricesEqual( U, Ux, tolerance ) );
    CPPUNIT_ASSERT ( AreMatricesEqual( V, Vx, tolerance ) );
    CPPUNIT_ASSERT ( AreMatricesEqual( S, Sx, tolerance ) );

    // now check MatrixSVDPseudoInverse, which uses sc_linalg_SV_decomp

    tolerance = 1e-5;

    MATRIX *actualInverse = MatrixSVDPseudoInverse( mNonSquareMatrix, NULL );
    MATRIX *expectedInverse =
        MatrixRead( (char*) ( NON_SQUARE_MATRIX_PSEUDO_INVERSE.c_str() ) );
    CPPUNIT_ASSERT( AreMatricesEqual( actualInverse, expectedInverse ) );

    actualInverse = MatrixSVDPseudoInverse( mSquareMatrix, NULL );
    expectedInverse =
        MatrixRead( (char*) ( SQUARE_MATRIX_PSEUDO_INVERSE.c_str() ) );
    CPPUNIT_ASSERT
    ( AreMatricesEqual( actualInverse, expectedInverse, tolerance ) );
}
コード例 #15
0
static int
add_vertex_to_cluster(MRI_SURFACE *mris, MRI *mri_profiles, CLUSTER *ct, int c, int vno) {
  int    nsamples;
  static VECTOR *v_vals = NULL ;

  nsamples = mri_profiles->nframes ;

  if (ct[c].npoints == 0)
    ct[c].vno = vno ;
  mris->vertices[vno].curv = c ;
  CTABannotationAtIndex(mris->ct, c, &mris->vertices[vno].annotation);
  if (v_vals == NULL)
    v_vals = VectorAlloc(nsamples, MATRIX_REAL) ;

  VectorScalarMul(ct[c].v_mean, ct[c].npoints, ct[c].v_mean) ;
  load_vals(mri_profiles, v_vals, vno) ;
  VectorAdd(ct[c].v_mean, v_vals, ct[c].v_mean) ;
  ct[c].npoints++ ;
  VectorScalarMul(ct[c].v_mean, 1.0/(double)ct[c].npoints, ct[c].v_mean) ;

  return(NO_ERROR) ;
}
コード例 #16
0
static int
remove_vertex_from_cluster(MRI_SURFACE *mris, MRI *mri_profiles, CLUSTER *ct,
                           int c, int vno) {
  int    nsamples;
  static VECTOR *v_vals = NULL ;

  nsamples = mri_profiles->nframes ;

  mris->vertices[vno].curv = c ;
  if (v_vals == NULL)
    v_vals = VectorAlloc(nsamples, MATRIX_REAL) ;

  VectorScalarMul(ct[c].v_mean, ct[c].npoints, ct[c].v_mean) ;
  load_vals(mri_profiles, v_vals, vno) ;
  VectorSubtract(ct[c].v_mean, v_vals, ct[c].v_mean) ;
  ct[c].npoints-- ;
  if (ct[c].npoints == 0)
    ErrorPrintf(ERROR_BADPARM, "%s: empty cluster %d (vertex %d removed)",
                Progname, c, vno) ;
  else
    VectorScalarMul(ct[c].v_mean, 1.0/(double)ct[c].npoints, ct[c].v_mean) ;

  return(NO_ERROR) ;
}
コード例 #17
0
ファイル: matrix.c プロジェクト: dkogan/PDL
void LUsubst(const int n, double **a, int *p, double *b) {

  int        i, j, k;           /* counters               */
  double     sum;               /* temporary sum variable */
  double    *x;                 /* solution               */
  
  x=VectorAlloc(n);

  for(k=0; k<(n-1); k++)        /* forward subst */
    for(i=(k+1); i<n; i++)
      b[p[i]]-=a[p[i]][k]*b[p[k]];
  
  for(i=(n-1); i>=0; i--) {     /* back subst */
    sum=b[p[i]];
    for(j=(i+1); j<n; j++)
      sum-=a[p[i]][j]*x[j];
    x[i]=sum/a[p[i]][i];
  } /* for i */
    
  for(i=0; i<n; i++)             /* copy solution */
    b[i]=x[i];

  VectorFree(n, x);
} /* LUsubst */
コード例 #18
0
static int
compute_cluster_statistics(MRI_SURFACE *mris, MRI *mri_profiles, MATRIX **m_covs, VECTOR **v_means, int k) {
  int    i, vno, cluster, nsamples, num[MAX_CLUSTERS];
  int    singular, cno_pooled, cno ;
  MATRIX *m1, *mpooled, *m_inv_covs[MAX_CLUSTERS] ;
  VECTOR *v1 ;
  FILE   *fp ;
  double det, det_pooled ;

  memset(num, 0, sizeof(num)) ;
  nsamples = mri_profiles->nframes ;

  v1 = VectorAlloc(nsamples, MATRIX_REAL) ;
  m1 = MatrixAlloc(nsamples, nsamples, MATRIX_REAL) ;
  mpooled = MatrixAlloc(nsamples, nsamples, MATRIX_REAL) ;

  for (cluster = 0 ; cluster < k ; cluster++) {
    VectorClear(v_means[cluster]) ;
    MatrixClear(m_covs[cluster]) ;
  }

  // compute means
  // fp = fopen("co.dat", "w") ;
  fp = NULL ;
  for (vno = 0 ; vno < mris->nvertices ; vno++) {
    cluster = mris->vertices[vno].curv ;
    for (i = 0 ; i < nsamples ; i++) {
      VECTOR_ELT(v1, i+1) = MRIgetVoxVal(mri_profiles, vno, 0, 0, i) ;
      if (cluster == 0 && fp)
        fprintf(fp, "%f ", VECTOR_ELT(v1, i+1));
    }
    if (cluster == 0 && fp)
      fprintf(fp, "\n") ;
    num[cluster]++ ;
    VectorAdd(v_means[cluster], v1, v_means[cluster]) ;
  }

  if (fp)
    fclose(fp) ;
  for (cluster = 0 ; cluster < k ; cluster++)
    if (num[cluster] > 0)
      VectorScalarMul(v_means[cluster], 1.0/(double)num[cluster], v_means[cluster]) ;

  // compute inverse covariances
  for (vno = 0 ; vno < mris->nvertices ; vno++) {
    cluster = mris->vertices[vno].curv ;
    for (i = 0 ; i < nsamples ; i++)
      VECTOR_ELT(v1, i+1) = MRIgetVoxVal(mri_profiles, vno, 0, 0, i) ;
    VectorSubtract(v_means[cluster], v1, v1) ;
    VectorOuterProduct(v1, v1, m1) ;
    MatrixAdd(m_covs[cluster], m1, m_covs[cluster]) ;
    MatrixAdd(mpooled, m1, mpooled) ;
  }

  MatrixScalarMul(mpooled, 1.0/(double)mris->nvertices, mpooled) ;
  cno_pooled = MatrixConditionNumber(mpooled) ;
  det_pooled = MatrixDeterminant(mpooled) ;
  for (cluster = 0 ; cluster < k ; cluster++)
    if (num[cluster] > 0)
      MatrixScalarMul(m_covs[cluster], 1.0/(double)num[cluster], m_covs[cluster]) ;


  // invert all the covariance matrices
  MatrixFree(&m1) ;
  singular = 0 ;
  for (cluster = 0 ; cluster < k ; cluster++) {
    m1 = MatrixInverse(m_covs[cluster], NULL) ;
    cno = MatrixConditionNumber(m_covs[cluster]) ;
    det = MatrixDeterminant(m_covs[cluster]) ;
    if (m1 == NULL)
      singular++ ;
    while (cno > 100*cno_pooled || 100*det < det_pooled) {
      if (m1)
        MatrixFree(&m1) ;
      m1 = MatrixScalarMul(mpooled, 0.1, NULL) ;
      MatrixAdd(m_covs[cluster], m1, m_covs[cluster]) ;
      MatrixFree(&m1) ;
      cno = MatrixConditionNumber(m_covs[cluster]) ;
      m1 = MatrixInverse(m_covs[cluster], NULL) ;
      det = MatrixDeterminant(m_covs[cluster]) ;
    }
    m_inv_covs[cluster] = m1 ;
  }

  for (cluster = 0 ; cluster < k ; cluster++) {
    if (m_inv_covs[cluster] == NULL)
      DiagBreak() ;
    else {
      MatrixFree(&m_covs[cluster]) ;
      m_covs[cluster] = m_inv_covs[cluster] ;
      //   MatrixIdentity(m_covs[cluster]->rows, m_covs[cluster]);
    }
  }
  MatrixFree(&mpooled) ;
  VectorFree(&v1) ;
  return(NO_ERROR) ;
}
コード例 #19
0
int
main(int argc, char *argv[]) {
  char   **av, *label_name, *vol_name, *out_name ;
  int    ac, nargs ;
  int    msec, minutes, seconds,  i  ;
  LABEL  *area ;
  struct timeb start ;
  MRI    *mri,  *mri_seg ;
  Real   xw, yw, zw, xv, yv, zv, val;

  /* rkt: check for and handle version tag */
  nargs = handle_version_option (argc, argv, "$Id: mri_label_vals.c,v 1.16 2015/08/24 18:22:05 fischl Exp $", "$Name:  $");
  if (nargs && argc - nargs == 1)
    exit (0);
  argc -= nargs;

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

  TimerStart(&start) ;

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

  if (argc < 3)
    usage_exit(1) ;

  vol_name = argv[1] ;
  label_name = argv[2]  ;
  out_name = argv[3] ;

  mri = MRIread(vol_name) ;
  if (!mri)
    ErrorExit(ERROR_NOFILE, "%s: could not read volume from %s",Progname, vol_name) ;
  if (scaleup_flag) {
    float scale, fov_x, fov_y, fov_z  ;

    scale = 1.0/MIN(MIN(mri->xsize, mri->ysize),mri->zsize) ;
    fprintf(stderr, "scaling voxel sizes up by %2.2f\n", scale) ;
    mri->xsize *= scale ;
    mri->ysize *= scale ;
    mri->zsize *= scale ;
    fov_x = mri->xsize * mri->width;
    fov_y = mri->ysize * mri->height;
    fov_z = mri->zsize * mri->depth;
    mri->xend = fov_x / 2.0;
    mri->xstart = -mri->xend;
    mri->yend = fov_y / 2.0;
    mri->ystart = -mri->yend;
    mri->zend = fov_z / 2.0;
    mri->zstart = -mri->zend;

    mri->fov = (fov_x > fov_y ? (fov_x > fov_z ? fov_x : fov_z) : (fov_y > fov_z ? fov_y : fov_z) );
  }

  if (segmentation_flag >= 0) {
    int x, y, z  ;
    VECTOR *v_seg, *v_mri ;
    MATRIX *m_seg_to_mri ;

    v_seg = VectorAlloc(4, MATRIX_REAL) ;
    v_mri = VectorAlloc(4, MATRIX_REAL) ;
    VECTOR_ELT(v_seg, 4) = 1.0 ;
    VECTOR_ELT(v_mri, 4) = 1.0 ;

    mri_seg = MRIread(argv[2]) ;
    if (!mri_seg)
      ErrorExit(ERROR_NOFILE, "%s: could not read volume from %s",Progname, argv[2]) ;
    if (erode) {
      MRI *mri_tmp ;

      mri_tmp = MRIclone(mri_seg, NULL) ;
      MRIcopyLabel(mri_seg, mri_tmp, segmentation_flag) ;
      while (erode-- > 0)
        MRIerode(mri_tmp, mri_tmp) ;
      MRIcopy(mri_tmp, mri_seg) ;
      MRIfree(&mri_tmp) ;
    }

    m_seg_to_mri = MRIgetVoxelToVoxelXform(mri_seg, mri) ;
    for (x = 0  ; x  < mri_seg->width ; x++) {
      V3_X(v_seg) = x ;
      for (y = 0  ; y  < mri_seg->height ; y++) {
        V3_Y(v_seg) = y ;
        for (z = 0  ; z  < mri_seg->depth ; z++) {
          V3_Z(v_seg) = z ;
          if (MRIvox(mri_seg, x, y,  z) == segmentation_flag) {
            MatrixMultiply(m_seg_to_mri, v_seg, v_mri) ;
            xv = V3_X(v_mri) ;
            yv = V3_Y(v_mri) ;
            zv = V3_Z(v_mri) ;
            MRIsampleVolumeType(mri, xv,  yv, zv, &val, SAMPLE_NEAREST);
#if  0
            if (val < .000001) {
              val *= 1000000;
              printf("%f*0.000001\n", val);
            } else
#endif
              if (coords)
                printf("%2.1f %2.1f %2.1f %f\n", xv, yv, zv, val);
              else
                printf("%f\n", val);
          }
        }
      }
    }
    MatrixFree(&m_seg_to_mri) ;
    VectorFree(&v_seg) ;
    VectorFree(&v_mri) ;
  } else {
    if (cras == 1)
      fprintf(stderr,"using the label coordinates to be c_(r,a,s) != 0.\n");

    if (surface_dir) {
      MRI_SURFACE *mris ;
      char fname[STRLEN] ;
      sprintf(fname, "%s/%s.white", surface_dir, hemi) ;
      mris = MRISread(fname) ;
      if (mris == NULL)
        ErrorExit(ERROR_NOFILE, "%s: could not read surface file %s...\n", Progname,fname) ;
      sprintf(fname, "%s/%s.thickness", surface_dir, hemi) ;
      if (MRISreadCurvatureFile(mris, fname) != NO_ERROR)
        ErrorExit(ERROR_BADPARM, "%s: could not read thickness file %s...\n", Progname,fname) ;

      if (annot_prefix)   /* read an annotation in and print vals in it */
      {
#define MAX_ANNOT 10000
        int   vno, annot_counts[MAX_ANNOT], index ;
        VERTEX *v ;
        Real  xw, yw, zw, xv, yv, zv, val ;
        float annot_means[MAX_ANNOT] ;
        FILE  *fp ;

        memset(annot_means, 0, sizeof(annot_means)) ;
        memset(annot_counts, 0, sizeof(annot_counts)) ;
        if (MRISreadAnnotation(mris, label_name) != NO_ERROR)
          ErrorExit(ERROR_BADPARM, "%s: could not read annotation file %s...\n", Progname,fname) ;
        if (mris->ct == NULL)
          ErrorExit(ERROR_BADPARM, "%s: annot file does not contain a color table, specifiy one with -t ", Progname);
        for (vno = 0 ; vno < mris->nvertices ; vno++) {
          v = &mris->vertices[vno] ;
          if (v->ripflag)
            continue ;
          CTABfindAnnotation(mris->ct, v->annotation, &index) ;
          if (index >= 0 && index < mris->ct->nentries) {
            annot_counts[index]++ ;
            xw = v->x + v->curv*.5*v->nx ;
            yw = v->y + v->curv*.5*v->ny ;
            zw = v->z + v->curv*.5*v->nz ;
            if (cras == 1)
              MRIworldToVoxel(mri, xw, yw,  zw, &xv, &yv, &zv) ;
            else
              MRIsurfaceRASToVoxel(mri, xw, yw, zw, &xv, &yv, &zv);
            MRIsampleVolume(mri, xv, yv, zv, &val) ;
            annot_means[index] += val ;
            sprintf(fname, "%s-%s-%s.dat", annot_prefix, hemi, mris->ct->entries[index]->name) ;
            fp = fopen(fname, "a") ;
            fprintf(fp, "%f\n", val) ;
            fclose(fp) ;
          }
        }
      }
      else  /* read label in and print vals in it */
      {
        area = LabelRead(NULL, label_name) ;
        if (!area)
          ErrorExit(ERROR_NOFILE, "%s: could not read label from %s",Progname, label_name) ;

      }
    } else {
      area = LabelRead(NULL, label_name) ;
      if (!area)
        ErrorExit(ERROR_NOFILE, "%s: could not read label from %s",Progname, label_name) ;

      for (i = 0 ;  i  < area->n_points ; i++) {

        xw =  area->lv[i].x ;
        yw =  area->lv[i].y ;
        zw =  area->lv[i].z ;
        if (cras == 1)
          MRIworldToVoxel(mri, xw, yw,  zw, &xv, &yv, &zv) ;
        else
          MRIsurfaceRASToVoxel(mri, xw, yw, zw, &xv, &yv, &zv);
        MRIsampleVolumeType(mri, xv,  yv, zv, &val, SAMPLE_NEAREST);
#if 0
        if (val < .000001) {
          val *= 1000000;
          printf("%f*0.000001\n", val);
        } else
#endif
          printf("%f\n", val);
      }
    }
  }
  msec = TimerStop(&start) ;
  seconds = nint((float)msec/1000.0f) ;
  minutes = seconds / 60 ;
  seconds = seconds % 60 ;

  if (DIAG_VERBOSE_ON)
    fprintf(stderr, "label value extractiong took %d minutes and %d seconds.\n",
            minutes, seconds) ;

  exit(0) ;
  return(0) ;
}
コード例 #20
0
/* Actually no need to modify this function, since I will only use the float
 * type here, so the roundoff I added will never take effect.
 * What I need to modify is the MRIchangeType function!
 */
MRI *MRIlinearTransformInterpBSpline(MRI *mri_src, MRI *mri_dst, MATRIX *mA,
                                     int splinedegree)
{
  int    y1, y2, y3, width, height, depth ;
  VECTOR *v_X, *v_Y ;   /* original and transformed coordinate systems */
  MATRIX *mAinv ;     /* inverse of mA */
  double   val, x1, x2, x3 ;
  MRI *mri_Bcoeff;

  mAinv = MatrixInverse(mA, NULL) ;      /* will sample from dst back to src */
  if (!mAinv)
    ErrorReturn(NULL, (ERROR_BADPARM,
                       "MRIlinearTransformBSpline: xform is singular")) ;

  if (!mri_dst) mri_dst = MRIclone(mri_src, NULL) ;
  else          MRIclear(mri_dst) ; /* set all values to zero */

  if (mri_src->type != MRI_FLOAT)
    mri_Bcoeff = MRIchangeType(mri_src, MRI_FLOAT, 0, 1.0, 1);
  else
    mri_Bcoeff = MRIcopy(mri_src, NULL);

  /* convert between a representation based on image samples */
  /* and a representation based on image B-spline coefficients */
  if (SamplesToCoefficients(mri_Bcoeff, splinedegree))
  {
    ErrorReturn(NULL, (ERROR_BADPARM, "Change of basis failed\n"));
  }

  printf("Direct B-spline Transform Finished. \n");

  width = mri_src->width ;
  height = mri_src->height ;
  depth = mri_src->depth ;
  v_X = VectorAlloc(4, MATRIX_REAL) ;  /* input (src) coordinates */
  v_Y = VectorAlloc(4, MATRIX_REAL) ;  /* transformed (dst) coordinates */

  v_Y->rptr[4][1] = 1.0f ;
  for (y3 = 0 ; y3 < mri_dst->depth ; y3++)
  {
    V3_Z(v_Y) = y3 ;
    for (y2 = 0 ; y2 < mri_dst->height ; y2++)
    {
      V3_Y(v_Y) = y2 ;
      for (y1 = 0 ; y1 < mri_dst->width ; y1++)
      {
        V3_X(v_Y) = y1 ;
        MatrixMultiply(mAinv, v_Y, v_X) ;

        x1 = V3_X(v_X) ;
        x2 = V3_Y(v_X) ;
        x3 = V3_Z(v_X) ;

        if (x1 <= -0.5 || x1 >= (width - 0.5) || x2 <= -0.5 ||
            x2 >= (height - 0.5) || x3 <= -0.5 || x3 >= (depth-0.5))
          val = 0.0;
        else
          val = InterpolatedValue(mri_Bcoeff, x1, x2, x3, splinedegree);

        switch (mri_dst->type)
        {
        case MRI_UCHAR:
          if (val <-0.5) val = -0.5;
          if (val > 254.5) val = 254.5;
          MRIvox(mri_dst,y1,y2,y3) = (BUFTYPE)nint(val+0.5) ;
          break ;
        case MRI_SHORT:
          MRISvox(mri_dst,y1,y2,y3) = (short)nint(val+0.5) ;
          break ;
        case MRI_FLOAT:
          MRIFvox(mri_dst,y1,y2,y3) = (float)(val) ;
          break ;
        case MRI_INT:
          MRIIvox(mri_dst,y1,y2,y3) = nint(val+0.5) ;
          break ;
        default:
          ErrorReturn(NULL,
                      (ERROR_UNSUPPORTED,
                       "MRIlinearTransformBSpline: unsupported dst type %d",
                       mri_dst->type)) ;
          break ;
        }
      }
    }
  }

  MatrixFree(&v_X) ;
  MatrixFree(&mAinv) ;
  MatrixFree(&v_Y) ;

  MRIfree(&mri_Bcoeff);
  return(mri_dst) ;
}
コード例 #21
0
ファイル: fcreateMorph.cpp プロジェクト: CBoensel/freesurfer
// returns the mask if necessary
MRI*
CopyGcamToDeltaField(GCA_MORPH* gcam, MRI* field)
{
  if ( !field ) throw std::string(" Field not set in CopyGcamToDeltaField\n");

  // allocate the mask
  MRI* mask = MRIalloc( field->width,
                        field->height,
                        field->depth,
                        MRI_UCHAR );
  unsigned int maskCounter = 0;
  unsigned char ucOne(1);//, ucZero(0);
  // fill the mask with true values to start with

  for (int z=0; z<field->depth; ++z)
    for (int y=0; y<field->height; ++y)
      for (int x=0; x<field->width; ++x)
        MRIvox(mask, x,y,z) = ucOne;


  GMN* pnode = NULL;

  // currently bug in transform.c - names are swapped
  //MATRIX* v2r_atlas = VGgetVoxelToRasXform( &gcam->atlas, NULL, 0);
  //MATRIX* r2v_image = VGgetRasToVoxelXform( &gcam->image, NULL, 0);
  MATRIX* v2r_atlas = VGgetRasToVoxelXform( &gcam->atlas, NULL, 0);
  //MATRIX* r2v_image = VGgetVoxelToRasXform( &gcam->image, NULL, 0);
  MATRIX* r2v_image = extract_r_to_i( field );
  MATRIX* transform = MatrixMultiply( r2v_image, v2r_atlas, NULL);

  std::cout << " vox 2 ras atlas = \n";
  MatrixPrint( stdout, v2r_atlas );
  std::cout << " ras 2 vox image = \n";
  MatrixPrint( stdout, r2v_image );
  std::cout << " product = \n";
  MatrixPrint( stdout, transform);
  std::cout << std::endl;

  // using the above matrix, go through the nodes of the GCAM
  // and associate the delta to the transformed node
  //
  // !!!! The strong underlying assumption is that the IMAGE and ATLAS associated
  // with the GCAM share the same RAS
  //
  VECTOR *vx = VectorAlloc(4, MATRIX_REAL);
  VECTOR_ELT(vx, 4) = 1.0;
  VECTOR_ELT(vx, 1) = 0.0;
  VECTOR_ELT(vx, 2) = 0.0;
  VECTOR_ELT(vx, 3) = 0.0;

  VECTOR *vfx= VectorAlloc(4, MATRIX_REAL);

  MatrixMultiply(transform, vx, vfx);
  std::cout << " transform at origin\n";
  MatrixPrint(stdout, vfx);

  int shift_x, shift_y, shift_z;

  shift_x = myNint( VECTOR_ELT(vfx, 1) );
  shift_y = myNint( VECTOR_ELT(vfx, 2) );
  shift_z = myNint( VECTOR_ELT(vfx, 3) );

  unsigned int invalidCount = 0;
  int img_x, img_y, img_z;
  for ( int z=0, maxZ=gcam->depth; z<maxZ; ++z)
    for ( int y=0, maxY=gcam->height; y<maxY; ++y)
      for ( int x=0, maxX=gcam->width; x<maxX; ++x)
      {
#if 0
        // indexing is 1-based - NR
        VECTOR_ELT(vx, 1) = x;
        VECTOR_ELT(vx, 2) = y;
        VECTOR_ELT(vx, 3) = z;

        MatrixMultiply(transform, vx, vfx);

        img_x = myNint( VECTOR_ELT(vfx, 1) );
        img_y = myNint( VECTOR_ELT(vfx, 2) );
        img_z = myNint( VECTOR_ELT(vfx, 3) );
#endif

        img_x = x + shift_x;
        img_y = y + shift_y;
        img_z = z + shift_z;

        if ( img_x < 0 || img_x > field->width-1 ||
             img_y < 0 || img_y > field->height-1 ||
             img_z < 0 || img_z > field->depth-1 )
        {
          maskCounter++;
          continue;
        }
        pnode = &gcam->nodes[x][y][z];

        //if (pnode->invalid) continue;
        if ( pnode->invalid == GCAM_POSITION_INVALID )
        {
          ++invalidCount;
          continue;
        }

#if 0
        if ( img_x == g_vDbgCoords[0] &&
             img_y == g_vDbgCoords[1] &&
             img_z == g_vDbgCoords[2] )
        {
          std::cout << " node " << img_x
          << " , " << img_y
          << " , " << img_z
          << " comes from "
          << x << " , " << y << " , " << z
          << " -> " << pnode->x
          << " , " << pnode->y
          << " , " << pnode->z << std::endl;
        }
#endif

        MRIsetVoxVal(mask, img_x, img_y, img_z, 0, ucOne );

        MRIsetVoxVal( field, img_x, img_y, img_z, 0,
                      pnode->x - img_x );
        MRIsetVoxVal( field, img_x, img_y, img_z, 1,
                      pnode->y - img_y );
        MRIsetVoxVal( field, img_x, img_y, img_z, 2,
                      pnode->z - img_z );

      }
  std::cout << " invalid voxel count = " << invalidCount << std::endl;
  if ( !g_vDbgCoords.empty() )
  {
    int x,y,z;

    pnode = &gcam->nodes[gcam->width/2][gcam->height/2][gcam->depth/2];

    for (unsigned int ui=0; ui<3; ++ui)
      VECTOR_ELT(vx, ui+1) = g_vDbgCoords[ui];

    MATRIX* minv = MatrixInverse(transform, NULL);
    MatrixMultiply(minv, vx, vfx);

    std::cout << " debugging at coords = \n";
    std::copy( g_vDbgCoords.begin(), g_vDbgCoords.end(),
               std::ostream_iterator<int>( std::cout, " ") );
    std::cout << std::endl;

    x = myNint( VECTOR_ELT( vfx, 1) );
    y = myNint( VECTOR_ELT( vfx, 2) );
    z = myNint( VECTOR_ELT( vfx, 3) );

    std::cout << " linear transf to get gcam xyz = "
    << x << " , " << y << " , " << z << std::endl;
    if ( x < 0 || x > gcam->width -1 ||
         y < 0 || y > gcam->height-1 ||
         z < 0 || z > gcam->depth -1 )
      std::cout << " out of bounds\n";
    else
    {
      pnode = &gcam->nodes[x][y][z];
      std::cout << " value of gcam = "
      << pnode->x << " , "
      << pnode->y << " , "
      << pnode->z << std::endl;
    }
  }


//   for( int z(0), maxZ(field->depth); z<maxZ; ++z)
//     for( int y(0), maxY(field->height); y<maxY; ++y)
//       for( int x(0), maxX(field->width); x<maxX; ++x)
//  {

//    if ( !GCAMsampleMorph(gcam, x,y,z,
//     &pxd, &pyd, &pzd) )
//      {
//        MRIvox(mask, x,y,z) = ucZero;
//        maskCounter++;
//        continue;
//      }
//    MRIsetVoxVal( field, x,y,z, 0,
//    pxd - x );
//    MRIsetVoxVal( field, x,y,z, 1,
//    pyd - y );
//    MRIsetVoxVal( field, x,y,z, 2,
//    pzd - z );

//  } // next x,y,z

  if ( !maskCounter )
  {
    MRIfree(&mask);
    return NULL;
  }
  return mask;
}
コード例 #22
0
ファイル: ctrpoints.c プロジェクト: ewong718/freesurfer
// (mr) uses LTA to map point array:
MPoint *MRImapControlPoints(const MPoint *pointArray, int count, int useRealRAS,
                            MPoint *trgArray, LTA* lta)
{
	if (trgArray == NULL)
     trgArray=(MPoint*) malloc(count* sizeof(MPoint));

  if (! lta->xforms[0].src.valid )
    ErrorExit(ERROR_BADPARM,"MRImapControlPoints LTA src geometry not valid!\n");
  if (! lta->xforms[0].dst.valid )
    ErrorExit(ERROR_BADPARM,"MRImapControlPoints LTA dst geometry not valid!\n");

  // create face src and target mri from lta:
	MRI* mri_src = MRIallocHeader(1,1,1,MRI_UCHAR,1);
	useVolGeomToMRI(&lta->xforms[0].src,mri_src);
	MRI* mri_trg = MRIallocHeader(1,1,1,MRI_UCHAR,1);
	useVolGeomToMRI(&lta->xforms[0].dst,mri_trg);

  // set vox ras transforms depending on flag:
  MATRIX * src_ras2vox, *trg_vox2ras;
  switch (useRealRAS)
  {
    case 0:
		{
      MATRIX * src_vox2ras = MRIxfmCRS2XYZtkreg(mri_src);
      src_ras2vox = MatrixInverse(src_vox2ras,NULL);	
	  	MatrixFree(&src_vox2ras);
      trg_vox2ras = MRIxfmCRS2XYZtkreg(mri_trg);
      break;
		}
    case 1:
		{
      src_ras2vox = extract_r_to_i(mri_src);
      trg_vox2ras = extract_i_to_r(mri_trg);
      break;
		}
    default:
      ErrorExit(ERROR_BADPARM,
                "MRImapControlPoints has bad useRealRAS flag %d\n",
                useRealRAS) ;
  }
	
	// make vox2vox:
	lta = LTAchangeType(lta,LINEAR_VOX_TO_VOX);

  // concatenate transforms:
  MATRIX *M = NULL;
	M = MatrixMultiply(lta->xforms[0].m_L, src_ras2vox, M);
	M = MatrixMultiply(trg_vox2ras, M, M);
	
	// clenup some stuff:
	MRIfree(&mri_src);
	MRIfree(&mri_trg);
	MatrixFree(&src_ras2vox);
	MatrixFree(&trg_vox2ras);
	
	// map point array
  VECTOR * p  = VectorAlloc(4,MATRIX_REAL);
	VECTOR_ELT(p,4)=1.0;
  VECTOR * p2 = VectorAlloc(4,MATRIX_REAL);
	int i;
	for (i=0;i<count;i++)
	{
    VECTOR_ELT(p,1)=pointArray[i].x;
		VECTOR_ELT(p,2)=pointArray[i].y;
		VECTOR_ELT(p,3)=pointArray[i].z;
		MatrixMultiply(M, p, p2) ;
    trgArray[i].x=VECTOR_ELT(p2,1);
    trgArray[i].y=VECTOR_ELT(p2,2);
    trgArray[i].z=VECTOR_ELT(p2,3);
	}
	
	// cleanup rest
	MatrixFree(&M);
	MatrixFree(&p);
	MatrixFree(&p2);
	
  return trgArray;
}
コード例 #23
0
ファイル: mri_normalize.c プロジェクト: ewong718/freesurfer
static int
remove_nonwm_voxels(MRI *mri_ctrl_src, MRI *mri_aseg, MRI *mri_ctrl_dst)
{
  int   x, y, z, label, removed = 0, xa, ya, za ;
  MATRIX *m_vox_to_vox ;
  VECTOR *v_src, *v_dst ;

  m_vox_to_vox = MRIgetVoxelToVoxelXform(mri_ctrl_src, mri_aseg) ;
  v_src = VectorAlloc(4,1) ;
  v_dst = VectorAlloc(4,1) ;
  VECTOR_ELT(v_src, 4) = VECTOR_ELT(v_dst,4) = 1 ;

  for (x = 0 ; x < mri_ctrl_src->width ; x++)
    for (y = 0 ; y < mri_ctrl_src->height ; y++)
      for (z = 0 ; z < mri_ctrl_src->depth ; z++)
      {
        if (x == Gx && y == Gy && z == Gz)
        {
          DiagBreak() ;
        }
        if (MRIgetVoxVal(mri_ctrl_src, x, y, z, 0) == 0)
        {
          continue ;
        }
        V3_X(v_src) = x ;
        V3_Y(v_src) = y ;
        V3_Z(v_src) = z ;
        MatrixMultiply(m_vox_to_vox, v_src, v_dst) ;
        xa = nint(V3_X(v_dst)) ;
        ya = nint(V3_Y(v_dst)) ;
        za = nint(V3_Z(v_dst));
        label = MRIgetVoxVal(mri_aseg, xa, ya, za, 0) ;
        switch (label)
        {
        case Left_Thalamus_Proper:
        case Left_Lateral_Ventricle:
        case Left_Caudate:
        case Left_Putamen:
        case Left_Pallidum:
        case Left_Amygdala:
        case Left_Hippocampus:
        case Left_Cerebellum_Cortex:
        case Left_Inf_Lat_Vent:

        case Right_Thalamus_Proper:
        case Right_Lateral_Ventricle:
        case Right_Caudate:
        case Right_Putamen:
        case Right_Pallidum:
        case Right_Amygdala:
        case Right_Hippocampus:
        case Right_Cerebellum_Cortex:
        case Right_Inf_Lat_Vent:
        case Third_Ventricle:
        case Fourth_Ventricle:
        case Unknown:
          removed++ ;
          MRIsetVoxVal(mri_ctrl_dst, x, y, z, 0, CONTROL_NONE) ;
          break ;
        default:
          MRIsetVoxVal(mri_ctrl_dst, x, y, z, 0, CONTROL_MARKED) ;
          break ;
        }
      }

  printf("%d non wm control points removed\n", removed) ;
  return(NO_ERROR) ;
}
コード例 #24
0
static MATRIX *
pca_matrix(MATRIX *m_in_evectors, double in_means[3],
           MATRIX *m_ref_evectors, double ref_means[3]) {
  float   dx, dy, dz ;
  MATRIX  *mRot, *m_in_T, *mOrigin, *m_L, *m_R, *m_T, *m_tmp ;
  double  x_angle, y_angle, z_angle, r11, r21, r31, r32, r33, cosy ;
  int     row, col ;

  m_in_T = MatrixTranspose(m_in_evectors, NULL) ;
  mRot = MatrixMultiply(m_ref_evectors, m_in_T, NULL) ;

  r11 = mRot->rptr[1][1] ;
  r21 = mRot->rptr[2][1] ;
  r31 = mRot->rptr[3][1] ;
  r32 = mRot->rptr[3][2] ;
  r33 = mRot->rptr[3][3] ;
  y_angle = atan2(-r31, sqrt(r11*r11+r21*r21)) ;
  cosy = cos(y_angle) ;
  z_angle = atan2(r21 / cosy, r11 / cosy) ;
  x_angle = atan2(r32 / cosy, r33 / cosy) ;

#define MAX_ANGLE  (RADIANS(30))
  if (fabs(x_angle) > MAX_ANGLE || fabs(y_angle) > MAX_ANGLE ||
      fabs(z_angle) > MAX_ANGLE) {
    MatrixFree(&m_in_T) ;
    MatrixFree(&mRot) ;
    printf("eigenvector swap detected: ignoring PCA...\n") ;
    return(MatrixIdentity(4, NULL)) ;
  }

  mOrigin = VectorAlloc(3, MATRIX_REAL) ;
  mOrigin->rptr[1][1] = ref_means[0] ;
  mOrigin->rptr[2][1] = ref_means[1] ;
  mOrigin->rptr[3][1] = ref_means[2] ;

  printf("reference volume center of mass at (%2.1f,%2.1f,%2.1f)\n",
         ref_means[0], ref_means[1], ref_means[2]) ;
  printf("input volume center of mass at     (%2.1f,%2.1f,%2.1f)\n",
         in_means[0], in_means[1], in_means[2]) ;
  dx = ref_means[0] - in_means[0] ;
  dy = ref_means[1] - in_means[1] ;
  dz = ref_means[2] - in_means[2] ;

  printf("translating volume by %2.1f, %2.1f, %2.1f\n",
         dx, dy, dz) ;
  printf("rotating volume by (%2.2f, %2.2f, %2.2f)\n",
         DEGREES(x_angle), DEGREES(y_angle), DEGREES(z_angle)) ;

  /* build full rigid transform */
  m_R = MatrixAlloc(4,4,MATRIX_REAL) ;
  m_T = MatrixAlloc(4,4,MATRIX_REAL) ;
  for (row = 1 ; row <= 3 ; row++) {
    for (col = 1 ; col <= 3 ; col++) {
      *MATRIX_RELT(m_R,row,col) = *MATRIX_RELT(mRot, row, col) ;
    }
    *MATRIX_RELT(m_T,row,row) = 1.0 ;
  }
  *MATRIX_RELT(m_R, 4, 4) = 1.0 ;

  /* translation so that origin is at ref eigenvector origin */
  dx = -ref_means[0] ;
  dy = -ref_means[1] ;
  dz = -ref_means[2] ;
  *MATRIX_RELT(m_T, 1, 4) = dx ;
  *MATRIX_RELT(m_T, 2, 4) = dy ;
  *MATRIX_RELT(m_T, 3, 4) = dz ;
  *MATRIX_RELT(m_T, 4, 4) = 1 ;
  m_tmp = MatrixMultiply(m_R, m_T, NULL) ;
  *MATRIX_RELT(m_T, 1, 4) = -dx ;
  *MATRIX_RELT(m_T, 2, 4) = -dy ;
  *MATRIX_RELT(m_T, 3, 4) = -dz ;
  MatrixMultiply(m_T, m_tmp, m_R) ;

  /* now apply translation to take in centroid to ref centroid */
  dx = ref_means[0] - in_means[0] ;
  dy = ref_means[1] - in_means[1] ;
  dz = ref_means[2] - in_means[2] ;
  *MATRIX_RELT(m_T, 1, 4) = dx ;
  *MATRIX_RELT(m_T, 2, 4) = dy ;
  *MATRIX_RELT(m_T, 3, 4) = dz ;
  *MATRIX_RELT(m_T, 4, 4) = 1 ;

  m_L = MatrixMultiply(m_R, m_T, NULL) ;
  if (Gdiag & DIAG_SHOW && DIAG_VERBOSE_ON) {
    printf("m_T:\n") ;
    MatrixPrint(stdout, m_T) ;
    printf("m_R:\n") ;
    MatrixPrint(stdout, m_R) ;
    printf("m_L:\n") ;
    MatrixPrint(stdout, m_L) ;
  }
  MatrixFree(&m_R) ;
  MatrixFree(&m_T) ;

  MatrixFree(&mRot) ;
  VectorFree(&mOrigin) ;
  return(m_L) ;
}
コード例 #25
0
ファイル: inverse.c プロジェクト: ewong718/freesurfer
IOP *
IOPRead(char *fname, int hemi)
{
  IOP   *iop ;
  int   i,j,k,jc,d, dipoles_in_decimation ;
  FILE  *fp;
  char  c,str[STRLEN];
  float f;
  int   z ;

  printf("read_iop(%s,%d)\n",fname,hemi);

  fp = fopen(fname,"r");
  if (fp==NULL)
    ErrorReturn(NULL,
                (ERROR_NOFILE, "IOPRead: can't open file %s\n",fname));
  iop = calloc(1, sizeof(IOP)) ;
  if (!iop)
    ErrorReturn(NULL,
                (ERROR_NOMEMORY, "IOPRead: can't allocate struct\n"));
  iop->pthresh = 1000;
  c = getc(fp);
  if (c=='#')
  {
    fscanf(fp,"%s",str);
    if (!strcmp(str,"version"))
      fscanf(fp,"%d",&iop->version);
    printf("iop version = %d\n",iop->version);
    fscanf(fp,"%d %d %d %d",
           &iop->neeg_channels,
           &iop->nmeg_channels,
           &iop->ndipoles_per_location,
           &iop->ndipole_files);

    iop->nchan = iop->neeg_channels+iop->nmeg_channels;
    for (i=1;i<=hemi;i++)
    {
      fscanf(fp,"%d %d",&dipoles_in_decimation,&iop->ndipoles);
      if (i==hemi)
      {
#if 0
        if (iop->ndipoles_per_location != sol_ndec)
        {
          fclose(fp);
          IOPFree(&iop) ;
          ErrorReturn(NULL,
                      (ERROR_BADFILE,
                       "IOPRead: .dec and .iop file mismatch (%d!=%d)\n",
                       sol_ndec,iop->ndipoles_per_location));
        }
#endif
        iop->m_iop =
          MatrixAlloc(iop->ndipoles*iop->ndipoles_per_location,iop->nchan,
                      MATRIX_REAL);
        if (iop->version==1)
          iop->m_forward =
            MatrixAlloc(iop->nchan,iop->ndipoles*iop->ndipoles_per_location,
                        MATRIX_REAL);

#if 0
        sol_M = matrix(iop->nchan,iop->nchan); /* temporary space for xtalk */
        sol_Mi = matrix(iop->nchan,iop->nchan);
        sol_sensvec1 = vector(iop->nchan);
        sol_sensvec2 = vector(iop->nchan);
        sol_sensval = vector(iop->nchan);
#endif

        iop->dipole_normalization = calloc(iop->ndipoles, sizeof(float));
        iop->dipole_vertices = calloc(iop->ndipoles, sizeof(int));
        if (!iop->dipole_vertices)
          ErrorReturn(NULL,
                      (ERROR_NOMEMORY,
                       "IOPRead: could not allocated %d v indices",
                       iop->ndipoles)) ;
        iop->pvals = VectorAlloc(iop->ndipoles, MATRIX_REAL);
        iop->spatial_priors = VectorAlloc(iop->ndipoles, MATRIX_REAL);


        iop->bad_sensors = calloc(iop->nchan, sizeof(int));
        if (!iop->bad_sensors)
          ErrorReturn(NULL,
                      (ERROR_NOMEMORY,
                       "IOPRead: could not allocate bad sensor array",
                       iop->nchan)) ;

        /* initialize bad sensor locations*/
        for (z=0;z<iop->nchan;z++)
          iop->bad_sensors[z] = 0;

      }
      for (j=0;j<iop->ndipoles;j++)
      {
        if (i==hemi)
        {
          fscanf(fp,"%d",&d);
          iop->dipole_vertices[j] = d;
        }
        else
          fscanf(fp,"%*d");
      }
      for (j=0;j<iop->ndipoles;j++)
      {
        if (i==hemi)
        {
          fscanf(fp,"%f",&f);
          *MATRIX_RELT(iop->pvals,j+1,1) = f;
          f = fabs(f);
          if (f<iop->pthresh)
            iop->pthresh = f;
        }
        else
          fscanf(fp,"%*f");
      }
      for (j=0;j<iop->ndipoles;j++)
      {
        if (i==hemi)
        {
          fscanf(fp,"%f",&f);
          *MATRIX_RELT(iop->spatial_priors,j+1,1) = f;
#if 0
          vertex[iop->dipole_vertices[j]].val = f;
#endif
        }
        else
          fscanf(fp,"%*f");
      }
      for (j=0;j<iop->ndipoles;j++)
      {
        for (jc=0;jc<iop->ndipoles_per_location;jc++)
        {
          for (k=0;k<iop->nchan;k++)
          {
            if (i==hemi)
            {
              fscanf(fp,"%f",&f);
              *MATRIX_RELT(iop->m_iop, j*iop->ndipoles_per_location+jc+1,k+1)
              = f;
            }
            else
              fscanf(fp,"%*f");
          }
        }
      }
      if (iop->version==1)
      {
        for (j=0;j<iop->ndipoles;j++)
        {
          for (jc=0;jc<iop->ndipoles_per_location;jc++)
          {
            for (k=0;k<iop->nchan;k++)
            {
              if (i==hemi)
              {
                fscanf(fp,"%f",&f);
                *MATRIX_RELT(iop->m_forward,
                             k+1,
                             j*iop->ndipoles_per_location+jc+1) = f;
              }
              else
                fscanf(fp,"%*f");
            }
          }
        }
      }
    }
  }
  else
  {
    printf("Can't read binary .iop files\n");
  }
  fclose(fp);
  printf("neeg_channels=%d, nmeg_channels=%d, iop->ndipoles_per_location=%d, "
         "iop->ndipole_files=%d\n",
         iop->neeg_channels, iop->nmeg_channels,iop->ndipoles_per_location,
         iop->ndipole_files);
  return(iop) ;
}
コード例 #26
0
int
main(int argc, char *argv[]) {
  TRANSFORM    *transform = NULL ;
  char         **av, fname[STRLEN], *gca_fname, *subject_name, *cp ;
  int          ac, nargs, i, n ;
  int          msec, minutes, seconds, nsubjects ;
  struct timeb start ;
  GCA          *gca ;
  MRI          *mri_parc, *mri_T1, *mri_PD ;
  FILE         *fp ;

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

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

  TimerStart(&start) ;

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

  if (!strlen(subjects_dir)) /* hasn't been set on command line */
  {
    cp = getenv("SUBJECTS_DIR") ;
    if (!cp)
      ErrorExit(ERROR_BADPARM, "%s: SUBJECTS_DIR not defined in environment",
                Progname);
    strcpy(subjects_dir, cp) ;
    if (argc < 3)
      usage_exit(1) ;
  }


  gca_fname = argv[1] ;
  nsubjects = argc-2 ;
  printf("computing average tissue parameters on %d subject\n",
         nsubjects) ;

  n = 0 ;

  printf("reading GCA from %s...\n", gca_fname) ;
  gca = GCAread(gca_fname) ;

  for (i = 0 ; i < nsubjects ; i++) {
    subject_name = argv[i+2] ;
    printf("processing subject %s, %d of %d...\n", subject_name,i+1,
           nsubjects);
    sprintf(fname, "%s/%s/mri/%s", subjects_dir, subject_name, parc_dir) ;
    if (DIAG_VERBOSE_ON)
      printf("reading parcellation from %s...\n", fname) ;
    mri_parc = MRIread(fname) ;
    if (!mri_parc)
      ErrorExit(ERROR_NOFILE, "%s: could not read parcellation file %s",
                Progname, fname) ;

    sprintf(fname, "%s/%s/mri/%s", subjects_dir, subject_name, T1_name) ;
    if (DIAG_VERBOSE_ON)
      printf("reading co-registered T1 from %s...\n", fname) ;
    mri_T1 = MRIread(fname) ;
    if (!mri_T1)
      ErrorExit(ERROR_NOFILE, "%s: could not read T1 data from file %s",
                Progname, fname) ;

    sprintf(fname, "%s/%s/mri/%s", subjects_dir, subject_name, PD_name) ;
    if (DIAG_VERBOSE_ON)
      printf("reading co-registered T1 from %s...\n", fname) ;
    mri_PD = MRIread(fname) ;
    if (!mri_PD)
      ErrorExit(ERROR_NOFILE, "%s: could not read PD data from file %s",
                Progname, fname) ;


    if (xform_name) {
      /*      VECTOR *v_tmp, *v_tmp2 ;*/

      sprintf(fname, "%s/%s/mri/%s", subjects_dir, subject_name, xform_name) ;
      printf("reading xform from %s...\n", fname) ;
      transform = TransformRead(fname) ;
      if (!transform)
        ErrorExit(ERROR_NOFILE, "%s: could not read xform from %s",
                  Progname, fname) ;
#if 0
      v_tmp = VectorAlloc(4,MATRIX_REAL) ;
      *MATRIX_RELT(v_tmp,4,1)=1.0 ;
      v_tmp2 = MatrixMultiply(lta->xforms[0].m_L, v_tmp, NULL) ;
      printf("RAS (0,0,0) -->\n") ;
      MatrixPrint(stdout, v_tmp2) ;
#endif

      if (transform->type == LINEAR_RAS_TO_RAS) {
        MATRIX *m_L ;
        m_L = ((LTA *)transform->xform)->xforms[0].m_L ;
        MRIrasXformToVoxelXform(mri_parc, mri_T1, m_L,m_L) ;
      }
#if 0
      v_tmp2 = MatrixMultiply(lta->xforms[0].m_L, v_tmp, v_tmp2) ;
      printf("voxel (0,0,0) -->\n") ;
      MatrixPrint(stdout, v_tmp2) ;
      VectorFree(&v_tmp) ;
      VectorFree(&v_tmp2) ;
      test(mri_parc, mri_T1, mri_PD, lta->xforms[0].m_L) ;
#endif
    }
    if (histo_parms)
      GCAhistogramTissueStatistics(gca,mri_T1,mri_PD,mri_parc,transform,histo_parms);
#if 0
    else
      GCAaccumulateTissueStatistics(gca, mri_T1, mri_PD, mri_parc, transform) ;
#endif

    MRIfree(&mri_parc) ;
    MRIfree(&mri_T1) ;
    MRIfree(&mri_PD) ;
  }
  GCAnormalizeTissueStatistics(gca) ;

  if (log_fname) {
    printf("writing tissue parameters to %s\n", log_fname) ;
    fp = fopen(log_fname, "w") ;
    for (n = 1 ; n < MAX_GCA_LABELS ; n++) {
      GCA_TISSUE_PARMS *gca_tp ;

      gca_tp = &gca->tissue_parms[n] ;
      if (gca_tp->total_training <= 0)
        continue ;
      fprintf(fp, "%d  %f  %f\n", n, gca_tp->T1_mean, gca_tp->PD_mean) ;
    }
    fclose(fp) ;
  }

  if (write_flag)
    GCAwrite(gca, gca_fname) ;
  GCAfree(&gca) ;
  msec = TimerStop(&start) ;
  seconds = nint((float)msec/1000.0f) ;
  minutes = seconds / 60 ;
  seconds = seconds % 60 ;
  printf("tissue parameter statistic calculation took %d minutes"
         " and %d seconds.\n", minutes, seconds) ;
  exit(0) ;
  return(0) ;
}
コード例 #27
0
ファイル: mri_nl_align.c プロジェクト: guo2004131/freesurfer
int
main(int argc, char *argv[])
{
  char         **av, *source_fname, *target_fname, *out_fname, fname[STRLEN] ;
  int          ac, nargs, new_transform = 0, pad ;
  MRI          *mri_target, *mri_source, *mri_orig_source ;
  MRI_REGION   box ;
  struct timeb start ;
  int          msec, minutes, seconds ;
  GCA_MORPH    *gcam ;
  MATRIX       *m_L/*, *m_I*/ ;
  LTA          *lta ;


  /* initialize the morph params */
  memset(&mp, 0, sizeof(GCA_MORPH_PARMS));
  /* for nonlinear morph */
  mp.l_jacobian = 1 ;
  mp.min_sigma = 0.4 ;
  mp.l_distance = 0 ;
  mp.l_log_likelihood = .025 ;
  mp.dt = 0.005 ;
  mp.noneg = True ;
  mp.exp_k = 20 ;
  mp.diag_write_snapshots = 1 ;
  mp.momentum = 0.9 ;
  if (FZERO(mp.l_smoothness))
    mp.l_smoothness = 2 ;
  mp.sigma = 8 ;
  mp.relabel_avgs = -1 ;
  mp.navgs = 256 ;
  mp.levels = 6 ;
  mp.integration_type = GCAM_INTEGRATE_BOTH ;
  mp.nsmall = 1 ;
  mp.reset_avgs = -1 ;
  mp.npasses = 3 ;
  mp.regrid = regrid? True : False ;
  mp.tol = 0.1 ;
  mp.niterations = 1000 ;
	
  TimerStart(&start) ;
  setRandomSeed(-1L) ;
  DiagInit(NULL, NULL, NULL) ;
  ErrorInit(NULL, NULL, NULL) ;

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

  if (argc < 4)
    usage_exit(1) ;

  source_fname = argv[1] ;
  target_fname = argv[2] ;
  out_fname = argv[3] ;
  FileNameOnly(out_fname, fname) ;
  FileNameRemoveExtension(fname, fname) ;
  strcpy(mp.base_name, fname) ;
  mri_source = MRIread(source_fname) ;
  if (!mri_source)
    ErrorExit(ERROR_NOFILE, "%s: could not read source label volume %s",
	      Progname, source_fname) ;

  if (mri_source->type == MRI_INT)
    {
      MRI *mri_tmp = MRIchangeType(mri_source, MRI_FLOAT, 0, 1, 1) ;
      MRIfree(&mri_source); mri_source = mri_tmp ;
    }
  mri_target = MRIread(target_fname) ;
  if (!mri_target)
    ErrorExit(ERROR_NOFILE, "%s: could not read target label volume %s",
	      Progname, target_fname) ;
  if (mri_target->type == MRI_INT)
    {
      MRI *mri_tmp = MRIchangeType(mri_target, MRI_FLOAT, 0, 1, 1) ;
      MRIfree(&mri_target); mri_target = mri_tmp ;
    }
  if (erosions > 0)
    {
      int n ;
      for (n = 0 ; n < erosions ; n++)
	{
	  MRIerodeZero(mri_target, mri_target) ;
	  MRIerodeZero(mri_source, mri_source) ;
	}
    }
  if (scale_values > 0)
    {
      MRIscalarMul(mri_source, mri_source, scale_values) ;
      MRIscalarMul(mri_target, mri_target, scale_values) ;
    }
  if (transform && transform->type == MORPH_3D_TYPE)
    TransformRas2Vox(transform, mri_source,NULL) ;
  if (use_aseg == 0)
    {
      if (match_peak_intensity_ratio)
	MRImatchIntensityRatio(mri_source, mri_target, mri_source, .8, 1.2, 
			       100, 125) ;
      else if (match_mean_intensity)
	MRImatchMeanIntensity(mri_source, mri_target, mri_source) ;
      MRIboundingBox(mri_source, 0, &box) ;
      pad = (int)ceil(PADVOX * 
		      MAX(mri_target->xsize,MAX(mri_target->ysize,mri_target->zsize)) / 
		      MIN(mri_source->xsize,MIN(mri_source->ysize,mri_source->zsize))); 
#if 0
      { MRI *mri_tmp ;
	if (pad < 1)
	  pad = 1 ;
	printf("padding source with %d voxels...\n", pad) ;
	mri_tmp = MRIextractRegionAndPad(mri_source, NULL, &box, pad) ;
	if ((Gdiag & DIAG_WRITE) && DIAG_VERBOSE_ON)
	  MRIwrite(mri_tmp, "t.mgz") ;
	MRIfree(&mri_source) ;
	mri_source = mri_tmp ;
      }
#endif
    }
  mri_orig_source = MRIcopy(mri_source, NULL) ;

  mp.max_grad = 0.3*mri_source->xsize ;

  if (transform == NULL)
    transform = TransformAlloc(LINEAR_VOXEL_TO_VOXEL, NULL) ;

  if (transform->type != MORPH_3D_TYPE)  // initializing m3d from a linear transform
    {
      new_transform = 1 ;
      lta = ((LTA *)(transform->xform)) ;
      if (lta->type != LINEAR_VOX_TO_VOX)
	{
	  printf("converting ras xform to voxel xform\n") ;
	  m_L = MRIrasXformToVoxelXform(mri_source, mri_target, lta->xforms[0].m_L, NULL) ;
	  MatrixFree(&lta->xforms[0].m_L) ;
	  lta->type = LINEAR_VOX_TO_VOX ;
	}
      else
	{
	  printf("using voxel xform\n") ;
	  m_L = lta->xforms[0].m_L ;
	}
#if 0
      if (Gsx >= 0)   // update debugging coords
	{
	  VECTOR *v1, *v2 ;

	  v1 = VectorAlloc(4, MATRIX_REAL) ;
	  Gsx -= (box.x-pad) ;
	  Gsy -= (box.y-pad) ;
	  Gsz -= (box.z-pad) ;
	  V3_X(v1) = Gsx ; V3_Y(v1) = Gsy ; V3_Z(v1) = Gsz ;
	  VECTOR_ELT(v1,4) = 1.0 ;
	  v2 = MatrixMultiply(m_L, v1, NULL) ;
      
	  Gsx = nint(V3_X(v2)) ; Gsy = nint(V3_Y(v2)) ; Gsz = nint(V3_Z(v2)) ;
	  MatrixFree(&v2) ; MatrixFree(&v1) ;
	  printf("mapping by transform (%d, %d, %d) --> (%d, %d, %d) for rgb writing\n",
		 Gx, Gy, Gz, Gsx, Gsy, Gsz) ;
	}
#endif
      if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
	write_snapshot(mri_target, mri_source, m_L, &mp, 0, 1, "linear_init");

      lta->xforms[0].m_L = m_L ;
      printf("initializing GCAM with vox->vox matrix:\n") ;
      MatrixPrint(stdout, m_L) ;
      gcam = GCAMcreateFromIntensityImage(mri_source, mri_target, transform) ;
#if 0
      gcam->gca = gcaAllocMax(1, 1, 1, 
			      mri_target->width, mri_target->height, 
			      mri_target->depth,
			      0, 0) ;
#endif
      GCAMinitVolGeom(gcam, mri_source, mri_target) ;
      if (use_aseg)
	{
	  if (ribbon_name)
	    {
	      char fname[STRLEN], path[STRLEN], *str, *hemi ;
	      int  h, s, label ;
	      MRI_SURFACE *mris_white, *mris_pial ;
	      MRI         *mri ;

	      for (s = 0 ; s <= 1 ; s++) // source and target
		{
		  if (s == 0)
		    {
		      str = source_surf ;
		      mri = mri_source ;
		      FileNamePath(mri->fname, path) ;
		      strcat(path, "/../surf") ;
		    }
		  else
		    {
		      mri = mri_target ;
		      FileNamePath(mri->fname, path) ;
		      strcat(path, "/../elastic") ;
		      str = target_surf ;
		    }
		  // sorry - these values come from FreeSurferColorLUT.txt
		  MRIreplaceValueRange(mri, mri, 1000, 1034, Left_Cerebral_Cortex) ;
		  MRIreplaceValueRange(mri, mri, 1100, 1180, Left_Cerebral_Cortex) ;
		  MRIreplaceValueRange(mri, mri, 2000, 2034, Right_Cerebral_Cortex) ;
		  MRIreplaceValueRange(mri, mri, 2100, 2180, Right_Cerebral_Cortex) ;
		  for (h = LEFT_HEMISPHERE ; h <= RIGHT_HEMISPHERE ; h++)  
		    {
		      if (h == LEFT_HEMISPHERE)
			{
			  hemi = "lh" ;
			  label = Left_Cerebral_Cortex ;
			}
		      else
			{
			  label = Right_Cerebral_Cortex ;
			  hemi = "rh" ;
			}
		      sprintf(fname, "%s/%s%s.white", path, hemi, str) ;
		      mris_white = MRISread(fname) ;
		      if (mris_white == NULL)
			ErrorExit(ERROR_NOFILE, "%s: could not read surface %s", Progname, fname) ;
		      MRISsaveVertexPositions(mris_white, WHITE_VERTICES) ;
		      sprintf(fname, "%s/%s%s.pial", path, hemi, str) ;
		      mris_pial = MRISread(fname) ;
		      if (mris_pial == NULL)
			ErrorExit(ERROR_NOFILE, "%s: could not read surface %s", Progname, fname) ;
		      MRISsaveVertexPositions(mris_pial, PIAL_VERTICES) ;
		      if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
			{
			  sprintf(fname, "sb.mgz") ;
			  MRIwrite(mri_source, fname) ; 
			  sprintf(fname, "tb.mgz") ;
			  MRIwrite(mri_target, fname) ;
			}

		      insert_ribbon_into_aseg(mri, mri, mris_white, mris_pial, h) ;
		      if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
			{
			  sprintf(fname, "sa.mgz") ;
			  MRIwrite(mri_source, fname) ; 
			  sprintf(fname, "ta.mgz") ;
			  MRIwrite(mri_target, fname) ;
			}
		      MRISfree(&mris_white) ; MRISfree(&mris_pial) ;
		    }
		}
	      if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON)
		{
		  sprintf(fname, "s.mgz") ;
		  MRIwrite(mri_source, fname) ; 
		  sprintf(fname, "t.mgz") ;
		  MRIwrite(mri_target, fname) ;
		}
	    }
	  GCAMinitLabels(gcam, mri_target) ;
	  GCAMsetVariances(gcam, 1.0) ;
	  mp.mri_dist_map = create_distance_transforms(mri_source, mri_target, NULL, 40.0, gcam) ;
	}
    }
  else  /* use a previously create morph and integrate it some more */
    {
      printf("using previously create gcam...\n") ;
      gcam = (GCA_MORPH *)(transform->xform) ;
      GCAMrasToVox(gcam, mri_source) ;
      if (use_aseg)
	{
	  GCAMinitLabels(gcam, mri_target) ;
	  GCAMsetVariances(gcam, 1.0) ;
	  mp.mri_dist_map = create_distance_transforms(mri_source, mri_target, NULL, 40.0, gcam) ;
	}
      else
	GCAMaddIntensitiesFromImage(gcam, mri_target) ;
    }
  if (gcam->width != mri_source->width ||
      gcam->height != mri_source->height ||
      gcam->depth != mri_source->depth)
    ErrorExit(ERROR_BADPARM, "%s: warning gcam (%d, %d, %d), doesn't match source vol (%d, %d, %d)",
	      Progname, gcam->width, gcam->height, gcam->depth,
	      mri_source->width, mri_source->height, mri_source->depth) ;
	
  mp.mri_diag = mri_source ;
  mp.diag_morph_from_atlas = 0 ;
  mp.diag_write_snapshots = 1 ;
  mp.diag_sample_type = use_aseg ? SAMPLE_NEAREST : SAMPLE_TRILINEAR ;
  mp.diag_volume = use_aseg ? GCAM_LABEL : GCAM_MEANS ;

  if (renormalize)
    GCAMnormalizeIntensities(gcam, mri_target) ;
  if (mp.write_iterations != 0)
    {
      char fname[STRLEN] ;
      MRI  *mri_gca ;
		
      if (getenv("DONT_COMPRESS"))
        sprintf(fname, "%s_target.mgh", mp.base_name) ;
      else
        sprintf(fname, "%s_target.mgz", mp.base_name) ;
      if (mp.diag_morph_from_atlas == 0)
      {
        printf("writing target volume to %s...\n", fname) ;
        MRIwrite(mri_target, fname) ;
        sprintf(fname, "%s_target", mp.base_name) ;
        MRIwriteImageViews(mri_target, fname, IMAGE_SIZE) ;
      }
      else
      {
        if (use_aseg)
          mri_gca = GCAMwriteMRI(gcam, NULL, GCAM_LABEL) ;
        else
        {
          mri_gca = MRIclone(mri_source, NULL) ;
          GCAMbuildMostLikelyVolume(gcam, mri_gca) ;
        }
	  printf("writing target volume to %s...\n", fname) ;
	  MRIwrite(mri_gca, fname) ;
	  sprintf(fname, "%s_target", mp.base_name) ;
	  MRIwriteImageViews(mri_gca, fname, IMAGE_SIZE) ;
	  MRIfree(&mri_gca) ;
	}
    }

  if (nozero)
    {
      printf("disabling zero nodes\n") ;
      GCAMignoreZero(gcam, mri_target) ;
    }
  mp.mri = mri_target ;
  if (mp.regrid == True && new_transform == 0)
    GCAMregrid(gcam, mri_target, PAD, &mp, &mri_source) ;

  mp.write_fname = out_fname ;
  GCAMregister(gcam, mri_source, &mp) ; // atlas is target, morph target into register with it
  if (apply_transform)
    {
      MRI *mri_aligned ;
      char   fname[STRLEN] ;
		
      FileNameRemoveExtension(out_fname, fname) ;
      strcat(fname, ".mgz") ;
      mri_aligned = GCAMmorphToAtlas(mp.mri, gcam, NULL, -1, mp.diag_sample_type) ;
      printf("writing transformed output volume to %s...\n", fname) ;
      MRIwrite(mri_aligned, fname) ;
      MRIfree(&mri_aligned) ;
    }
  printf("writing warp vector field to %s\n", out_fname) ;
  GCAMvoxToRas(gcam) ;
  GCAMwrite(gcam, out_fname) ;
  GCAMrasToVox(gcam, mri_source) ;

  msec = TimerStop(&start) ;
  seconds = nint((float)msec/1000.0f) ;
  minutes = seconds / 60 ;
  seconds = seconds % 60 ;
  printf("registration took %d minutes and %d seconds.\n", 
	 minutes, seconds) ;
  exit(0) ;
  return(0) ;
}
コード例 #28
0
static CLUSTER *
MRISclusterAgglomerative(MRI_SURFACE *mris, MRI *mri_profiles, int k,
                         char *start_fname, MRI_SURFACE *mris_ico) {
  int    i, nsamples, iter, done, vno, cluster ;
  char   fname[STRLEN] ;
  CLUSTER *ct ;

  if (start_fname) {
    VERTEX *v ;

    if (MRISreadAnnotation(mris, start_fname) != NO_ERROR)
      ErrorExit(ERROR_NOFILE, "%s: could not read initial annotation file %s",
                Progname, start_fname) ;
    k = 0 ;
    for (vno = 0 ; vno < mris->nvertices ; vno++) {
      v = &mris->vertices[vno] ;
      if (v->annotation == 0) {
        v->ripflag = 1;
        continue ;
      }
      CTABfindAnnotation(mris->ct, v->annotation, &cluster);
      if (cluster >= k)
        k = cluster+1 ;
      v->curv = cluster ;
    }
    printf("%d clusters detected...\n", k) ;
    ct = calloc(k, sizeof(CLUSTER)) ;
    if (!ct)
      ErrorExit(ERROR_BADPARM, "%s: could not allocate %d clusters", Progname, k) ;
    nsamples = mri_profiles->nframes ;
    for (i = 0 ; i < k ; i++) {
      ct[i].v_mean = VectorAlloc(nsamples, MATRIX_REAL) ;
      ct[i].m_cov = MatrixIdentity(nsamples, NULL) ;
      ct[i].npoints = 0 ;
    }
    for (vno = 0 ; vno < mris->nvertices ; vno++) {
      v = &mris->vertices[vno] ;
      if (v->ripflag)
        continue ;
      add_vertex_to_cluster(mris, mri_profiles, ct, v->curv, vno);
    }
  } else {
    if (mris_ico)
      k = mris_ico->nvertices ;
    ct = calloc(k, sizeof(CLUSTER)) ;
    if (!ct)
      ErrorExit(ERROR_BADPARM, "%s: could not allocate %d clusters", Progname, k) ;
    nsamples = mri_profiles->nframes ;
    for (i = 0 ; i < k ; i++) {
      ct[i].v_mean = VectorAlloc(nsamples, MATRIX_REAL) ;
      ct[i].m_cov = MatrixIdentity(nsamples, NULL) ;
      ct[i].npoints = 0 ;
    }

    MRISsetCurvature(mris, -1) ;
    if (mris_ico)
      initialize_cluster_centers_with_ico(mris, mri_profiles, ct, mris_ico) ;
    else
      initialize_cluster_centers(mris, mri_profiles, ct, k) ;

    done = iter = 0 ;
    do {
      vno = find_most_likely_unmarked_vertex(mris, mri_profiles, ct, k, &cluster);
      if (vno < 0)
        break ;
      add_vertex_to_cluster(mris, mri_profiles, ct, cluster, vno);
      if (write_iters > 0 && ((iter % write_iters) == 0)) {
        sprintf(fname, "%s.clusters%6.6d.annot",
                mris->hemisphere == LEFT_HEMISPHERE ? "lh" : "rh", iter) ;
        printf("%6.6d: writing %s\n", iter, fname) ;
        MRISwriteAnnotation(mris, fname) ;
        sprintf(fname, "./%s.clusters%6.6d.indices",
                mris->hemisphere == LEFT_HEMISPHERE ? "lh" : "rh", iter) ;
        //   MRISwriteCurvature(mris, fname) ;
      }
      if (write_iters == 0 && ((iter % 5000) == 0))
        printf("%6.6d of %6.6d\n", iter, mris->nvertices-k) ;
      if (iter++ > mris->nvertices-k || iter > max_iterations)
        done = 1 ;
    } while (!done) ;
  }
  iter = done = 0 ;
  do {
    vno = find_most_likely_vertex_to_swap(mris, mri_profiles, ct, k, &cluster);
    if (vno < 0)
      break ;
    remove_vertex_from_cluster(mris, mri_profiles, ct, mris->vertices[vno].curv, vno) ;
    add_vertex_to_cluster(mris, mri_profiles, ct, cluster, vno);
    if (write_iters > 0 && ((iter % write_iters) == 0)) {
      sprintf(fname, "%s.more_clusters%6.6d.annot",
              mris->hemisphere == LEFT_HEMISPHERE ? "lh" : "rh", iter) ;
      printf("%6.6d: writing %s\n", iter, fname) ;
      MRISwriteAnnotation(mris, fname) ;
      sprintf(fname, "./%s.more_clusters%6.6d.indices",
              mris->hemisphere == LEFT_HEMISPHERE ? "lh" : "rh", iter) ;
      //   MRISwriteCurvature(mris, fname) ;
    }
    if (write_iters == 0 && ((iter % 5000) == 0))
      printf("%6.6d of %6.6d\n", iter, mris->nvertices) ;
    if (iter++ > mris->nvertices || iter > max_iterations)
      done = 1 ;
  } while (!done) ;
  return(ct);
}
コード例 #29
0
ファイル: mricurv.c プロジェクト: guo2004131/freesurfer
static void computeCurvature(VerTex *vertex,int nvt,FaCe *face, int nfc,int* ref_tab,int nb,float* curv)
{
    int n,m,reference;
    VECTOR *v_n, *v_e1,*v_e2,*v;
    float nx,ny,nz,area,dx,dy,dz,y,r2,u1,u2,YR2,R4;

    v_n=VectorAlloc(3,MATRIX_REAL);
    v_e1=VectorAlloc(3,MATRIX_REAL);
    v_e2=VectorAlloc(3,MATRIX_REAL);
    v=VectorAlloc(3,MATRIX_REAL);
    for (n=0; n<nb; n++)
    {
        reference=ref_tab[n];
        //first need to compute normal
        nx=ny=nz=area=0;
        for (m=0; m<vertex[reference].fnum; m++)
        {
            nx+=face[vertex[reference].f[m]].nx*face[vertex[reference].f[m]].area;
            ny+=face[vertex[reference].f[m]].ny*face[vertex[reference].f[m]].area;
            nz+=face[vertex[reference].f[m]].nz*face[vertex[reference].f[m]].area;
            area+=face[vertex[reference].f[m]].area;
        }
        nx/=area;
        ny/=area;
        nz/=area;
        VECTOR_LOAD(v_n,nx,ny,nz);
        //now need to compute the tangent plane!
        VECTOR_LOAD(v,ny,nz,nx);
        V3_CROSS_PRODUCT(v_n,v,v_e1);
        if ((V3_LEN_IS_ZERO(v_e1)))
        {
            if (nz!=0)
                VECTOR_LOAD(v,ny,-nz,nx)
                else if (ny!=0)
                    VECTOR_LOAD(v,-ny,nz,nx)
                    else
                        VECTOR_LOAD(v,ny,nz,-nx);
            V3_CROSS_PRODUCT(v_n,v,v_e1);
        }
        V3_CROSS_PRODUCT(v_n,v_e1,v_e2);
        V3_NORMALIZE(v_e1,v_e1);
        V3_NORMALIZE(v_e2,v_e2);
        //finally compute curvature by fitting a 1-d quadratic r->a*r*r: curv=2*a

        for (YR2=0,R4=0,m=0; m<vertex[reference].vnum; m++)
        {
            dx=vertex[vertex[reference].v[m]].x-vertex[reference].x;
            dy=vertex[vertex[reference].v[m]].y-vertex[reference].y;
            dz=vertex[vertex[reference].v[m]].z-vertex[reference].z;
            VECTOR_LOAD(v,dx,dy,dz);

            y=V3_DOT(v,v_n);
            u1=V3_DOT(v_e1,v);
            u2=V3_DOT(v_e2,v);
            r2=u1*u1+u2*u2;
            YR2+=y*r2;
            R4+=r2*r2;
        }
        curv[n]=2*YR2/R4;
    }


    VectorFree(&v);
    VectorFree(&v_n);
    VectorFree(&v_e1);
    VectorFree(&v_e2);
}
コード例 #30
0
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) ;
}