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) ; }
static int initialize_cluster_centers_with_ico(MRI_SURFACE *mris, MRI *mri_profiles, CLUSTER *ct, MRI_SURFACE *mris_ico) { int i, j, vno, nsamples, vnos[MAX_CLUSTERS], k ; double r1, r2, res ; float fmin ; MRIS_HASH_TABLE *mht ; VERTEX *vico ; k = mris_ico->nvertices ; MRISstoreRipFlags(mris) ; MRISunrip(mris) ; r1 = MRISaverageRadius(mris) ; r2 = MRISaverageRadius(mris_ico) ; MRISscaleBrain(mris_ico,mris_ico, r1/r2); res = sqrt(mris->total_area/mris->nvertices) ; mht = MHTfillVertexTableRes(mris, NULL, CURRENT_VERTICES, 2*res) ; nsamples = mri_profiles->nframes ; for (i = 0 ; i < mris_ico->nvertices ; i++) { vico = &mris_ico->vertices[i] ; vno = MRISfindClosestVertex(mris, vico->x, vico->y, vico->z, &fmin) ; if (vno < 0) continue ; vnos[i] = vno ; for (j = 0 ; j < nsamples ; j++) VECTOR_ELT(ct[i].v_mean, j+1) = MRIgetVoxVal(mri_profiles, vno, 0, 0, j) ; } mris->ct = CTABalloc(k) ; for (i = 0 ; i < k ; i++) { mris->vertices[vnos[i]].curv = i ; ct[i].npoints++ ; ct[i].vno = vnos[i] ; CTABannotationAtIndex(mris->ct, i, &mris->vertices[vnos[i]].annotation) ; } MRISrestoreRipFlags(mris) ; return(NO_ERROR) ; }
/*--------------------------------------------------*/ int main(int argc, char **argv) { int nargs, err, asegid, c, r, s, nctx, annot,vtxno,nripped; int annotid, IsCortex=0, IsWM=0, IsHypo=0, hemi=0, segval=0; int RibbonVal=0,nbrute=0; float dmin=0.0, lhRibbonVal=0, rhRibbonVal=0; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, vcid, "$Name: stable5 $"); if (nargs && argc - nargs == 1) { exit (0); } argc -= nargs; Progname = argv[0] ; argc --; argv++; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; if (argc == 0) { usage_exit(); } SUBJECTS_DIR = getenv("SUBJECTS_DIR"); if (SUBJECTS_DIR==NULL) { printf("ERROR: SUBJECTS_DIR not defined in environment\n"); exit(1); } parse_commandline(argc, argv); check_options(); dump_options(stdout); /* ------ Load subject's lh white surface ------ */ sprintf(tmpstr,"%s/%s/surf/lh.white",SUBJECTS_DIR,subject); printf("\nReading lh white surface \n %s\n",tmpstr); lhwhite = MRISread(tmpstr); if (lhwhite == NULL) { fprintf(stderr,"ERROR: could not read %s\n",tmpstr); exit(1); } /* ------ Load subject's lh pial surface ------ */ sprintf(tmpstr,"%s/%s/surf/lh.pial",SUBJECTS_DIR,subject); printf("\nReading lh pial surface \n %s\n",tmpstr); lhpial = MRISread(tmpstr); if (lhpial == NULL) { fprintf(stderr,"ERROR: could not read %s\n",tmpstr); exit(1); } if (lhwhite->nvertices != lhpial->nvertices) { printf("ERROR: lh white and pial have a different number of " "vertices (%d,%d)\n", lhwhite->nvertices,lhpial->nvertices); exit(1); } /* ------ Load lh annotation ------ */ sprintf(annotfile,"%s/%s/label/lh.%s.annot",SUBJECTS_DIR,subject,annotname); printf("\nLoading lh annotations from %s\n",annotfile); err = MRISreadAnnotation(lhwhite, annotfile); if (err) { printf("ERROR: MRISreadAnnotation() failed %s\n",annotfile); exit(1); } /* ------ Load subject's rh white surface ------ */ sprintf(tmpstr,"%s/%s/surf/rh.white",SUBJECTS_DIR,subject); printf("\nReading rh white surface \n %s\n",tmpstr); rhwhite = MRISread(tmpstr); if (rhwhite == NULL) { fprintf(stderr,"ERROR: could not read %s\n",tmpstr); exit(1); } /* ------ Load subject's rh pial surface ------ */ sprintf(tmpstr,"%s/%s/surf/rh.pial",SUBJECTS_DIR,subject); printf("\nReading rh pial surface \n %s\n",tmpstr); rhpial = MRISread(tmpstr); if (rhpial == NULL) { fprintf(stderr,"ERROR: could not read %s\n",tmpstr); exit(1); } if (rhwhite->nvertices != rhpial->nvertices) { printf("ERROR: rh white and pial have a different " "number of vertices (%d,%d)\n", rhwhite->nvertices,rhpial->nvertices); exit(1); } /* ------ Load rh annotation ------ */ sprintf(annotfile,"%s/%s/label/rh.%s.annot",SUBJECTS_DIR,subject,annotname); printf("\nLoading rh annotations from %s\n",annotfile); err = MRISreadAnnotation(rhwhite, annotfile); if (err) { printf("ERROR: MRISreadAnnotation() failed %s\n",annotfile); exit(1); } if (lhwhite->ct) { printf("Have color table for lh white annotation\n"); } if (rhwhite->ct) { printf("Have color table for rh white annotation\n"); } //print_annotation_table(stdout); if (UseRibbon) { sprintf(tmpstr,"%s/%s/mri/lh.ribbon.mgz",SUBJECTS_DIR,subject); printf("Loading lh ribbon mask from %s\n",tmpstr); lhRibbon = MRIread(tmpstr); if (lhRibbon == NULL) { printf("ERROR: loading %s\n",tmpstr); exit(1); } sprintf(tmpstr,"%s/%s/mri/rh.ribbon.mgz",SUBJECTS_DIR,subject); printf("Loading rh ribbon mask from %s\n",tmpstr); rhRibbon = MRIread(tmpstr); if (rhRibbon == NULL) { printf("ERROR: loading %s\n",tmpstr); exit(1); } } if (UseNewRibbon) { sprintf(tmpstr,"%s/%s/mri/ribbon.mgz",SUBJECTS_DIR,subject); printf("Loading ribbon segmentation from %s\n",tmpstr); RibbonSeg = MRIread(tmpstr); if (RibbonSeg == NULL) { printf("ERROR: loading %s\n",tmpstr); exit(1); } } if (LabelHypoAsWM) { sprintf(tmpstr,"%s/%s/mri/filled.mgz",SUBJECTS_DIR,subject); printf("Loading filled from %s\n",tmpstr); filled = MRIread(tmpstr); if (filled == NULL) { printf("ERROR: loading filled %s\n",tmpstr); exit(1); } } // ------------ Rip ----------------------- if (RipUnknown) { printf("Ripping vertices labeled as unkown\n"); nripped = 0; for (vtxno = 0; vtxno < lhwhite->nvertices; vtxno++) { annot = lhwhite->vertices[vtxno].annotation; CTABfindAnnotation(lhwhite->ct, annot, &annotid); // Sometimes the annotation will be "none" indicated by // annotid = -1. We interpret this as "unknown". if (annotid == 0 || annotid == -1) { lhwhite->vertices[vtxno].ripflag = 1; lhpial->vertices[vtxno].ripflag = 1; nripped++; } } printf("Ripped %d vertices from left hemi\n",nripped); nripped = 0; for (vtxno = 0; vtxno < rhwhite->nvertices; vtxno++) { annot = rhwhite->vertices[vtxno].annotation; CTABfindAnnotation(rhwhite->ct, annot, &annotid); if (annotid == 0 || annotid == -1) { rhwhite->vertices[vtxno].ripflag = 1; rhpial->vertices[vtxno].ripflag = 1; nripped++; } } printf("Ripped %d vertices from right hemi\n",nripped); } printf("\n"); printf("Building hash of lh white\n"); lhwhite_hash = MHTfillVertexTableRes(lhwhite, NULL,CURRENT_VERTICES,hashres); printf("\n"); printf("Building hash of lh pial\n"); lhpial_hash = MHTfillVertexTableRes(lhpial, NULL,CURRENT_VERTICES,hashres); printf("\n"); printf("Building hash of rh white\n"); rhwhite_hash = MHTfillVertexTableRes(rhwhite, NULL,CURRENT_VERTICES,hashres); printf("\n"); printf("Building hash of rh pial\n"); rhpial_hash = MHTfillVertexTableRes(rhpial, NULL,CURRENT_VERTICES,hashres); /* ------ Load ASeg ------ */ sprintf(tmpstr,"%s/%s/mri/aseg.mgz",SUBJECTS_DIR,subject); if (!fio_FileExistsReadable(tmpstr)) { sprintf(tmpstr,"%s/%s/mri/aseg.mgh",SUBJECTS_DIR,subject); if (!fio_FileExistsReadable(tmpstr)) { sprintf(tmpstr,"%s/%s/mri/aseg/COR-.info",SUBJECTS_DIR,subject); if (!fio_FileExistsReadable(tmpstr)) { printf("ERROR: cannot find aseg\n"); exit(1); } else { sprintf(tmpstr,"%s/%s/mri/aseg/",SUBJECTS_DIR,subject); } } } printf("\nLoading aseg from %s\n",tmpstr); ASeg = MRIread(tmpstr); if (ASeg == NULL) { printf("ERROR: loading aseg %s\n",tmpstr); exit(1); } mritmp = MRIchangeType(ASeg,MRI_INT,0,0,1); MRIfree(&ASeg); ASeg = mritmp; if (CtxSegFile) { printf("Loading Ctx Seg File %s\n",CtxSegFile); CtxSeg = MRIread(CtxSegFile); if (CtxSeg == NULL) { exit(1); } } AParc = MRIclone(ASeg,NULL); if (OutDistFile != NULL) { Dist = MRIclone(ASeg,NULL); mritmp = MRIchangeType(Dist,MRI_FLOAT,0,0,0); if (mritmp == NULL) { printf("ERROR: could change type\n"); exit(1); } MRIfree(&Dist); Dist = mritmp; } Vox2RAS = MRIxfmCRS2XYZtkreg(ASeg); printf("ASeg Vox2RAS: -----------\n"); MatrixPrint(stdout,Vox2RAS); printf("-------------------------\n"); CRS = MatrixAlloc(4,1,MATRIX_REAL); CRS->rptr[4][1] = 1; RAS = MatrixAlloc(4,1,MATRIX_REAL); RAS->rptr[4][1] = 1; if (crsTest) { printf("Testing point %d %d %d\n",ctest,rtest,stest); err = FindClosestLRWPVertexNo(ctest,rtest,stest, &lhwvtx, &lhpvtx, &rhwvtx, &rhpvtx, Vox2RAS, lhwhite, lhpial, rhwhite, rhpial, lhwhite_hash, lhpial_hash, rhwhite_hash, rhpial_hash); printf("Result: err = %d\n",err); exit(err); } printf("\nLabeling Slice\n"); nctx = 0; annot = 0; annotid = 0; nbrute = 0; // Go through each voxel in the aseg for (c=0; c < ASeg->width; c++) { printf("%3d ",c); if (c%20 ==19) { printf("\n"); } fflush(stdout); for (r=0; r < ASeg->height; r++) { for (s=0; s < ASeg->depth; s++) { asegid = MRIgetVoxVal(ASeg,c,r,s,0); if (asegid == 3 || asegid == 42) { IsCortex = 1; } else { IsCortex = 0; } if (asegid >= 77 && asegid <= 82) { IsHypo = 1; } else { IsHypo = 0; } if (asegid == 2 || asegid == 41) { IsWM = 1; } else { IsWM = 0; } if (IsHypo && LabelHypoAsWM && MRIgetVoxVal(filled,c,r,s,0)) { IsWM = 1; } // integrate surface information // // Only Do This for GM,WM or Unknown labels in the ASEG !!! // // priority is given to the ribbon computed from the surface // namely // ribbon=GM => GM // aseg=GM AND ribbon=WM => WM // ribbon=UNKNOWN => UNKNOWN if (UseNewRibbon && ( IsCortex || IsWM || asegid==0 ) ) { RibbonVal = MRIgetVoxVal(RibbonSeg,c,r,s,0); MRIsetVoxVal(ASeg,c,r,s,0, RibbonVal); if (RibbonVal==2 || RibbonVal==41) { IsWM = 1; IsCortex = 0; } else if (RibbonVal==3 || RibbonVal==42) { IsWM = 0; IsCortex = 1; } if (RibbonVal==0) { IsWM = 0; IsCortex = 0; } } // If it's not labeled as cortex or wm in the aseg, skip if (!IsCortex && !IsWM) { continue; } // If it's wm but not labeling wm, skip if (IsWM && !LabelWM) { continue; } // Check whether this point is in the ribbon if (UseRibbon) { lhRibbonVal = MRIgetVoxVal(lhRibbon,c,r,s,0); rhRibbonVal = MRIgetVoxVal(rhRibbon,c,r,s,0); if (IsCortex) { // ASeg says it's in cortex if (lhRibbonVal < 0.5 && rhRibbonVal < 0.5) { // but it is not part of the ribbon, // so set it to unknown (0) and go to the next voxel. MRIsetVoxVal(ASeg,c,r,s,0,0); continue; } } } // Convert the CRS to RAS CRS->rptr[1][1] = c; CRS->rptr[2][1] = r; CRS->rptr[3][1] = s; RAS = MatrixMultiply(Vox2RAS,CRS,RAS); vtx.x = RAS->rptr[1][1]; vtx.y = RAS->rptr[2][1]; vtx.z = RAS->rptr[3][1]; // Get the index of the closest vertex in the // lh.white, lh.pial, rh.white, rh.pial if (UseHash) { lhwvtx = MHTfindClosestVertexNo(lhwhite_hash,lhwhite,&vtx,&dlhw); lhpvtx = MHTfindClosestVertexNo(lhpial_hash, lhpial, &vtx,&dlhp); rhwvtx = MHTfindClosestVertexNo(rhwhite_hash,rhwhite,&vtx,&drhw); rhpvtx = MHTfindClosestVertexNo(rhpial_hash, rhpial, &vtx,&drhp); if (lhwvtx < 0 && lhpvtx < 0 && rhwvtx < 0 && rhpvtx < 0) { /* printf(" Could not map to any surface with hash table:\n"); printf(" crs = %d %d %d, ras = %6.4f %6.4f %6.4f \n", c,r,s,vtx.x,vtx.y,vtx.z); printf(" Using brute force search %d ... \n",nbrute); fflush(stdout); */ lhwvtx = MRISfindClosestVertex(lhwhite,vtx.x,vtx.y,vtx.z,&dlhw); lhpvtx = MRISfindClosestVertex(lhpial,vtx.x,vtx.y,vtx.z,&dlhp); rhwvtx = MRISfindClosestVertex(rhwhite,vtx.x,vtx.y,vtx.z,&drhw); rhpvtx = MRISfindClosestVertex(rhpial,vtx.x,vtx.y,vtx.z,&drhp); nbrute ++; //exit(1); } } else { lhwvtx = MRISfindClosestVertex(lhwhite,vtx.x,vtx.y,vtx.z,&dlhw); lhpvtx = MRISfindClosestVertex(lhpial,vtx.x,vtx.y,vtx.z,&dlhp); rhwvtx = MRISfindClosestVertex(rhwhite,vtx.x,vtx.y,vtx.z,&drhw); rhpvtx = MRISfindClosestVertex(rhpial,vtx.x,vtx.y,vtx.z,&drhp); } if (lhwvtx < 0) { dlhw = 1000000000000000.0; } if (lhpvtx < 0) { dlhp = 1000000000000000.0; } if (rhwvtx < 0) { drhw = 1000000000000000.0; } if (rhpvtx < 0) { drhp = 1000000000000000.0; } if (dlhw <= dlhp && dlhw < drhw && dlhw < drhp && lhwvtx >= 0) { annot = lhwhite->vertices[lhwvtx].annotation; hemi = 1; if (lhwhite->ct) { CTABfindAnnotation(lhwhite->ct, annot, &annotid); } else { annotid = annotation_to_index(annot); } dmin = dlhw; } if (dlhp < dlhw && dlhp < drhw && dlhp < drhp && lhpvtx >= 0) { annot = lhwhite->vertices[lhpvtx].annotation; hemi = 1; if (lhwhite->ct) { CTABfindAnnotation(lhwhite->ct, annot, &annotid); } else { annotid = annotation_to_index(annot); } dmin = dlhp; } if (drhw < dlhp && drhw < dlhw && drhw <= drhp && rhwvtx >= 0) { annot = rhwhite->vertices[rhwvtx].annotation; hemi = 2; if (rhwhite->ct) { CTABfindAnnotation(rhwhite->ct, annot, &annotid); } else { annotid = annotation_to_index(annot); } dmin = drhw; } if (drhp < dlhp && drhp < drhw && drhp < dlhw && rhpvtx >= 0) { annot = rhwhite->vertices[rhpvtx].annotation; hemi = 2; if (rhwhite->ct) { CTABfindAnnotation(rhwhite->ct, annot, &annotid); } else { annotid = annotation_to_index(annot); } dmin = drhp; } // Sometimes the annotation will be "none" indicated by // annotid = -1. We interpret this as "unknown". if (annotid == -1) { annotid = 0; } // why was this here in the first place? /* if (annotid == 0 && lhwvtx >= 0 && lhpvtx >= 0 && rhwvtx >= 0 && rhpvtx >= 0) { printf("%d %d %d %d\n", lhwhite->vertices[lhwvtx].ripflag, lhpial->vertices[lhpvtx].ripflag, rhwhite->vertices[rhwvtx].ripflag, rhpial->vertices[rhpvtx].ripflag); } */ if ( IsCortex && hemi == 1) { segval = annotid+1000 + baseoffset; //ctx-lh } if ( IsCortex && hemi == 2) { segval = annotid+2000 + baseoffset; //ctx-rh } if (!IsCortex && hemi == 1) { segval = annotid+3000 + baseoffset; // wm-lh } if (!IsCortex && hemi == 2) { segval = annotid+4000 + baseoffset; // wm-rh } if (!IsCortex && dmin > dmaxctx && hemi == 1) { segval = 5001; } if (!IsCortex && dmin > dmaxctx && hemi == 2) { segval = 5002; } // This is a hack for getting the right cortical seg with --rip-unknown // The aparc+aseg should be passed as CtxSeg. if (IsCortex && CtxSeg) { segval = MRIgetVoxVal(CtxSeg,c,r,s,0); } MRIsetVoxVal(ASeg,c,r,s,0,segval); MRIsetVoxVal(AParc,c,r,s,0,annot); if (OutDistFile != NULL) { MRIsetVoxVal(Dist,c,r,s,0,dmin); } if (debug || annotid == -1) { // Gets here when there is no label at the found vertex. // This is different than having a vertex labeled as "unknown" if (!debug) { continue; } printf("\n"); printf("Found closest vertex, but it has no label.\n"); printf("aseg id = %d\n",asegid); printf("crs = %d %d %d, ras = %6.4f %6.4f %6.4f \n", c,r,s,vtx.x,vtx.y,vtx.z); if (lhwvtx > 0) printf("lhw %d %7.5f %6.4f %6.4f %6.4f\n", lhwvtx, dlhw, lhwhite->vertices[lhwvtx].x, lhwhite->vertices[lhwvtx].y, lhwhite->vertices[lhwvtx].z); if (lhpvtx > 0) printf("lhp %d %7.5f %6.4f %6.4f %6.4f\n", lhpvtx, dlhp, lhpial->vertices[lhpvtx].x, lhpial->vertices[lhpvtx].y, lhpial->vertices[lhpvtx].z); if (rhwvtx > 0) printf("rhw %d %7.5f %6.4f %6.4f %6.4f\n", rhwvtx, drhw, rhwhite->vertices[rhwvtx].x, rhwhite->vertices[rhwvtx].y, rhwhite->vertices[rhwvtx].z); if (rhpvtx > 0) printf("rhp %d %7.5f %6.4f %6.4f %6.4f\n", rhpvtx, drhp, rhpial->vertices[rhpvtx].x, rhpial->vertices[rhpvtx].y, rhpial->vertices[rhpvtx].z); printf("annot = %d, annotid = %d\n",annot,annotid); CTABprintASCII(lhwhite->ct,stdout); continue; } nctx++; } } } printf("nctx = %d\n",nctx); printf("Used brute-force search on %d voxels\n",nbrute); if (FixParaHipWM) { /* This is a bit of a hack. There are some vertices that have been ripped because they are "unkown". When the above alorithm finds these, it searches for the closest known vertex. If this is less than dmax away, then the wm voxel gets labeled accordingly. However, there are often some voxels near ventralDC that are just close enough in 3d space to parahip to get labeled even though they are very far away along the surface. These voxels end up forming an island. CCSegment() will eliminate any islands. Unforunately, CCSegment() uses 6-neighbor (face) definition of connectedness, so some voxels may be eliminated. */ printf("Fixing Parahip LH WM\n"); CCSegment(ASeg, 3016, 5001); //3016 = lhphwm, 5001 = unsegmented WM left printf("Fixing Parahip RH WM\n"); CCSegment(ASeg, 4016, 5002); //4016 = rhphwm, 5002 = unsegmented WM right } printf("Writing output aseg to %s\n",OutASegFile); MRIwrite(ASeg,OutASegFile); if (OutAParcFile != NULL) { printf("Writing output aparc to %s\n",OutAParcFile); MRIwrite(AParc,OutAParcFile); } if (OutDistFile != NULL) { printf("Writing output dist file to %s\n",OutDistFile); MRIwrite(Dist,OutDistFile); } return(0); }
int MRIsampleParcellationToSurface(MRI_SURFACE *mris, MRI *mri_parc) { int min_label, max_label, **label_histo, l, vno, nlabels, x, y, z, max_l ; float fmin, fmax, max_count, d ; MRIS_HASH_TABLE *mht ; VERTEX *v ; Real xs, ys, zs, xv, yv, zv, val ; MRI *mri_parc_unused ; mri_parc_unused = MRIcopy(mri_parc, NULL) ; MRIvalRange(mri_parc, &fmin, &fmax) ; min_label = (int)floor(fmin) ; max_label = (int)ceil(fmax) ; nlabels = max_label - min_label + 1 ; label_histo = (int **)calloc(mris->nvertices, sizeof(int *)) ; if (label_histo == NULL) ErrorExit(ERROR_NOMEMORY, "%s: could not create label frequency histo", Progname) ; for (vno = 0 ; vno < mris->nvertices ; vno++) { label_histo[vno] = (int *)calloc(nlabels, sizeof(int)) ; if (label_histo[vno] == NULL) ErrorExit(ERROR_NOMEMORY, "%s: could not create label frequency histo[%d] with %d bins", Progname, vno, nlabels) ; } mht = MHTfillVertexTableRes(mris, NULL, CURRENT_VERTICES, 8.0) ; MRISclearMarks(mris) ; // build histograms at each vertex for (x = 0 ; x < mri_parc->width ; x++) { for (y = 0 ; y < mri_parc->height ; y++) { for (z = 0 ; z < mri_parc->depth ; z++) { if (x == Gx && y == Gy && z == Gz) DiagBreak() ; l = (int)MRIgetVoxVal(mri_parc, x, y, z, 0) ; if (l == 0) continue ; MRIvoxelToSurfaceRAS(mri_parc, x, y, z, &xs, &ys, &zs) ; v = MHTfindClosestVertexInTable(mht, mris, xs, ys, zs, 0) ; if (v == NULL) continue ; if (sqrt(SQR(v->x-xs) + SQR(v->y-ys) + SQR(v->z-zs)) > 3) continue ; MRIsetVoxVal(mri_parc_unused, x, y, z, 0, 0) ; vno = v-mris->vertices ; if (vno == Gdiag_no) { printf("v %d: sampling from (%d, %d, %d) - %d\n", vno, x, y, z, l); DiagBreak() ; } label_histo[vno][l-min_label]++ ; } } } MRIwrite(mri_parc_unused, "pu.mgz") ; for (vno = 0 ; vno < mris->nvertices ; vno++) { if (vno == Gdiag_no) DiagBreak() ; max_l = 0 ; max_count = 0 ; for (l = 0 ; l < nlabels ; l++) { if (label_histo[vno][l] > max_count) { max_count = label_histo[vno][l] ; max_l = l+min_label ; } } v = &mris->vertices[vno] ; v->val = v->annotation = max_l ; if (max_count > 0) v->marked = 1 ; } for (vno = 0 ; vno < mris->nvertices ; vno++) { v = &mris->vertices[vno] ; if (vno == Gdiag_no) DiagBreak() ; if (v->marked) continue ; // found something here for (d = 0 ; d <= 2 ; d += 0.25) { xs = v->x + d*v->nx; ys = v->y + d*v->ny; zs = v->z + d*v->nz; MRIsurfaceRASToVoxel(mri_parc, xs, ys, zs, &xv, &yv, &zv); MRIsampleVolumeType(mri_parc, xv, yv, zv, &val, SAMPLE_NEAREST) ; l = (int)nint(val) ; if (l > 0) { v->val = v->annotation = l ; break ; } } } MHTfree(&mht) ; for (vno = 0 ; vno < mris->nvertices ; vno++) free(label_histo[vno]) ; free(label_histo) ; MRIfree(&mri_parc_unused) ; return(NO_ERROR) ; }
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 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) ; }
/*--------------------------------------------------*/ int main(int argc, char **argv) { int nargs, err, asegid, c, r, s, annot, hemioffset; int annotid; struct utsname uts; char *cmdline, cwd[2000]; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, vcid, "$Name: stable5 $"); if (nargs && argc - nargs == 1) exit (0); argc -= nargs; cmdline = argv2cmdline(argc,argv); uname(&uts); getcwd(cwd,2000); Progname = argv[0] ; argc --; argv++; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; if (argc == 0) usage_exit(); parse_commandline(argc, argv); check_options(); dump_options(stdout); printf("\n"); printf("%s\n",vcid); printf("cwd %s\n",cwd); printf("cmdline %s\n",cmdline); printf("sysname %s\n",uts.sysname); printf("hostname %s\n",uts.nodename); printf("machine %s\n",uts.machine); SUBJECTS_DIR = getenv("SUBJECTS_DIR"); if (SUBJECTS_DIR==NULL) { printf("ERROR: SUBJECTS_DIR not defined in environment\n"); exit(1); } printf("SUBJECTS_DIR %s\n",SUBJECTS_DIR); printf("subject %s\n",subject); printf("\n"); fflush(stdout); /* ------ Load subject's lh white surface ------ */ sprintf(tmpstr,"%s/%s/surf/lh.white",SUBJECTS_DIR,subject); printf("Reading lh white surface \n %s\n",tmpstr); lhwhite = MRISread(tmpstr); if (lhwhite == NULL) { fprintf(stderr,"ERROR: could not read %s\n",tmpstr); exit(1); } printf("Building hash of lh white\n"); lhwhite_hash = MHTfillVertexTableRes(lhwhite, NULL,CURRENT_VERTICES,16); /* ------ Load lh annotation ------ */ sprintf(annotfile,"%s/%s/label/lh.aparc.annot",SUBJECTS_DIR,subject); printf("Loading lh annotations from %s\n",annotfile); err = MRISreadAnnotation(lhwhite, annotfile); if (err) { printf("ERROR: MRISreadAnnotation() failed %s\n",annotfile); exit(1); } /* ------ Load subject's rh surface ------ */ sprintf(tmpstr,"%s/%s/surf/rh.white",SUBJECTS_DIR,subject); printf("Reading rh white surface \n %s\n",tmpstr); rhwhite = MRISread(tmpstr); if (rhwhite == NULL) { fprintf(stderr,"ERROR: could not read %s\n",tmpstr); exit(1); } if (debug) printf("Building hash of rh white\n"); rhwhite_hash = MHTfillVertexTableRes(rhwhite, NULL,CURRENT_VERTICES,16); /* ------ Load rh annotation ------ */ sprintf(annotfile,"%s/%s/label/rh.aparc.annot",SUBJECTS_DIR,subject); printf("Loading rh annotations from %s\n",annotfile); err = MRISreadAnnotation(rhwhite, annotfile); if (err) { printf("ERROR: MRISreadAnnotation() failed %s\n",annotfile); exit(1); } if (debug && lhwhite->ct) printf("Have color table for annotation\n"); if (debug) print_annotation_table(stdout); /* ------ Load ASeg ------ */ sprintf(tmpstr,"%s/%s/mri/aseg.mgz",SUBJECTS_DIR,subject); if (!fio_FileExistsReadable(tmpstr)) { sprintf(tmpstr,"%s/%s/mri/aseg.mgh",SUBJECTS_DIR,subject); if (!fio_FileExistsReadable(tmpstr)) { sprintf(tmpstr,"%s/%s/mri/aseg/COR-.info",SUBJECTS_DIR,subject); if (!fio_FileExistsReadable(tmpstr)) { printf("ERROR: cannot find aseg\n"); exit(1); } else sprintf(tmpstr,"%s/%s/mri/aseg/",SUBJECTS_DIR,subject); } } printf("Loading aseg from %s\n",tmpstr); ASeg = MRIread(tmpstr); if (ASeg == NULL) { printf("ERROR: loading aseg %s\n",tmpstr); exit(1); } mritmp = MRIchangeType(ASeg,MRI_INT,0,0,0); MRIfree(&ASeg); ASeg = mritmp; WMSeg = MRIclone(ASeg,NULL); Vox2RAS = MRIxfmCRS2XYZtkreg(ASeg); if (debug) { printf("ASeg Vox2RAS: -----------\n"); MatrixPrint(stdout,Vox2RAS); printf("-------------------------\n"); } CRS = MatrixAlloc(4,1,MATRIX_REAL); CRS->rptr[4][1] = 1; RAS = MatrixAlloc(4,1,MATRIX_REAL); RAS->rptr[4][1] = 1; // Go through each voxel in the aseg printf("\n"); printf("Labeling WM\n"); for (c=0; c < ASeg->width; c++) { if (debug) printf("%3d ",c); if (debug && c%20 ==19) printf("\n"); for (r=0; r < ASeg->height; r++) { for (s=0; s < ASeg->depth; s++) { // If it's not labeled as white matter in the aseg, set // seg value to that from the aseg and skip the rest asegid = MRIgetVoxVal(ASeg,c,r,s,0); if (asegid != 2 && asegid != 41) { MRIsetVoxVal(WMSeg,c,r,s,0,asegid); continue; } // Convert the CRS to RAS CRS->rptr[1][1] = c; CRS->rptr[2][1] = r; CRS->rptr[3][1] = s; RAS = MatrixMultiply(Vox2RAS,CRS,RAS); vtx.x = RAS->rptr[1][1]; vtx.y = RAS->rptr[2][1]; vtx.z = RAS->rptr[3][1]; // Get the index of the closest vertex in the // lh.white, rh.white lhwvtx = MHTfindClosestVertexNo(lhwhite_hash,lhwhite,&vtx,&dlhw); rhwvtx = MHTfindClosestVertexNo(rhwhite_hash,rhwhite,&vtx,&drhw); if ( (lhwvtx < 0) && (rhwvtx < 0) ) { printf("ERROR: could not map to any surface.\n"); printf("crs = %d %d %d, ras = %6.4f %6.4f %6.4f \n", c,r,s,vtx.x,vtx.y,vtx.z); exit(1); } if (lhwvtx < 0) dlhw = 1000000000000000.0; if (rhwvtx < 0) drhw = 1000000000000000.0; if (dlhw < drhw) { // Left hemi is closer than the right annot = lhwhite->vertices[lhwvtx].annotation; hemioffset = 1000; if (lhwhite->ct) CTABfindAnnotation(lhwhite->ct, annot, &annotid); else annotid = annotation_to_index(annot); } else { // Right hemi is closer than the left annot = rhwhite->vertices[rhwvtx].annotation; hemioffset = 2000; if (rhwhite->ct) CTABfindAnnotation(lhwhite->ct, annot, &annotid); else annotid = annotation_to_index(annot); } MRIsetVoxVal(WMSeg,c,r,s,0,annotid+hemioffset); } } } printf("\nWriting output wmseg to %s\n",WMSegFile); MRIwrite(WMSeg,WMSegFile); printf("mri_aparc2wmseg done\n"); return(0); }
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) ; }