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) ; }
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 */
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) ; }
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 */
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) ; }
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) ; }
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) ; }
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) ; }
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 */
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) ; }
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 */
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) ; }
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 */
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 ) ); }
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) ; }
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) ; }
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 */
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) ; }
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) ; }
/* 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) ; }
// 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; }
// (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(<a->xforms[0].src,mri_src); MRI* mri_trg = MRIallocHeader(1,1,1,MRI_UCHAR,1); useVolGeomToMRI(<a->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; }
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) ; }
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) ; }
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) ; }
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) ; }
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(<a->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) ; }
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); }
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); }
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) ; }