MRI * MRIcropVolumeToLabel(MRI *mri_src, MRI *mri_dst, LABEL *area, MRI_SURFACE *mris_white, MRI_SURFACE *mris_pial) { MHT *mht_white, *mht_pial ; int x, y, z ; VERTEX *v_white, *v_pial ; Real xs, ys, zs ; mht_white = MHTfillVertexTableRes(mris_white, NULL, CURRENT_VERTICES, 5.0) ; mht_pial = MHTfillVertexTableRes(mris_pial, NULL, CURRENT_VERTICES, 5.0) ; if (mri_dst == NULL) mri_dst = MRIclone(mri_src, NULL) ; MRISclearMarks(mris_white) ; MRISclearMarks(mris_pial) ; LabelMarkSurface(area, mris_white) ; LabelMarkSurface(area, mris_pial) ; for (x = 0 ; x < mri_src->width ; x++) { for (y = 0 ; y < mri_src->height ; y++) { for (z = 0 ; z < mri_src->depth ; z++) { if (x == Gx && y == Gy && z == Gz) DiagBreak() ; if (MRIgetVoxVal(mri_src, x, y, z, 0) > 0) { MRISsurfaceRASFromVoxel(mris_white, mri_dst, x, y, z, &xs, &ys, &zs) ; v_white = MHTfindClosestVertexInTable(mht_white, mris_white, xs, ys, zs, 1) ; v_pial = MHTfindClosestVertexInTable(mht_pial, mris_pial, xs, ys, zs, 1) ; if ((v_white && v_white->marked == 1) || (v_pial && v_pial->marked == 1)) { MRIsetVoxVal(mri_dst, x, y, z, 0, 255) ; } else MRIsetVoxVal(mri_dst, x, y, z, 0, 0) ; } } } } MHTfree(&mht_white) ; MHTfree(&mht_pial) ; return(mri_dst) ; }
int MRIsampleParcellationToSurface(MRI_SURFACE *mris, MRI *mri_parc) { int min_label, max_label, **label_histo, l, vno, nlabels, x, y, z, max_l ; float fmin, fmax, max_count, d ; MRIS_HASH_TABLE *mht ; VERTEX *v ; Real xs, ys, zs, xv, yv, zv, val ; MRI *mri_parc_unused ; mri_parc_unused = MRIcopy(mri_parc, NULL) ; MRIvalRange(mri_parc, &fmin, &fmax) ; min_label = (int)floor(fmin) ; max_label = (int)ceil(fmax) ; nlabels = max_label - min_label + 1 ; label_histo = (int **)calloc(mris->nvertices, sizeof(int *)) ; if (label_histo == NULL) ErrorExit(ERROR_NOMEMORY, "%s: could not create label frequency histo", Progname) ; for (vno = 0 ; vno < mris->nvertices ; vno++) { label_histo[vno] = (int *)calloc(nlabels, sizeof(int)) ; if (label_histo[vno] == NULL) ErrorExit(ERROR_NOMEMORY, "%s: could not create label frequency histo[%d] with %d bins", Progname, vno, nlabels) ; } mht = MHTfillVertexTableRes(mris, NULL, CURRENT_VERTICES, 8.0) ; MRISclearMarks(mris) ; // build histograms at each vertex for (x = 0 ; x < mri_parc->width ; x++) { for (y = 0 ; y < mri_parc->height ; y++) { for (z = 0 ; z < mri_parc->depth ; z++) { if (x == Gx && y == Gy && z == Gz) DiagBreak() ; l = (int)MRIgetVoxVal(mri_parc, x, y, z, 0) ; if (l == 0) continue ; MRIvoxelToSurfaceRAS(mri_parc, x, y, z, &xs, &ys, &zs) ; v = MHTfindClosestVertexInTable(mht, mris, xs, ys, zs, 0) ; if (v == NULL) continue ; if (sqrt(SQR(v->x-xs) + SQR(v->y-ys) + SQR(v->z-zs)) > 3) continue ; MRIsetVoxVal(mri_parc_unused, x, y, z, 0, 0) ; vno = v-mris->vertices ; if (vno == Gdiag_no) { printf("v %d: sampling from (%d, %d, %d) - %d\n", vno, x, y, z, l); DiagBreak() ; } label_histo[vno][l-min_label]++ ; } } } MRIwrite(mri_parc_unused, "pu.mgz") ; for (vno = 0 ; vno < mris->nvertices ; vno++) { if (vno == Gdiag_no) DiagBreak() ; max_l = 0 ; max_count = 0 ; for (l = 0 ; l < nlabels ; l++) { if (label_histo[vno][l] > max_count) { max_count = label_histo[vno][l] ; max_l = l+min_label ; } } v = &mris->vertices[vno] ; v->val = v->annotation = max_l ; if (max_count > 0) v->marked = 1 ; } for (vno = 0 ; vno < mris->nvertices ; vno++) { v = &mris->vertices[vno] ; if (vno == Gdiag_no) DiagBreak() ; if (v->marked) continue ; // found something here for (d = 0 ; d <= 2 ; d += 0.25) { xs = v->x + d*v->nx; ys = v->y + d*v->ny; zs = v->z + d*v->nz; MRIsurfaceRASToVoxel(mri_parc, xs, ys, zs, &xv, &yv, &zv); MRIsampleVolumeType(mri_parc, xv, yv, zv, &val, SAMPLE_NEAREST) ; l = (int)nint(val) ; if (l > 0) { v->val = v->annotation = l ; break ; } } } MHTfree(&mht) ; for (vno = 0 ; vno < mris->nvertices ; vno++) free(label_histo[vno]) ; free(label_histo) ; MRIfree(&mri_parc_unused) ; return(NO_ERROR) ; }
/* expects the two surfaces to have the CANONICAL_VERTICES field set to the sphere.reg positions. */ int MRISmapCuts(MRI_SURFACE *mris_in, MRI_SURFACE *mris_out) { MHT *mht_in, *mht_out ; int vno_out /*, vno_in, fno_in, fno_out, n, ripflag*/ ; VERTEX *v_out, *v_in ; #if 0 FACE *f_in, *f_out ; #endif MRISstoreRipFlags(mris_in) ; MRISunrip(mris_in) ; mht_in = MHTfillVertexTable(mris_in, NULL, CANONICAL_VERTICES) ; mht_out = MHTfillVertexTable(mris_out, NULL, CANONICAL_VERTICES) ; #if 0 for (vno_in = 0 ; vno_in < mris_in->nvertices ; vno_in++) { if (vno_in == Gdiag_no) DiagBreak() ; v_in = &mris_in->vertices[vno_in] ; if (v_in->oripflag == 0) continue ; v_out = MHTfindClosestVertexInTable(mht_out, mris_out, v_in->cx, v_in->cy, v_in->cz, 1) ; if (v_out == NULL) DiagBreak() ; else v_out->ripflag = 1 ; } for (vno_out = 0 ; vno_out < mris_out->nvertices ; vno_out++) { if (vno_out == Gdiag_no) DiagBreak() ; v_out = &mris_out->vertices[vno_out] ; v_in = MHTfindClosestVertexInTable(mht_in, mris_in, v_out->cx, v_out->cy, v_out->cz, 1) ; if (v_in == NULL) DiagBreak() ; else if (v_in->oripflag) v_out->ripflag = 1 ; } for (fno_in = 0 ; fno_in < mris_in->nfaces ; fno_in++) { f_in = &mris_in->faces[fno_in] ; if (f_in->ripflag == 0) continue ; for (n = 0 ; n < VERTICES_PER_FACE ; n++) { vno_in = f_in->v[n] ; if (vno_in == Gdiag_no) DiagBreak() ; v_in = &mris_in->vertices[vno_in] ; v_out = MHTfindClosestVertexInTable(mht_out, mris_out, v_in->cx, v_in->cy, v_in->cz, 1) ; if (v_out == NULL) DiagBreak() ; else v_out->ripflag = 1 ; } } for (fno_out = 0 ; fno_out < mris_out->nfaces ; fno_out++) { f_out = &mris_out->faces[fno_out] ; ripflag = 0 ; for (n = 0 ; n < VERTICES_PER_FACE ; n++) { vno_out = f_out->v[n] ; if (vno_out == Gdiag_no) DiagBreak() ; v_out = &mris_out->vertices[vno_out] ; v_in = MHTfindClosestVertexInTable(mht_in, mris_in, v_out->cx, v_out->cy, v_out->cz, 1) ; if (v_in == NULL) DiagBreak() ; else if (v_in->ripflag) ripflag = 1 ; } f_out->ripflag = ripflag ; } for (fno_out = 0 ; fno_out < mris_out->nfaces ; fno_out++) { double cx, cy, cz ; int n ; f_out = &mris_out->faces[fno_out] ; ripflag = 0 ; cx = cy = cz = 0.0 ; for (n = 0 ; n < VERTICES_PER_FACE ; n++) { vno_out = f_out->v[n] ; if (vno_out == Gdiag_no) DiagBreak() ; v_out = &mris_out->vertices[vno_out] ; cx += v_out->cx ; cy += v_out->cy ; cz += v_out->cz ; } cx /= VERTICES_PER_FACE ; cy /= VERTICES_PER_FACE ; cz /= VERTICES_PER_FACE ; v_in = MHTfindClosestVertexInTable(mht_in, mris_in, cx, cy, cz, 1) ; if (v_in == NULL) DiagBreak() ; else if (v_in->ripflag) { f_out->ripflag = 1 ; for (n = 0 ; n < VERTICES_PER_FACE ; n++) mris_out->vertices[f_out->v[n]].ripflag = 1 ; } } #endif #define STEP_SIZE 0.05 for (vno_out = 0 ; vno_out < mris_out->nvertices ; vno_out++) { double d, dx, dy, dz ; int n ; VERTEX *vn ; v_out = &mris_out->vertices[vno_out] ; for (n = 0 ; n < v_out->vnum ; n++) { vn = &mris_out->vertices[v_out->v[n]] ; dx = vn->cx - v_out->cx ; dy = vn->cy - v_out->cy ; dz = vn->cz - v_out->cz ; for (d = 0.0 ; d <= 1.0 ; d+= STEP_SIZE) { v_in = MHTfindClosestVertexInTable(mht_in, mris_in, v_out->cx+dx*d, v_out->cy+dy*d, v_out->cz+dz*d, 1) ; if (v_in == NULL) DiagBreak() ; else if (v_in->oripflag) { v_out->ripflag = 1 ; break ; } } } } MRISripFaces(mris_out) ; MRISrestoreRipFlags(mris_in) ; MHTfree(&mht_in) ; MHTfree(&mht_out) ; return(NO_ERROR) ; }
static int update_histograms(MRI_SURFACE *mris, MRI_SURFACE *mris_avg, float ***histograms, int nbins) { int vno, vno2, vno_avg ; double volume_dist, surface_dist, circumference, angle ; VERTEX *v1, *v2 ; VECTOR *vec1, *vec2 ; MHT *mht ; float **histogram, min_dist ; mht = MHTfillVertexTableRes(mris_avg, NULL, CURRENT_VERTICES, 2.0) ; vec1 = VectorAlloc(3, MATRIX_REAL) ; vec2 = VectorAlloc(3, MATRIX_REAL) ; v1 = &mris->vertices[0] ; VECTOR_LOAD(vec1, v1->cx, v1->cy, v1->cz) ; /* radius vector */ circumference = M_PI * 2.0 * V3_LEN(vec1) ; MRISclearMarks(mris_avg) ; #if 0 for (vno = 0 ; vno < mris->nvertices ; vno++) { if ((vno % 1000) == 0) { printf("\r%d of %d ", vno, mris->nvertices) ; fflush(stdout) ; } v1 = &mris->vertices[vno] ; VECTOR_LOAD(vec1, v1->cx, v1->cy, v1->cz) ; /* radius vector */ vno_avg = MHTfindClosestVertexNo(mht, mris_avg, v1, &min_dist) ; /* which histogram to increment */ if (vno_avg < 0) continue ; if (vno_avg == Gdiag_no) DiagBreak() ; histogram = histograms[vno_avg] ; mris_avg->vertices[vno_avg].marked = 1 ; for (vno2 = 0 ; vno2 < mris->nvertices ; vno2++) { if (vno2 == vno) continue ; v2 = &mris->vertices[vno2] ; VECTOR_LOAD(vec2, v2->cx, v2->cy, v2->cz) ; /* radius vector */ volume_dist = sqrt(SQR(v1->origx-v2->origx)+SQR(v1->origy-v2->origy)+SQR(v1->origz-v2->origz)) ; if (nint(volume_dist) >= nbins || nint(volume_dist) < 0) continue ; angle = fabs(Vector3Angle(vec1, vec2)) ; surface_dist = circumference * angle / (2.0 * M_PI) ; if (surface_dist > nbins*MAX_SURFACE_SCALE) surface_dist = nbins*MAX_SURFACE_SCALE ; if (surface_dist < 1) surface_dist = 1 ; histogram[nint(volume_dist)][nint(surface_dist)]++ ; if (mht->buckets[0][0] != NULL) DiagBreak() ; } } MHTfree(&mht) ; #endif /* map back ones that were missed */ /* printf("\nfilling holes in mapping\n") ;*/ mht = MHTfillVertexTableRes(mris, NULL, CURRENT_VERTICES, 2.0) ; for (vno_avg = 0 ; vno_avg < mris_avg->nvertices ; vno_avg++) { if (mris_avg->vertices[vno_avg].marked > 0) continue ; if ((vno_avg % 1000) == 0) { printf("\r%d of %d ", vno_avg, mris_avg->nvertices) ; fflush(stdout) ; } vno = MHTfindClosestVertexNo(mht, mris, &mris_avg->vertices[vno_avg], &min_dist) ; if (vno < 0) continue ; v1 = &mris->vertices[vno] ; VECTOR_LOAD(vec1, v1->cx, v1->cy, v1->cz) ; /* radius vector */ if (vno_avg < 0) continue ; if (vno_avg == Gdiag_no) DiagBreak() ; histogram = histograms[vno_avg] ; mris_avg->vertices[vno_avg].marked = 1 ; for (vno2 = 0 ; vno2 < mris->nvertices ; vno2++) { if (vno2 == vno) continue ; v2 = &mris->vertices[vno2] ; VECTOR_LOAD(vec2, v2->cx, v2->cy, v2->cz) ; /* radius vector */ volume_dist = sqrt(SQR(v1->origx-v2->origx)+SQR(v1->origy-v2->origy)+SQR(v1->origz-v2->origz)) ; if (nint(volume_dist) >= nbins || nint(volume_dist) < 0) continue ; angle = fabs(Vector3Angle(vec1, vec2)) ; surface_dist = circumference * angle / (2.0 * M_PI) ; if (surface_dist > nbins*MAX_SURFACE_SCALE) surface_dist = nbins*MAX_SURFACE_SCALE ; if (surface_dist < 1) surface_dist = 1 ; histogram[nint(volume_dist)][nint(surface_dist)]++ ; } } MHTfree(&mht) ; printf("\n") ; VectorFree(&vec1) ; VectorFree(&vec2) ; return(NO_ERROR) ; }
MRI * MRIflattenOverlay(MRI_SURFACE *mris, MRI *mri_overlay, MRI *mri_flat, double res, LABEL *label_overlay, MRI **pmri_vertices) { double xmin, ymin, xmax, ymax, fdist, lambda[3], xf, yf, val0, val1, val2, val ; int width, height, x, y, fno, ret, z ; MHT *mht ; FACE *face; MRI *mri_vertices ; find_biggest_inscribed_rectangle(mris, &xmin, &ymin, &xmax, &ymax) ; width = (int)ceil((xmax-xmin)/res) ; width = (int)(floor(width/2.0)*2.0+1) ; xmax=xmin+width; height = (int)ceil((ymax-ymin)/res) ;height = (int)(floor(height/2.0)*2.0+1) ; ymax=ymin+height; // 1st frame is correlations and 2nd is vertex # mri_vertices = MRIalloc(width, height, 1, MRI_FLOAT) ; MRIsetValues(mri_vertices, -1) ; mri_flat = MRIalloc(width, height, mri_overlay->nframes, MRI_FLOAT) ; mri_vertices->xstart = mri_flat->xstart = xmin ; mri_vertices->xend = mri_flat->xend = xmax ; mri_vertices->ystart = mri_flat->ystart = ymin ; mri_vertices->yend = mri_flat->yend = ymax ; mri_vertices->zstart = mri_flat->zstart = 0 ; mri_vertices->zend = mri_flat->zend = mri_overlay->nframes-1 ; mri_vertices->c_r = mri_flat->c_r = xmin ; mri_vertices->c_a = mri_flat->c_a = ymin ; mri_vertices->c_s = mri_flat->c_s = 0 ; MRIsetResolution(mri_flat, res, res, 1) ; MRIsetResolution(mri_vertices, res, res, 1) ; if (label_overlay) // constrain processing to only this label LabelRipRestOfSurface(label_overlay, mris) ; mht = MHTfillTableAtResolution(mris, NULL, CURRENT_VERTICES, 1.0) ; for (x = 0 ; x < width; x++) for (y = 0 ; y < height ; y++) { xf = x*res + xmin ; yf = y*res + ymin ; // back to flattened coords MHTfindClosestFaceGeneric(mht, mris, xf, yf, 0.0, 10*res, 2, 1, &face, &fno, &fdist) ; if (fno >= 0) // otherwise this point is not in a face { ret = face_barycentric_coords(mris, fno, CURRENT_VERTICES, xf, yf, 0, &lambda[0], &lambda[1],&lambda[2]); if (ret >= 0) { if (lambda[0] > lambda[1]) { if (lambda[0] > lambda[2]) { if (face->v[0] == Gdiag_no) DiagBreak() ; MRIsetVoxVal(mri_vertices, x, y, 0, 0, face->v[0]) ; } else { if (face->v[2] == Gdiag_no) DiagBreak() ; MRIsetVoxVal(mri_vertices, x, y, 0, 0, face->v[2]) ; } } else { if (lambda[1] > lambda[2]) { if (face->v[1] == Gdiag_no) DiagBreak() ; MRIsetVoxVal(mri_vertices, x, y, 0, 0, face->v[1]) ; } else { if (face->v[2] == Gdiag_no) DiagBreak() ; MRIsetVoxVal(mri_vertices, x, y, 0, 0, face->v[2]) ; } } for (z = 0 ;z < mri_flat->depth ; z++) { val0 = MRIgetVoxVal(mri_overlay, face->v[0], 0, 0, z) ; val1 = MRIgetVoxVal(mri_overlay, face->v[1], 0, 0, z) ; val2 = MRIgetVoxVal(mri_overlay, face->v[2], 0, 0, z) ; val = lambda[0]*val0 + lambda[1]*val1 + lambda[2]*val2 ; MRIsetVoxVal(mri_flat, x, y, z, 0, val) ; } } else if (fabs(xf) < 10 && fabs(yf) < 10) { MHTfindClosestFaceGeneric(mht, mris, xf, yf, 0.0, 1000, -1, 1, &face, &fno, &fdist) ; printf("(%d, %d) --> %f %f unmapped (goes to face %d, v (%d, %d, %d) if projected\n", x, y, xf, yf, fno, face->v[0], face->v[1], face->v[2]) ; DiagBreak() ; } } } if (pmri_vertices) *pmri_vertices = mri_vertices ; MHTfree(&mht) ; return(mri_flat) ; }
static int relabel_hypointensities(MRI *mri, MRI_SURFACE *mris, int right) { int x, y, z, label, changed ; MRIS_HASH_TABLE *mht ; VERTEX *v ; float dx, dy, dz, dot, dist ; Real xw, yw, zw ; MRI *mri_dist ; mri_dist = MRIcloneDifferentType(mri, MRI_FLOAT) ; MRIScomputeDistanceToSurface(mris, mri_dist, mri_dist->xsize) ; mht = MHTfillVertexTableRes(mris,NULL, CURRENT_VERTICES, 8.0f) ; for (changed = x = 0 ; x < mri->width ; x++) { for (y = 0 ; y < mri->height ; y++) { for (z = 0 ; z < mri->depth ; z++) { if (x == Gx && y == Gy && z == Gz) { DiagBreak() ; } label = MRIgetVoxVal(mri, x, y, z, 0) ; if (label == Left_WM_hypointensities) { MRIsetVoxVal(mri, x, y, z,0, WM_hypointensities) ; } else if (label == Right_WM_hypointensities) { MRIsetVoxVal(mri, x, y, z, 0, WM_hypointensities) ; } if ((!right && (label != Left_Cerebral_Cortex)) || (right && (label != Right_Cerebral_Cortex))) { continue ; } // MRIvoxelToWorld(mri, x, y, z, &xw, &yw, &zw) ; MRIvoxelToSurfaceRAS(mri, x, y, z, &xw, &yw, &zw); v = MHTfindClosestVertexInTable(mht, mris, xw, yw, zw, 0) ; if (v == NULL) /* no vertices within range - assume it is hypointensity */ { dot = -1 ; dist = MRIgetVoxVal(mri_dist, x, y, z, 0) ; if (dist > 0) { dot = 1 ; } } else { dx = xw - v->x ; dy = yw - v->y ; dz = zw - v->z ; dot = v->nx*dx + v->ny*dy + v->nz*dz ; dist = sqrt(dx*dx+dy*dy+dz*dz) ; } if (dot < 0 && dist > 1) { changed++ ; MRIsetVoxVal(mri, x, y, z, 0, WM_hypointensities) ; } } } } printf("%d voxels changed to hypointensity...\n", changed) ; MHTfree(&mht) ; MRIfree(&mri_dist) ; return(NO_ERROR) ; }