void convert_vox_to_surf(MRI_SURFACE* mris, MRI* vol) { double cx, cy, cz; Real vx, vy, vz; VERTEX* pvtx = &( mris->vertices[0] ); unsigned int nvertices = (unsigned int)mris->nvertices; for (unsigned int ui=0; ui < nvertices; ++ui, ++pvtx ) { cx = pvtx->x; cy = pvtx->y; cz = pvtx->z; MRIvoxelToSurfaceRAS( vol, cx, cy, cz, &vx, &vy, &vz ); pvtx->x = vx; pvtx->y = vy; pvtx->z = vz; } // next ui, pvtx }
static int compute_rigid_gradient(MRI_SURFACE *mris, MRI *mri, double *pdx, double *pdy, double *pdz) { int vno ; VERTEX *v ; Real val, xw, yw, zw, dx, dy, dz, delV, x, y, z, Ix, Iy, Iz, xv, yv, zv ; dx = dy = dz = 0.0 ; for (vno = 0 ; vno < mris->nvertices ; vno++) { v = &mris->vertices[vno] ; if (v->ripflag) continue ; if (vno == Gdiag_no) DiagBreak() ; x = v->x ; y = v->y ; z = v->z ; MRISvertexToVoxel(mris, v, mri, &xw, &yw, &zw); MRIsampleVolume(mri, xw, yw, zw, &val) ; MRIsampleVolumeGradient(mri, xw, yw, zw, &Ix, &Iy, &Iz) ; // convert back to surface coords xw += Ix ; yw += Iy ; zw += Iz ; if (mris->useRealRAS) MRIvoxelToWorld(mri, xw, yw, zw, &xv, &yv, &zv) ; else MRIvoxelToSurfaceRAS(mri, xw, yw, zw, &xv, &yv, &zv) ; Ix = xv-v->x ; Iy = yv-v->y; Iz = zv-v->z ; delV = v->val - val ; dx += delV * Ix ; dy += delV * Iy ; dz += delV * Iz ; if (!finitep((float)dx)) DiagBreak() ; if (!finitep((float)dy)) DiagBreak() ; if (!finitep((float)dz)) DiagBreak() ; } dx /= mris->nvertices ; dy /= mris->nvertices ; dz /= mris->nvertices ; *pdx = dx ; *pdy = dy ; *pdz = dz ; return(NO_ERROR) ; }
static MRI_REGION*mriFindLabel(MRI *mri,int label,int offset) { MRI_REGION *region; int i,j,k,nlabels; Real xmin,ymax,zmin,xmax,ymin,zmax; Real xw,yw,zw; region=(MRI_REGION*)calloc(1,sizeof(MRI_REGION)); xmin=ymin=zmin=100000; xmax=ymax=zmax=-100000; for (nlabels=k=0;k<mri->depth;k++) for (j=0;j<mri->height;j++) for (i=0;i<mri->width;i++) if (MRIvox(mri,i,j,k)==label) { nlabels++; MRIvoxelToSurfaceRAS(mri, i, j, k, &xw, &yw, &zw) ; if (xmin>xw) xmin=xw; if (ymin>yw) ymin=yw; if (zmin>zw) zmin=zw; if (xmax<xw) xmax=xw; if (ymax<yw) ymax=yw; if (zmax<zw) zmax=zw; } if (nlabels==0) ErrorExit(1,"No labels %d could be found in the volume\n",nlabels); region->x=(int)floor(xmin-offset); region->y=(int)floor(ymin-offset); region->z=(int)floor(zmin-offset); region->dx=(int)ceil(xmax-xmin+2*offset); region->dy=(int)ceil(ymax-ymin+2*offset); region->dz=(int)ceil(zmax-zmin+2*offset); return region; }
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) ; }
MRI* MRIcomputeVolumeFractionFromSurface(MRI_SURFACE *mris, double acc, MRI *mri_src, MRI *mri_fractions) { const int width = mri_src->width; const int height = mri_src->height; const int depth = mri_src->depth; int x,y,z, vno; double xs, ys, zs, dist; MRIS_HASH_TABLE *mht; VERTEX *v; /* preparing the output */ printf("preparing the output\n"); if (mri_fractions == NULL) { mri_fractions = MRIalloc(width,height,depth,MRI_FLOAT); MRIcopyHeader(mri_src, mri_fractions); } MRI *mri_shell, *mri_interior; /* creating a shell from the surface */ printf("computing the shell\n"); mri_shell = MRIclone(mri_src, NULL); mri_shell = MRISshell(mri_src, mris, mri_shell, 1); /* creating an interior image from the surface */ printf("computing an interior image\n"); mri_interior = MRIclone(mri_src, NULL); MRIclear(mri_interior); mri_interior = MRISfillInterior(mris, 0.0, mri_interior); /* creating the hash table related to the surface vertices */ printf("computing the hash table\n"); mht = MHTfillVertexTableRes(mris, NULL, CURRENT_VERTICES, 10); /* looping over the nonzero elements of the shell */ printf("computing the fractions\n"); volFraction frac; octTreeVoxel V; double vox[3], vsize[3]; vsize[0] = mri_src->xsize; vsize[1] = mri_src->ysize; vsize[2] = mri_src->zsize; for (x = 0; x < width; x++) { for (y = 0; y < height; y++) { for (z = 0; z < depth; z++) { if (MRIgetVoxVal (mri_shell, x, y, z, 0) > 125.0) { /* change of coordinates from image to surface domain */ MRIvoxelToSurfaceRAS(mri_shell, x, y, z, &xs, &ys, &zs); /* find the closest vertex to the point */ MHTfindClosestVertexGeneric(mht, mris, xs, ys, zs, 10, 2, &v, &vno, &dist); /* creating the oct tree voxel structure */ vox[0] = xs - vsize[0] / 2.0; vox[1] = ys - vsize[1] / 2.0; vox[2] = zs - vsize[2] / 2.0; V = octTreeVoxelCreate(vox,vsize); /* compute the volume fraction of this voxel */ frac = MRIcomputeVoxelFractions( V, v, acc, 1, mris); MRIsetVoxVal(mri_fractions,x,y,z,0,frac.frac); } else if(MRIgetVoxVal(mri_interior,x,y,z,0) > 0.0) MRIsetVoxVal(mri_fractions,x,y,z,0,1.0); } } } return mri_fractions; }
static int initialize_surface_position(MRI_SURFACE *mris, MRI *mri_masked, int outside, INTEGRATION_PARMS *parms) { MRI *mri_dilated ; int x, y, z, vno ; double x0, y0, z0, radius = 0, dist, num ; Real xs, ys, zs ; VERTEX *v ; if (outside) { mri_dilated = MRIdilate(mri_masked, NULL) ; MRIsubtract(mri_dilated, mri_masked, mri_dilated) ; MRIwrite(mri_dilated, "outside.mgz") ; num = x0 = y0 = z0 = 0 ; for (x = 0 ; x < mri_dilated->width ; x++) { for (y = 0 ; y < mri_dilated->height ; y++) { for (z = 0 ; z < mri_dilated->depth ; z++) { if (MRIgetVoxVal(mri_dilated, x, y, z,0) > 0) { MRIvoxelToSurfaceRAS(mri_dilated, x, y, z, &xs, &ys, &zs) ; x0 += xs ; y0 += ys ; z0 += zs ; num++ ; } } } } x0 /= num ; y0 /= num ; z0 /= num ; printf("centroid at (%2.1f, %2.1f, %2.1f)\n", x0, y0, z0) ; num = radius = 0 ; for (x = 0 ; x < mri_dilated->width ; x++) { for (y = 0 ; y < mri_dilated->height ; y++) { for (z = 0 ; z < mri_dilated->depth ; z++) { if (MRIgetVoxVal(mri_dilated, x, y, z,0) > 0) { MRIvoxelToSurfaceRAS(mri_dilated, x, y, z, &xs, &ys, &zs) ; dist = sqrt(SQR(xs-x0)+SQR(ys-y0)+SQR(zs-z0)) ; radius += dist ; num++ ; } } } } radius /= num ; printf("average radius = %2.3f\n", radius) ; MRIfree(&mri_dilated) ; MRISprojectOntoSphere(mris, mris, radius*1.25) ; for (vno = 0 ; vno < mris->nvertices ; vno++) { v = &mris->vertices[vno] ; v->x += x0 ; v->y += y0 ; v->z += z0 ; } MRIScomputeMetricProperties(mris) ; } parms->target_radius = radius ; MRISsaveVertexPositions(mris, ORIGINAL_VERTICES) ; return(NO_ERROR) ; }
static int relabel_hypointensities(MRI *mri, MRI_SURFACE *mris, int right) { int x, y, z, label, changed ; MRIS_HASH_TABLE *mht ; VERTEX *v ; float dx, dy, dz, dot, dist ; Real xw, yw, zw ; MRI *mri_dist ; mri_dist = MRIcloneDifferentType(mri, MRI_FLOAT) ; MRIScomputeDistanceToSurface(mris, mri_dist, mri_dist->xsize) ; mht = MHTfillVertexTableRes(mris,NULL, CURRENT_VERTICES, 8.0f) ; for (changed = x = 0 ; x < mri->width ; x++) { for (y = 0 ; y < mri->height ; y++) { for (z = 0 ; z < mri->depth ; z++) { if (x == Gx && y == Gy && z == Gz) { DiagBreak() ; } label = MRIgetVoxVal(mri, x, y, z, 0) ; if (label == Left_WM_hypointensities) { MRIsetVoxVal(mri, x, y, z,0, WM_hypointensities) ; } else if (label == Right_WM_hypointensities) { MRIsetVoxVal(mri, x, y, z, 0, WM_hypointensities) ; } if ((!right && (label != Left_Cerebral_Cortex)) || (right && (label != Right_Cerebral_Cortex))) { continue ; } // MRIvoxelToWorld(mri, x, y, z, &xw, &yw, &zw) ; MRIvoxelToSurfaceRAS(mri, x, y, z, &xw, &yw, &zw); v = MHTfindClosestVertexInTable(mht, mris, xw, yw, zw, 0) ; if (v == NULL) /* no vertices within range - assume it is hypointensity */ { dot = -1 ; dist = MRIgetVoxVal(mri_dist, x, y, z, 0) ; if (dist > 0) { dot = 1 ; } } else { dx = xw - v->x ; dy = yw - v->y ; dz = zw - v->z ; dot = v->nx*dx + v->ny*dy + v->nz*dz ; dist = sqrt(dx*dx+dy*dy+dz*dz) ; } if (dot < 0 && dist > 1) { changed++ ; MRIsetVoxVal(mri, x, y, z, 0, WM_hypointensities) ; } } } } printf("%d voxels changed to hypointensity...\n", changed) ; MHTfree(&mht) ; MRIfree(&mri_dist) ; return(NO_ERROR) ; }