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) ; }
static MRI * make_atrophy_map(MRI *mri_time1, MRI *mri_time2, MRI *mri_dst, TRANSFORM *transform1, TRANSFORM *transform2, int *gray_labels, int ngray, int *csf_labels, int ncsf) { int x, y, z, label1, label2, n, found, xp, yp, zp, spacing ; GCA_MORPH_NODE *gcamn1, *gcamn2 ; GCA_MORPH *gcam1, *gcam2 ; float volume ; if (mri_dst == NULL) { mri_dst = MRIalloc(mri_time1->width, mri_time1->height, mri_time1->depth, MRI_FLOAT) ; MRIcopyHeader(mri_time1, mri_dst) ; } gcam1 = (GCA_MORPH*)transform1->xform ; gcam2 = (GCA_MORPH*)transform2->xform ; spacing = gcam1->spacing ; for (x = 0 ; x < mri_time1->width ; x++) { xp = x / spacing; for (y = 0 ; y < mri_time1->height ; y++) { yp = y / spacing; for (z = 0 ; z < mri_time1->depth ; z++) { if (x == Gx && y == Gy && z == Gz) DiagBreak() ; label1 = MRIgetVoxVal(mri_time1, x, y, z, 0) ; label2 = MRIgetVoxVal(mri_time2, x, y, z, 0) ; if (label1 == label2) continue ; /* if label1 was one of the gray types and label2 one of the csf, call it atrophy */ for (found = n = 0 ; n < ngray ; n++) if (label1 == gray_labels[n]) { found = 1 ; break ; } if (found == 0) continue ; for (found = n = 0 ; n < ncsf ; n++) if (label2 == csf_labels[n]) { found = 1 ; break ; } if (found == 0) continue ; zp = z / spacing; gcamn1 = &gcam1->nodes[xp][yp][zp] ; gcamn2 = &gcam2->nodes[xp][yp][zp] ; volume = 0 ; if (FZERO(gcamn1->area) == 0) volume += gcamn1->orig_area / gcamn1->area ; if (FZERO(gcamn2->area) == 0) volume += gcamn2->orig_area / gcamn2->area ; MRIsetVoxVal(mri_dst, x, y, z, 0, volume) ; } } } return(mri_dst) ; }
static MRI * compute_bias(MRI *mri_src, MRI *mri_dst, MRI *mri_bias) { int x, y, z ; float bias, src, dst ; if (!mri_bias) mri_bias = MRIalloc (mri_src->width, mri_src->height, mri_src->depth, MRI_FLOAT) ; MRIcopyHeader(mri_src, mri_bias) ; for (x = 0 ; x < mri_src->width ; x++) { for (y = 0; y < mri_src->height ; y++) { for (z = 0 ; z < mri_src->depth ; z++) { src = MRIgetVoxVal(mri_src, x, y, z, 0) ; dst = MRIgetVoxVal(mri_dst, x, y, z, 0) ; if (FZERO(src)) { bias = 1 ; } else { bias = dst/src ; } MRIsetVoxVal(mri_bias, x, y, z, 0, bias) ; } } } return(mri_bias) ; }
static MRI * MRIupdatePriors(MRI *mri_binary, MRI *mri_priors) { int width, height, depth, x, y, z ; BUFTYPE *pbin ; float prob ; width = mri_binary->width ; height = mri_binary->height ; depth = mri_binary->depth ; if (!mri_priors) { mri_priors = MRIalloc(width, height, depth, MRI_FLOAT) ; } for (z = 0 ; z < depth ; z++) { for (y = 0 ; y < height ; y++) { pbin = &MRIvox(mri_binary, 0, y, z) ; for (x = 0 ; x < width ; x++) { if (x == DEBUG_X && y == DEBUG_Y && z == DEBUG_Z) DiagBreak() ; prob = *pbin++ / 100.0f ; MRIFvox(mri_priors, x, y, z) += prob ; } } } return(mri_priors) ; }
static MRI * MRIcomputePriors(MRI *mri_priors, int ndof, MRI *mri_char_priors) { int width, height, depth, x, y, z ; BUFTYPE *pchar_prior, char_prior ; float *pprior, prior ; width = mri_priors->width ; height = mri_priors->height ; depth = mri_priors->depth ; if (!mri_char_priors) { mri_char_priors = MRIalloc(width, height, depth, MRI_UCHAR) ; } for (z = 0 ; z < depth ; z++) { for (y = 0 ; y < height ; y++) { pprior = &MRIFvox(mri_priors, 0, y, z) ; pchar_prior = &MRIvox(mri_char_priors, 0, y, z) ; for (x = 0 ; x < width ; x++) { if (x == DEBUG_X && y == DEBUG_Y && z == DEBUG_Z) DiagBreak() ; prior = *pprior++ ; if (prior > 0) DiagBreak() ; if (prior > 10) DiagBreak() ; char_prior = (BUFTYPE)nint(100.0f*prior/(float)ndof) ; if (char_prior > 101) DiagBreak() ; *pchar_prior++ = char_prior ; } } } return(mri_char_priors) ; }
MRI * MRIsadd(MRI *mri1, MRI *mri2, MRI *mri_dst) { int width, height, depth, x, y, z ; short *p1, *p2, *pdst ; width = mri1->width ; height = mri1->height ; depth = mri1->depth ; if (!mri_dst) { mri_dst = MRIalloc(width, height, depth, mri1->type) ; MRIcopyHeader(mri1, mri_dst) ; } for (z = 0 ; z < depth ; z++) { for (y = 0 ; y < height ; y++) { p1 = &MRISvox(mri1, 0, y, z) ; p2 = &MRISvox(mri2, 0, y, z) ; pdst = &MRISvox(mri_dst, 0, y, z) ; for (x = 0 ; x < width ; x++) *pdst++ = *p1++ + *p2++ ; } } return(mri_dst) ; }
static int write_snapshot(MRI *mri_target, MRI *mri_source, MATRIX *m_vox_xform, GCA_MORPH_PARMS *parms, int fno, int conform, char *in_fname) { MRI *mri_aligned ; char fname[STRLEN] ; if (Gdiag & DIAG_SHOW && DIAG_VERBOSE_ON) { printf("source->target vox->vox transform:\n") ; MatrixPrint(stdout, m_vox_xform) ; } if (conform || 1) { mri_aligned = MRIalloc(mri_target->width, mri_target->height, mri_target->depth,mri_source->type); MRIcopyHeader(mri_target, mri_aligned) ; MRIlinearTransformInterp(mri_source, mri_aligned, m_vox_xform, SAMPLE_NEAREST); } else { mri_aligned = MRITransformedCenteredMatrix(mri_source, mri_target, m_vox_xform) ; } if (in_fname) sprintf(fname, "%s_%s", parms->base_name, in_fname) ; else sprintf(fname, "%s_%03d", parms->base_name, fno) ; MRIwriteImageViews(mri_aligned, fname, IMAGE_SIZE) ; if (in_fname) sprintf(fname, "%s_%s.mgz", parms->base_name, in_fname) ; else sprintf(fname, "%s_%03d.mgz", parms->base_name, fno) ; printf("writing snapshot to %s...\n", fname) ; MRIwrite(mri_aligned, fname) ; MRIfree(&mri_aligned) ; { #if 0 mri_aligned = MRIsrcTransformedCentered(mri_source, mri_target, m_vox_xform, SAMPLE_NEAREST) ; #else mri_aligned = MRITransformedCenteredMatrix(mri_source, mri_target, m_vox_xform) ; #endif if (in_fname) sprintf(fname, "orig_%s_%s.mgz", parms->base_name, in_fname) ; else sprintf(fname, "orig_%s_%03d.mgz", parms->base_name, fno) ; printf("writing snapshot to %s...\n", fname) ; MRIwrite(mri_aligned, fname) ; MRIfree(&mri_aligned) ; } return(NO_ERROR) ; }
MRI * MRIcomputeConditionalProbabilities(MRI *mri_T1, MRI *mri_mean, MRI *mri_std, MRI *mri_dst) { int x, y, z, width, height, depth ; BUFTYPE *pT1, *pmean, *pstd ; float p, mean, std, val, n, *pdst ; width = mri_T1->width ; height = mri_T1->height ; depth = mri_T1->depth ; if (!mri_dst) mri_dst = MRIalloc(width, height, depth, MRI_FLOAT) ; for (z = 0 ; z < depth ; z++) { for (y = 0 ; y < height ; y++) { pT1 = &MRIvox(mri_T1, 0, y, z) ; pmean = &MRIvox(mri_mean, 0, y, z) ; pstd = &MRIvox(mri_std, 0, y, z) ; pdst = &MRIFvox(mri_dst, 0, y, z) ; for (x = 0 ; x < width ; x++) { if (DEBUG_POINT(x,y,z)) DiagBreak() ; val = (float)*pT1++ ; mean = (float)*pmean++ ; std = (float)*pstd++ ; if (FZERO(std)) std = 1.0 ; #if 0 if (std < 10.0) /* hack!!!!! - not enough observations */ std = 10.0 ; #endif n = 1 / (std * sqrt(2.0*M_PI)) ; p = n * exp(-SQR(val - mean) / (2.0f*SQR(std))) ; *pdst++ = p*100.0f ; } } } return(mri_dst) ; }
int main(int argc, char *argv[]) { MRI *mri; Progname=argv[0]; printf("Generating test_volume.mgz...\n"); mri=MRIalloc(20,20,20,MRI_UCHAR); MRIvox(mri,10,10,10)=255; MRIvox(mri,11,10,10)=255; MRIvox(mri,11,11,10)=255; MRIvox(mri,11,11,11)=255; MRIvox(mri,10,11,11)=255; MRIvox(mri,10,10,11)=255; MRIwrite(mri,"test_volume.mgz"); return 0; }
MRI * MRIbinarizeEditting(MRI *mri_src, MRI *mri_dst) { int width, height, depth, x, y, z, val ; BUFTYPE * width = mri_src->width ; height = mri_src->height ; depth = mri_src->depth ; mri_dst = MRIalloc(width, height, depth, MRI_UCHAR) ; if (!mri_dst) mri_dst = MRIclone(mri_src, NULL) ; MRIvalRange(mri_src, &fmin, &fmax) ; for (z = 0 ; z < depth ; z++) { for (y = 0 ; y < height ; y++) { for (x = 0 ; x < width ; x++) {} } } return(mri_dst) ; }
MRI * MRIfloatToChar(MRI *mri_src, MRI *mri_dst) { int width, height, depth/*, x, y, z, out_val*/ ; /* float fmax, fmin ;*/ width = mri_src->width ; height = mri_src->height ; depth = mri_src->depth ; if (!mri_dst) mri_dst = MRIalloc(width, height, depth, MRI_UCHAR) ; #if 1 MRIcopy(mri_src, mri_dst) ; #else MRIvalRange(mri_src, &fmin, &fmax) ; for (z = 0 ; z < depth ; z++) { for (y = 0 ; y < height ; y++) { for (x = 0 ; x < width ; x++) {} } } #endif return(mri_dst) ; }
MRI * correct_gmwm_boundaries_2(MRI *segmri, MRI *outmri) { int x, y, z, width, height, depth = 0; double val; MRI *allvol = NULL; MRI *allmaskdist, *label2, *label2distmap, *label41, *label41distmap = NULL; width = segmri->width ; height = segmri->height ; depth = segmri->depth ; // all lables allvol = MRIclone(segmri, NULL) ; for (z = 0 ; z < depth ; z++) for (y = 0 ; y < height ; y++) for (x = 0 ; x < width ; x++) { val = MRIgetVoxVal(segmri,x,y,z,0); if (val > 0) MRIsetVoxVal(allvol,x,y,z,0,1); } allmaskdist = MRIalloc(width, height, depth, MRI_FLOAT); allmaskdist = MRIextractDistanceMap(allvol, allmaskdist, 1, 3, 3, NULL); // label 2 label2 = MRIclone(segmri, NULL) ; for (z = 0 ; z < depth ; z++) for (y = 0 ; y < height ; y++) for (x = 0 ; x < width ; x++) { val = MRIgetVoxVal(segmri,x,y,z,0); if (val == 2) MRIsetVoxVal(label2,x,y,z,0,1); } label2distmap = MRIalloc(width, height, depth, MRI_FLOAT); label2distmap = MRIextractDistanceMap(label2, label2distmap, 1, 3, 3, NULL); // label 41 label41 = MRIclone(segmri, NULL) ; for (z = 0 ; z < depth ; z++) for (y = 0 ; y < height ; y++) for (x = 0 ; x < width ; x++) { val = MRIgetVoxVal(segmri,x,y,z,0); if (val == 41) MRIsetVoxVal(label41,x,y,z,0,1); } label41distmap = MRIalloc(width, height, depth, MRI_FLOAT); label41distmap = MRIextractDistanceMap(label41, label41distmap, 1, 3, 3, NULL); if (!outmri) outmri = MRIclone(segmri, NULL) ; for (z = 0 ; z < depth ; z++) for (y = 0 ; y < height ; y++) for (x = 0 ; x < width ; x++) { if(MRIgetVoxVal(allvol,x,y,z,0) == 1) { if((fabs(MRIgetVoxVal(allmaskdist,x,y,z,0)) <= .5) && (MRIgetVoxVal(label41distmap,x,y,z,0) <=0 )) MRIsetVoxVal(outmri,x,y,z,0,42); else if((fabs(MRIgetVoxVal(allmaskdist,x,y,z,0)) <= .5) && (MRIgetVoxVal(label2distmap,x,y,z,0) <=0 )) MRIsetVoxVal(outmri,x,y,z,0,3); } } return(outmri) ; }
int main(int argc, char *argv[]) { tesselation_parms *parms; MRIS **mris_table, *mris,*mris_corrected; MRI *mri; char cmdline[CMD_LINE_LEN] ; make_cmd_version_string (argc, argv, "$Id: mri_mc.c,v 1.22 2011/03/02 00:04:23 nicks Exp $", "$Name: stable5 $", cmdline); Progname=argv[0]; if (argc > 1 && (stricmp(argv[1], "-d") == 0)) { downsample = atoi(argv[2]) ; argc -= 2; argv += 2 ; printf("downsampling input volume %d times\n", downsample) ; } if (argc < 4) { fprintf(stderr,"\n\nUSAGE: mri_mc input_volume " "label_value output_surface [connectivity]"); fprintf(stderr, "\noption connectivity: 1=6+,2=18,3=6,4=26 (default=1)\n\n"); exit(-1); } parms=(tesselation_parms*)calloc(1,sizeof(tesselation_parms)); if (!parms) ErrorExit(ERROR_NOMEMORY, "tesselation parms\n") ; mri=MRIread(argv[1]); if (downsample > 0) { MRI *mri_tmp ; mri_tmp = MRIdownsample2(mri, NULL) ; MRIfree(&mri) ; mri = mri_tmp ; } { MRI *mri_tmp ; mri_tmp = MRIalloc(mri->width+2, mri->height+2, mri->depth+2, mri->type) ; MRIextractInto(mri, mri_tmp, 0, 0, 0, mri->width, mri->height, mri->depth, 1, 1, 1) ; MRIfree(&mri) ; mri = mri_tmp ; } MRIreInitCache(mri); if (mri->type != MRI_UCHAR) { MRI *mri_tmp ; float min_val, max_val ; MRIvalRange(mri, &min_val, &max_val) ; if (min_val < 0 || max_val > 255) ErrorExit (ERROR_UNSUPPORTED, "%s: input volume (val range [%2.1f %2.1f]) must be " "convertible to UCHAR", Progname, min_val, max_val) ; printf("changing type of input volume to 8 bits/voxel...\n") ; mri_tmp = MRIchangeType(mri, MRI_UCHAR, 0.0, 0.999, TRUE) ; MRIfree(&mri) ; mri = mri_tmp ; } parms->mri=mri; parms->number_of_labels=1; //only one single label parms->label_values=(int*)malloc(sizeof(int)); parms->label_values[0]=atoi(argv[2]);//label; parms->ind=0; mris_table=(MRIS**)malloc(sizeof(MRIS*)); //final surface information parms->mris_table=mris_table; if ((!parms->label_values) || (!mris_table)) ErrorExit(ERROR_NOMEMORY, "labels/surfaces tables\n") ; if (argc==5) parms->connectivity=atoi(argv[4]);//connectivity; else parms->connectivity=1; initTesselationParms(parms); generateMCtesselation(parms); free(parms->label_values); mris=parms->mris_table[0]; free(parms->mris_table); freeTesselationParms(&parms); { float dist,max_e=0.0; int n,p,vn0,vn2; VERTEX *v,*vp; fprintf(stderr,"computing the maximum edge length..."); for (n = 0 ; n < mris->nvertices ; n++) { v=&mris->vertices[n]; for (p = 0 ; p < v->vnum ; p++) { vp = &mris->vertices[v->v[p]]; dist=SQR(vp->x-v->x)+SQR(vp->y-v->y)+SQR(vp->z-v->z); if (dist>max_e) max_e=dist; } } fprintf(stderr,"%f mm",sqrt(max_e)); fprintf(stderr,"\nreversing orientation of faces..."); for (n = 0 ; n < mris->nfaces ; n++) { vn0=mris->faces[n].v[0]; vn2=mris->faces[n].v[2]; /* vertex 0 becomes vertex 2 */ v=&mris->vertices[vn0]; for (p = 0 ; p < v->num ; p++) if (v->f[p]==n) v->n[p]=2; mris->faces[n].v[2]=vn0; /* vertex 2 becomes vertex 0 */ v=&mris->vertices[vn2]; for (p = 0 ; p < v->num ; p++) if (v->f[p]==n) v->n[p]=0; mris->faces[n].v[0]=vn2; } } fprintf(stderr,"\nchecking orientation of surface..."); MRISmarkOrientationChanges(mris); mris_corrected=MRISextractMainComponent(mris,0,1,0); MRISfree(&mris); fprintf(stderr,"\nwriting out surface..."); MRISaddCommandLine(mris_corrected, cmdline) ; if (mriConformed(mri) == 0) { printf("input volume is not conformed - using useRealRAS=1\n") ; mris_corrected->useRealRAS = 1 ; } // getVolGeom(mri, &mris_corrected->vg); MRISwrite(mris_corrected,argv[3]); fprintf(stderr,"done\n"); MRIfree(&mri); MRISfree(&mris_corrected); return 0; }
int main(int argc, char *argv[]) { char **av, *in_fname, *out_fname ; int ac, nargs, i, label ; MRI *mri_in, *mri_out, *mri_kernel, *mri_smoothed ; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mri_extract_label.c,v 1.13 2011/03/02 00:04:15 nicks Exp $", "$Name: $"); if (nargs && argc - nargs == 1) exit (0); argc -= nargs; Progname = argv[0] ; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; 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() ; in_fname = argv[1] ; out_fname = argv[argc-1] ; printf("reading volume from %s...\n", in_fname) ; mri_in = MRIread(in_fname) ; if (!mri_in) ErrorExit(ERROR_NOFILE, "%s: could not read MRI volume %s", Progname, in_fname) ; if (out_like_fname) { MRI *mri_tmp = MRIread(out_like_fname) ; if (!mri_tmp) ErrorExit (ERROR_NOFILE, "%s: could not read template volume from %s", out_like_fname) ; mri_out = MRIalloc(mri_tmp->width, mri_tmp->height, mri_tmp->depth, mri_tmp->type) ; /* MRIcopyHeader(mri_tmp, mri_out) ;*/ MRIfree(&mri_tmp) ; } else mri_out = MRIclone(mri_in, NULL) ; for (i = 2 ; i < argc-1 ; i++) { label = atoi(argv[i]) ; printf("extracting label %d (%s)\n", label, cma_label_to_name(label)) ; extract_labeled_image(mri_in, transform, label, mri_out) ; } if (!FZERO(sigma)) { printf("smoothing extracted volume...\n") ; mri_kernel = MRIgaussian1d(sigma, 10*sigma) ; mri_smoothed = MRIconvolveGaussian(mri_out, NULL, mri_kernel) ; MRIfree(&mri_out) ; mri_out = mri_smoothed ; } /* removed for gcc3.3 * vsprintf(out_fname, out_fname, (va_list) &label) ; */ if (dilate > 0) { int i ; printf("dilating output volume %d times...\n", dilate) ; for (i = 0 ; i < dilate ; i++) MRIdilate(mri_out, mri_out) ; } if (erode > 0) { int i ; printf("eroding output volume %d times...\n", erode) ; for (i = 0 ; i < erode ; i++) MRIerode(mri_out, mri_out) ; } printf("writing output to %s.\n", out_fname) ; MRIwrite(mri_out, out_fname) ; if (exit_none_found && (nvoxels == 0)) { printf("No voxels with specified label were found!\n"); exit(1); } exit(0) ; return(0) ; /* for ansi */ }
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) ; }
int main(int argc, char *argv[]) { char **av, *in_vol, *out_vol; int ac, nargs; MRI *mri_in, *mri_out, *mri_tmp ; LTA *lta = 0; MATRIX *i_to_r_src = 0; /* src geometry of the input LTA */ MATRIX *V_to_V = 0; /* Final voxel-to-voxel transform */ MATRIX *r_to_i_dst = 0; /* dst geometry of the input LTA */ MATRIX *m_tmp = 0; MATRIX *i_to_r_reg = 0; /* i_to_r of the volume after registration */ MATRIX *r_to_i_out = 0; /* r_to_i of the final output volume */ VOL_GEOM vgm_in; int x, y, z; double maxV, minV, value; // MATRIX *i_to_r, *r_to_i; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mri_transform_to_COR.c,v 1.8 2011/03/02 00:04:55 nicks Exp $", "$Name: stable5 $"); if (nargs && argc - nargs == 1) usage_exit (0); argc -= nargs; Progname = argv[0] ; ErrorInit(NULL, NULL, NULL) ; DiagInit(NULL, NULL, NULL) ; 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(0) ; in_vol = argv[1] ; out_vol = argv[2] ; printf("reading volume from %s...\n", in_vol) ; mri_in = MRIread(in_vol) ; if (!mri_in) ErrorExit(ERROR_NOFILE, "%s: could not read MRI volume %s", Progname, in_vol) ; /* Convert mri_in to float type */ /* double would be more accurate */ if (mri_in->type != MRI_FLOAT) { printf("Input volume type is %d\n", mri_in->type); printf("Change input volume to float type for convenience and accuracy"); mri_tmp = MRIchangeType(mri_in, MRI_FLOAT, 0, 1.0, 1); MRIfree(&mri_in); mri_in = mri_tmp; //swap } /* Get input volume geometry, which is needed to compute i_to_r * and r_to_i of input volume. Note that i_to_r and r_to_i assumed * a certain prespecified c_r, c_a, c_s */ getVolGeom(mri_in, &vgm_in); maxV = -10000.0; minV = 10000.0; for (z=0; z < mri_in->depth; z++) for (y=0; y< mri_in->height; y++) for (x=0; x < mri_in->width; x++) { if (MRIFvox(mri_in, x, y, z) > maxV ) maxV = MRIFvox(mri_in, x, y,z) ; if (MRIFvox(mri_in, x, y, z) < minV ) minV = MRIFvox(mri_in, x, y,z) ; } printf("Input volume has max = %g, min =%g\n", maxV, minV); printf("Scale input volume by %g \n", scale); maxV = -10000.0; minV = 10000.0; for (z=0; z < mri_in->depth; z++) for (y=0; y< mri_in->height; y++) for (x=0; x < mri_in->width; x++) { MRIFvox(mri_in, x, y, z) *= scale; if (MRIFvox(mri_in, x, y, z) > maxV ) maxV = MRIFvox(mri_in, x, y,z) ; if (MRIFvox(mri_in, x, y, z) < minV ) minV = MRIFvox(mri_in, x, y,z) ; } printf("Input volume after scaling has max = %g, min =%g\n", maxV, minV); /* Try to compute the Voxel_to_Voxel transform from the input volume * and the registration target/reference volume! * If no registration is involved, vox_to_vox is simply identity */ /* Things become more complicated when allowing inverse transform */ if (transform_flag) { int transform_type; printf("INFO: Applying transformation from file %s...\n", transform_fname); transform_type = TransformFileNameType(transform_fname); /* Read in LTA transform file name */ if (transform_type == MNI_TRANSFORM_TYPE || transform_type == TRANSFORM_ARRAY_TYPE || transform_type == REGISTER_DAT || transform_type == FSLREG_TYPE ) { printf("Reading transform ...\n"); lta = LTAreadEx(transform_fname) ; if (!lta) ErrorExit(ERROR_NOFILE, "%s: could not read transform file %s", Progname, transform_fname) ; if (transform_type == FSLREG_TYPE) { if (lta_src == 0 || lta_dst == 0) { fprintf(stderr, "ERROR: fslmat does not have information on the src and dst volumes\n"); fprintf(stderr, "ERROR: you must give options '-src' and '-dst' to specify the src and dst volume infos for the registration\n"); } LTAmodifySrcDstGeom(lta, lta_src, lta_dst); // add src and dst information //The following is necessary to interpret FSLMAT correctly!!! LTAchangeType(lta, LINEAR_VOX_TO_VOX); } if (lta->xforms[0].src.valid == 0) { if (lta_src == 0) { fprintf(stderr, "The transform does not have the valid src volume info.\n"); fprintf(stderr, "Either you give src volume info by option -src or\n"); fprintf(stderr, "make the transform to have the valid src info.\n"); ErrorExit(ERROR_BAD_PARM, "Bailing out...\n"); } else { LTAmodifySrcDstGeom(lta, lta_src, NULL); // add src information } } if (lta->xforms[0].dst.valid == 0) { if (lta_dst == 0) { fprintf(stderr, "The transform does not have the valid dst volume info.\n"); fprintf(stderr, "Either you give src volume info by option -dst or\n"); fprintf(stderr, "make the transform to have the valid dst info.\n"); fprintf(stderr, "If the dst was average_305, then you can set\n"); fprintf(stderr, "environmental variable USE_AVERAGE305 true\n"); fprintf(stderr, "instead.\n"); ErrorExit(ERROR_BAD_PARM, "Bailing out...\n"); } else { LTAmodifySrcDstGeom(lta, NULL, lta_dst); // add dst information } } // The following procedure aims to apply an LTA computed from COR format to a volume in non-COR format, or vice versa, as long as they share the same RAS // first change to LINEAR RAS_TO_RAS using old info if (lta->type != LINEAR_RAS_TO_RAS) { LTAchangeType(lta, LINEAR_RAS_TO_RAS); } // now possiblly reset the src and dst if (lta_src != NULL) { //always trust the user LTAmodifySrcDstGeom(lta, lta_src, NULL); } if (lta_dst != NULL) { //always trust the user LTAmodifySrcDstGeom(lta, NULL, lta_dst); } if (lta->type == LINEAR_RAS_TO_RAS) { /* Convert it to VOX_TO_VOX */ /* VOXELsrc_to_VOXELdst = R2Vdst*R2Rlta*V2Rsrc */ /* Note whether the input should be identical to src or dst here depends * on whether the LTA here is the direct or inverse transform */ i_to_r_src = vg_i_to_r(<a->xforms[0].src); r_to_i_dst = vg_r_to_i(<a->xforms[0].dst); if (!r_to_i_dst || !i_to_r_src) ErrorExit(ERROR_BADFILE, "%s: failed to extract volume geometries from input LTA file",Progname); m_tmp = MatrixMultiply(lta->xforms[0].m_L, i_to_r_src, NULL); V_to_V = MatrixMultiply(r_to_i_dst, m_tmp, NULL); MatrixFree(&m_tmp); MatrixFree(&i_to_r_src); MatrixFree(&r_to_i_dst); } } else { fprintf(stderr, "unknown transform type in file %s\n", transform_fname); exit(1); } if (invert_flag) { /* Geometry of input volume should match that of the dst of the LTA */ if (MYvg_isEqual(<a->xforms[0].dst, &vgm_in) == 0) { ErrorExit(ERROR_BADFILE, "%s: dst volume of lta doesn't match that of input volume",Progname); } i_to_r_reg = vg_i_to_r(<a->xforms[0].src); if (!i_to_r_reg) ErrorExit(ERROR_BADFILE, "%s: failed to extract i_to_r of registered volume from LTA",Progname); m_tmp = MatrixInverse(V_to_V, NULL); if (!m_tmp) ErrorExit(ERROR_BADPARM, "%s: transform is singular!", Progname); MatrixFree(&V_to_V); V_to_V = m_tmp; } else { /* Geometry of input volume should match that of the src of the LTA */ if (MYvg_isEqual(<a->xforms[0].src, &vgm_in) == 0) { ErrorExit(ERROR_BADFILE, "%s: src volume of lta doesn't match that of input volume",Progname); } i_to_r_reg = vg_i_to_r(<a->xforms[0].dst); if (!i_to_r_reg) ErrorExit(ERROR_BADFILE, "%s: failed to extract i_to_r of registered volume from LTA",Progname); } } else { /* No registration transform need be applied */ V_to_V = MatrixIdentity(4, NULL); i_to_r_reg = extract_i_to_r(mri_in); if (!i_to_r_reg) ErrorExit(ERROR_BADFILE, "%s: failed to extract i_to_r from input volume",Progname); } /* Now need to find the vox-to-vox transformation between registered volume * (or input volume itself if no registration involved) and the output * volume, either in COR format or as the out-like volume */ /* Given a volume with a certain i_to_r, we need to compute the necessary * vox-to-voxel transform to change its i_to_r to like another volume. * The vox-to-vox is equal to R2V(r_to_i)_likevol*i_to_r_current_vol. */ if (out_like_fname) { mri_tmp = MRIread(out_like_fname) ; if (!mri_tmp) ErrorExit(ERROR_NOFILE, "%s: could not read template volume from %s",out_like_fname) ; /* out_type = mri_tmp->type; */ /* specify the out-type to float initially so as not to lose accuracy * during reslicing, will change type to correct type later. */ mri_out = MRIalloc(mri_tmp->width, mri_tmp->height, mri_tmp->depth, MRI_FLOAT) ; MRIcopyHeader(mri_tmp, mri_out) ; MRIfree(&mri_tmp); } else /* assume output is in COR format */ { mri_out = MRIalloc(256, 256, 256, MRI_FLOAT) ; /* out_type = MRI_UCHAR; */ /* Who says MRIlinearTransformInterp will change the header?? * I don't think so! */ //E/ set xyzc_ras to coronal ones.. - these'll get zorched //by MRIlinearTransformInterp() - copy again later - is there //any use in having them here now? yes, so we can pass mri_out //to the ras2vox fns. mri_out->imnr0 = 1; /* what's this? */ mri_out->imnr1 = 256; /* what's this? */ mri_out->thick = 1.0; mri_out->ps = 1.0; /* what's this? */ mri_out->xsize = mri_out->ysize = mri_out->zsize = 1.0; mri_out->xstart = mri_out->ystart = mri_out->zstart = -128.0; mri_out->xend = mri_out->yend = mri_out->zend = 128.0; mri_out->x_r =-1; mri_out->y_r = 0; mri_out->z_r = 0; mri_out->x_a = 0; mri_out->y_a = 0; mri_out->z_a = 1; mri_out->x_s = 0; mri_out->y_s =-1; mri_out->z_s = 0; /* In this case, the RAS itself is not fully determined, i.e., c_ras. * It's quite arbitrary, different values just change the final * sitting of the volume inside the RAS system. */ /* NO! The C_RAS has to be set correctly, depending which target * volume the previous Vox_to_Vox transformation assumes! * When a registration is involved, the target volume is either * the src of LTA (direct) or the dst (inverse transform). When * just change format, the target volume is the input itself!! */ if (transform_flag) { if (invert_flag) { mri_out->c_r = lta->xforms[0].src.c_r; mri_out->c_a = lta->xforms[0].src.c_a; mri_out->c_s = lta->xforms[0].src.c_s; } else { mri_out->c_r = lta->xforms[0].dst.c_r; mri_out->c_a = lta->xforms[0].dst.c_a; mri_out->c_s = lta->xforms[0].dst.c_s; } } else { mri_out->c_r = mri_in->c_r; mri_out->c_a = mri_in->c_a; mri_out->c_s = mri_in->c_s; } mri_out->ras_good_flag=1; /* What does this flag mean ? */ /* since output is just transformed input */ MRIcopyPulseParameters(mri_in, mri_out) ; } /* Compute the final input-to-output VOX_to_VOX transformation matrix */ r_to_i_out = extract_r_to_i(mri_out); m_tmp = MatrixMultiply(r_to_i_out, i_to_r_reg, NULL); V_to_V = MatrixMultiply(m_tmp, V_to_V, V_to_V); MatrixFree(&m_tmp); printf("InterpMethod = %d\n", InterpMethod); /* Modify the MyMRIlinearTr... if I want to implement my cubic-B-spline * interpolation method. Otherwise, unnecessary */ /* mri_out = MyMRIlinearTransformInterp(mri_in, mri_out, V_to_V, InterpMethod); */ if (InterpMethod == SAMPLE_BSPLINE) mri_out = MRIlinearTransformInterpBSpline(mri_in, mri_out, V_to_V, SplineDegree); else mri_out = MRIlinearTransformInterp(mri_in, mri_out, V_to_V, InterpMethod); maxV = -10000.0; minV = 10000.0; for (z=0; z < mri_out->depth; z++) for (y=0; y< mri_out->height; y++) for (x=0; x < mri_out->width; x++) { if (MRIFvox(mri_out, x, y, z) > maxV ) maxV = MRIFvox(mri_out, x, y,z) ; if (MRIFvox(mri_out, x, y, z) < minV ) minV = MRIFvox(mri_out, x, y,z) ; } if (autoscale) { noscale = 1; /* compute histogram of output volume */ HISTOGRAM *h, *hsmooth ; float fmin, fmax, val, peak, smooth_peak; int i, nbins, bin; fmin = minV; fmax = maxV; if (fmin < 0) fmin = 0; nbins = 256 ; h = HISTOalloc(nbins) ; hsmooth = HISTOcopy(h, NULL) ; HISTOclear(h, h) ; h->bin_size = (fmax-fmin)/255.0 ; for (i = 0 ; i < nbins ; i++) h->bins[i] = (i+1)*h->bin_size ; for (z=0; z < mri_out->depth; z++) for (y=0; y< mri_out->height; y++) for (x=0; x < mri_out->width; x++) { val = MRIFvox(mri_out, x, y, z); if (val <= 0) continue; bin = nint((val - fmin)/h->bin_size); if (bin >= h->nbins) bin = h->nbins-1; else if (bin < 0) bin = 0; h->counts[bin] += 1.0; } HISTOfillHoles(h) ; HISTOsmooth(h, hsmooth, 5) ; peak = hsmooth->bins[HISTOfindHighestPeakInRegion(h, 1, h->nbins)] ; // smooth_peak = // hsmooth->bins[HISTOfindHighestPeakInRegion(hsmooth, 1, hsmooth->nbins)] ; smooth_peak = hsmooth->bins[HISTOfindLastPeak(hsmooth, 5, 0.8)] ; /* bin = nint((smooth_peak - fmin)/hsmooth->bin_size) ; printf("Highest peak has count = %d\n", (int)hsmooth->counts[bin]); bin = nint((420 - fmin)/hsmooth->bin_size) ; printf("bin at 420 has count = %d\n", (int)hsmooth->counts[bin]); */ scale = 110.0/smooth_peak; printf("peak of output volume is %g, smooth-peak is %g, multiply by %g to scale it to 110\n", peak, smooth_peak, scale); for (z=0; z < mri_out->depth; z++) for (y=0; y< mri_out->height; y++) for (x=0; x < mri_out->width; x++) { val = MRIFvox(mri_out, x, y, z); MRIFvox(mri_out, x, y, z) = val*scale; } } printf("Output volume (before type-conversion) has max = %g, min =%g\n", maxV, minV); /* Finally change type to desired */ if (mri_out->type != out_type) { printf("Change output volume to type %d\n", out_type); /* I need to modify the MIRchangeType function to make sure * it does roundoff instead of simple truncation! */ /* Note if the last flag is set to 1, then it won't do scaling and small float numbers will become zero after convert to BYTE */ if (out_type == 0 && noscale == 1) { //convert data to UCHAR mri_tmp = MRIalloc(mri_out->width, mri_out->height, mri_out->depth, out_type) ; MRIcopyHeader(mri_out, mri_tmp); for (z=0; z < mri_out->depth; z++) for (y=0; y< mri_out->height; y++) for (x=0; x < mri_out->width; x++) { value = floor(MRIgetVoxVal(mri_out, x, y, z, 0) + 0.5); if (value < 0 ) value = 0; if (value > 255) value = 255; MRIvox(mri_tmp,x,y,z) = (unsigned char)value; } } else mri_tmp = MRIchangeType(mri_out, out_type, thred_low, thred_high, noscale); MRIfree(&mri_out); mri_out = mri_tmp; //swap } MRIwrite(mri_out, out_vol) ; MRIfree(&mri_in); MRIfree(&mri_out); if (lta_src) MRIfree(<a_src); if (lta_dst) MRIfree(<a_dst); MatrixFree(&V_to_V); if (!r_to_i_out) MatrixFree(&r_to_i_out); if (!i_to_r_reg) MatrixFree(&i_to_r_reg); return(0) ; /* for ansi */ }
int main(int argc, char* argv[]) { IoParams params; try { params.parse(argc,argv); } catch (const std::exception& excp) { std::cerr << " Exception while parsing cmd-line\n" << excp.what() << std::endl; exit(1); } catch (...) { std::cerr << " unhandled exception caught while parsing cmd line\n"; exit(1); } boost::shared_ptr<gmp::VolumeMorph> pmorph(new gmp::VolumeMorph); if ( !params.strTemplate.empty() ) { MRI* mri = MRIread( const_cast<char*>(params.strTemplate.c_str()) ); if (!mri) std::cerr << " Failed to open template mri " << params.strTemplate << std::endl; else pmorph->set_volGeom_fixed(mri); MRIfree(&mri); } if ( !params.strSubject.empty() ) { MRI* mri = MRIread( const_cast<char*>(params.strSubject.c_str()) ); if (!mri) std::cerr << " Failed to open subject mri " << params.strSubject << std::endl; else pmorph->set_volGeom_moving(mri); MRIfree(&mri); } IoParams::MorphContainerType::iterator it; for ( it = params.items.begin(); it != params.items.end(); ++it ) { if ( it->type == "affine" ) { boost::shared_ptr<gmp::AffineTransform3d> paffine( new gmp::AffineTransform3d); float* pf = read_transform( it->file.c_str() ); if ( !pf ) { std::cerr << " failed to read transform\n"; exit(1); } paffine->set_pars( pf); pmorph->m_transforms.push_back( paffine ); } else if ( it->type == "volume" ) { boost::shared_ptr<gmp::DeltaTransform3d> pvol( new gmp::DeltaTransform3d); MRI* field = MRIread ( const_cast<char*>( it->file.c_str() ) ); if ( !field ) { std::cerr << " failed to read field " << std::endl; exit(1); } pvol->set_field(field); pmorph->m_transforms.push_back( pvol ); } else if ( it->type == "gcam" ) { boost::shared_ptr<gmp::DeltaTransform3d> pvol( new gmp::DeltaTransform3d); GCA_MORPH* gcam = GCAMread( const_cast<char*>( it->file.c_str() ) ); if ( !gcam ) { std::cerr << " failed to read GCAM " << std::endl; exit(1); } // create bogus MRI to hold the geometry MRI* mri_template = MRIread( const_cast<char*> ( params.strTemplate.c_str() ) ); MRI* mriBuf = MRIalloc( gcam->image.width, gcam->image.height, gcam->image.depth, MRI_UCHAR); useVolGeomToMRI( &gcam->image, mriBuf ); GCAMrasToVox(gcam, mriBuf ); MRIfree( &mriBuf ); std::cout << " atlas geometry = " << gcam->atlas.width << " , " << gcam->atlas.height << " , " << gcam->atlas.depth << std::endl << " image geometry = " << gcam->image.width << " , " << gcam->image.height << " , " << gcam->image.depth << std::endl; MRI* mri = MRIallocSequence( mri_template->width, mri_template->height, mri_template->depth, MRI_FLOAT, 3); MRIcopyHeader(mri_template, mri); g_vDbgCoords = params.vDbgCoords; try { //MRI* mask = CopyGcamToDeltaField(gcam, mri); pvol->set_field(mri); //pvol->set_mask(mask); pmorph->m_transforms.push_back( pvol ); } catch (const std::string& e) { std::cerr << " Exception caught while processing GCAM node\n" << e << std::endl; exit(1); } MRIfree(&mri_template); } else if ( it->type == "morph" ) { boost::shared_ptr<gmp::VolumeMorph> tmpMorph(new gmp::VolumeMorph); try { tmpMorph->load( it->file.c_str() ); } catch (const char* msg) { std::cerr << " Exception caught while loading morph in file " << it->file << std::endl; exit(1); } for ( gmp::VolumeMorph::TransformContainerType::iterator transformIter = tmpMorph->m_transforms.begin(); transformIter != tmpMorph->m_transforms.end(); ++transformIter ) pmorph->m_transforms.push_back( *transformIter ); } else if ( it->type == "mesh" ) { boost::shared_ptr<gmp::FemTransform3d> pfem(new gmp::FemTransform3d); boost::shared_ptr<CMesh3d> pmesh(new CMesh3d); pmesh->load( it->file.c_str() ); pfem->m_sharedMesh = pmesh; pmorph->m_transforms.push_back(pfem); } else { std::cerr << " unhandled transform type " << it->type << std::endl; } } // next it // finally write morph file try { pmorph->save( params.strOut.c_str() ); } catch (const char* msg) { std::cerr << " Exception caught while saving morph\n" << msg << std::endl; exit(1); } return 0; }
// 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; }
// the following only cares about finding the max segments // ignoring the rest MRI_SEGMENTATION * MRImaxsegment(MRI *mri, float low_val, float hi_val) { MRI_SEGMENTATION *mriseg ; MRI_SEGMENT *mseg, *mseg2 ; int x, y, z, width, height, depth, xi, yi, zi, xk, yk, zk, val, border_labels[NBR_VOX], nlabels, label, nvox ; MRI *mri_labeled ; float voxel_size ; int max; int count =0; int totcount = 0; int mem =0; int maxarea=0; voxel_size = mri->xsize * mri->ysize * mri->zsize ; width = mri->width ; height = mri->height ; depth = mri->depth ; mriseg = MRIsegmentAlloc(MAX_SEGMENTS, MAX_VOXELS) ; mriseg->mri = mri ; for (z =0; z < depth; z++) for (y=0; y < height; y++) for (x=0; x < width; x++) { val = MRIgetVoxVal(mri, x, y, z, 0) ; if (val >= low_val && val <= hi_val) totcount++; } /* mri_labeled will contain the label number for each voxel (if it has been assigned to a segment). */ mri_labeled = MRIalloc(width, height, depth, MRI_SHORT) ; for (z = 0 ; z < depth ; z++) { for (y = 0 ; y < height ; y++) { for (x = 0 ; x < width ; x++) MRISvox(mri_labeled, x, y, z) = -1 ; } } for (z = 0 ; z < depth ; z++) { for (y = 0 ; y < height ; y++) { for (x = 0 ; x < width ; x++) { val = MRIgetVoxVal(mri, x, y, z, 0) ; // if within the range if (val >= low_val && val <= hi_val) { count++; // initializer for border_labels memset(border_labels, -1, NBR_VOX*sizeof(int)) ; for (nvox = 0, zk = -1 ; zk <= 1 ; zk++) { zi = z+zk ; if ((zi < 0) || (zi >= depth)) continue ; for (yk = -1 ; yk <= 1 ; yk++) { yi = y+yk ; if ((yi < 0) || (yi >= height)) continue ; // increment nvox count here for (xk = -1 ; xk <= 1 ; xk++, nvox++) { #if 1 if ((abs(xk) + abs(yk) + abs(zk)) > 1) continue ; /* only allow 4 (6 in 3-d) connectivity */ #endif xi = x+xk ; if ((xi < 0) || (xi >= width)) continue ; // get the neighbor label label = MRISvox(mri_labeled, xi, yi, zi) ; if (label >= 0) border_labels[nvox] = label ; } } } // count nonzero labels in nbrs for (nlabels = nvox = 0 ; nvox < NBR_VOX ; nvox++) { label = border_labels[nvox] ; if ((label >= 0) && (!mriseg->segments[label].found)) { mriseg->segments[label].found = 1 ; nlabels++ ; } } // reset found for (nvox = 0 ; nvox < NBR_VOX ; nvox++) { label = border_labels[nvox] ; if (label >= 0) mriseg->segments[label].found = 0 ; /* for next time */ } // label = 0 ; // create labels for those points which are not connected switch (nlabels) { case 0: /* allocate a new segment */ if (mriseg->nsegments >= mriseg->max_segments) { mem = getMemoryUsed(); // only Linux gives the correct value // (the rest returns -1 // mem > 800*1024) // 800 Mbytes virtual memory usage if (mriseg->max_segments > MAX_SEGMENTS*VOX_INCREASE) { if (mem > 0) // only Linux can do this fprintf(stdout, "\n " "heap usage = %d Kbytes.", mem); // find the region with the largest area maxarea = MRImaxSegmentArea(mriseg); fprintf (stdout, "\n current max segment has " "%d voxels", maxarea); // the second max area can have area up to // (current - maxarea) + (total - maxarea) // = total + current - 2*maxarea // if this value is less than maxarea, // then the second candidate never // becomes the top. Thus I can remove // small segments // if (count+totcount < 3*maxarea) // // For those which has < 100*N % of maxarea, // the possible max count is // = maxarea*N + remaining voxels // = maxarea*N + (total - count) // Thus I can remove those when // maxarea*N + (total-count) < maxarea // or total - count < maxarea*(1 - N) // // Note that if you remove too much, // then possbile merging voxels will be lost // if (totcount - count < maxarea*0.99) { int i,j,k; fprintf(stdout, "\n removing " "small segments (less than 1 " "percent of maxarea)."); MRIremoveSmallSegments(mriseg, maxarea*0.01); // this does compactify // go through mri_labeled to // remove this label value s for (k=0; k < mri_labeled->depth; ++k) for (j=0; j < mri_labeled->height; ++j) for (i=0; i < mri_labeled->width; ++i) { if (MRISvox(mri_labeled, i,j,k) >= mriseg->nsegments) MRISvox(mri_labeled, i,j,k) = -1; } } } } label = mriSegmentNew(mriseg) ; // returns this added segment position mseg = &mriseg->segments[label] ; if (DIAG_VERBOSE_ON && 0) fprintf(stdout, "allocating new label %d (%d total)\n", label, mriseg->nsegments) ; break ; case 1: /* assign this voxel to the one that it borders */ for (nvox = 0 ; nvox < NBR_VOX ; nvox++) if (border_labels[nvox] >= 0) { label = border_labels[nvox] ; break ; } // points to the same label position mseg = &mriseg->segments[label] ; break ; default: /* merge segments and assign to lowest number */ mseg = NULL ; for (nvox = 0 ; nvox < NBR_VOX ; nvox++) { if (border_labels[nvox] >= 0) { // the 1st encountered label case if (!mseg) { // set the first index position label = border_labels[nvox] ; mseg = &mriseg->segments[label] ; mseg->found = 1 ; } // the rest else { mseg2 = &mriseg->segments[border_labels[nvox]] ; if (mseg2->found == 0) { mseg2->found = 1 ; /* prevent merging more than once */ // merge to the label position if (mriSegmentMerge(mriseg, label, border_labels[nvox], mri_labeled) != NO_ERROR) { // nsegments decreased by one MRIsegmentFree(&mriseg) ; return(NULL) ; } } } } } // reset found for (nvox = 0 ; nvox < NBR_VOX ; nvox++) if (border_labels[nvox] >= 0) mriseg->segments[border_labels[nvox]].found = 0 ; break ; } /* add it to the existing list */ if (mseg->nvoxels >= mseg->max_voxels) { // this max could be the same as mseg->max_voxels // this is taken care in mriSegmentReallocateVoxels() max = nint(mseg->max_voxels*VOX_INCREASE); // if (mriSegmentReallocateVoxels(mriseg, label, // nint(mseg->max_voxels*VOX_INCREASE)) // != NO_ERROR) if (mriSegmentReallocateVoxels(mriseg, label, max) != NO_ERROR) { MRIsegmentFree(&mriseg) ; return(NULL) ; } } mseg->voxels[mseg->nvoxels].x = x ; mseg->voxels[mseg->nvoxels].y = y ; mseg->voxels[mseg->nvoxels].z = z ; mseg->nvoxels++ ; mseg->area += voxel_size ; // voxel_size = volume #if 0 // this is for only 1mm voxel case if (mseg->nvoxels != (int)mseg->area) DiagBreak() ; #endif MRISvox(mri_labeled, x, y, z) = label ; } } } } mem = getMemoryUsed(); if (mem > 0) // only Linux can do this fprintf(stdout, "\n heap usage = %d Kbytes.", mem); maxarea = MRImaxSegmentArea(mriseg); fprintf(stdout, "\n removing small segments (less " "than 1 percent of maxarea)."); MRIremoveSmallSegments(mriseg, 0.01*maxarea); // MRIcompactSegments(mriseg) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON && 0) MRIwrite(mri_labeled, "labeled.mgh") ; MRIfree(&mri_labeled) ; mriComputeSegmentStatistics(mriseg) ; return(mriseg) ; }
MRI_SEGMENTATION * MRIsegment(MRI *mri, float low_val, float hi_val) { MRI_SEGMENTATION *mriseg ; MRI_SEGMENT *mseg, *mseg2 ; int x, y, z, width, height, depth, xi, yi, zi, xk, yk, zk, border_labels[NBR_VOX], nlabels, label, nvox ; MRI *mri_labeled ; float voxel_size, val ; int max; int count =0; voxel_size = mri->xsize * mri->ysize * mri->zsize ; width = mri->width ; height = mri->height ; depth = mri->depth ; mriseg = MRIsegmentAlloc(MAX_SEGMENTS, MAX_VOXELS) ; mriseg->mri = mri ; /* mri_labeled will contain the label number for each voxel (if it has been assigned to a segment). */ mri_labeled = MRIalloc(width, height, depth, MRI_SHORT) ; for (z = 0 ; z < depth ; z++) { for (y = 0 ; y < height ; y++) { for (x = 0 ; x < width ; x++) MRISvox(mri_labeled, x, y, z) = -1 ; } } for (z = 0 ; z < depth ; z++) { for (y = 0 ; y < height ; y++) { for (x = 0 ; x < width ; x++) { val = MRIgetVoxVal(mri, x, y, z, 0) ; // if within the range if (val >= low_val && val <= hi_val) { count++; // initializer for border_labels memset(border_labels, -1, NBR_VOX*sizeof(int)) ; for (nvox = 0, zk = -1 ; zk <= 1 ; zk++) { zi = z+zk ; if ((zi < 0) || (zi >= depth)) continue ; for (yk = -1 ; yk <= 1 ; yk++) { yi = y+yk ; if ((yi < 0) || (yi >= height)) continue ; // increment nvox count here for (xk = -1 ; xk <= 1 ; xk++, nvox++) { #if 1 if ((abs(xk) + abs(yk) + abs(zk)) > 1) continue ; /* only allow 4 (6 in 3-d) connectivity */ #endif xi = x+xk ; if ((xi < 0) || (xi >= width)) continue ; // get the neighbor label label = MRISvox(mri_labeled, xi, yi, zi) ; if (label >= 0) border_labels[nvox] = label ; } } } // count nonzero labels in nbrs for (nlabels = nvox = 0 ; nvox < NBR_VOX ; nvox++) { label = border_labels[nvox] ; if ((label >= 0) && (!mriseg->segments[label].found)) { mriseg->segments[label].found = 1 ; nlabels++ ; } } // reset found for (nvox = 0 ; nvox < NBR_VOX ; nvox++) { label = border_labels[nvox] ; if (label >= 0) mriseg->segments[label].found = 0 ; /* for next time */ } // label = 0 ; // create labels for those points which are not connected switch (nlabels) { case 0: /* allocate a new segment */ label = mriSegmentNew(mriseg) ; // returns this added segment position mseg = &mriseg->segments[label] ; if (DIAG_VERBOSE_ON && 0) fprintf(stdout, "allocating new label %d (%d total)\n", label, mriseg->nsegments) ; break ; case 1: /* assign this voxel to the one that it borders */ for (nvox = 0 ; nvox < NBR_VOX ; nvox++) if (border_labels[nvox] >= 0) { label = border_labels[nvox] ; break ; } // points to the same label position mseg = &mriseg->segments[label] ; break ; default: /* merge segments and assign to lowest number */ mseg = NULL ; for (nvox = 0 ; nvox < NBR_VOX ; nvox++) { if (border_labels[nvox] >= 0) { // the 1st encountered label case if (!mseg) { // set the first index position label = border_labels[nvox] ; mseg = &mriseg->segments[label] ; mseg->found = 1 ; } // the rest else { mseg2 = &mriseg->segments[border_labels[nvox]] ; if (mseg2->found == 0) { mseg2->found = 1 ; /* prevent merging more than once */ // merge to the label position if (mriSegmentMerge(mriseg, label, border_labels[nvox], mri_labeled) != NO_ERROR) { // nsegments decreased by one MRIsegmentFree(&mriseg) ; return(NULL) ; } } } } } // reset found for (nvox = 0 ; nvox < NBR_VOX ; nvox++) if (border_labels[nvox] >= 0) mriseg->segments[border_labels[nvox]].found = 0 ; break ; } /* add it to the existing list */ if (mseg->nvoxels >= mseg->max_voxels) { // this max could be the same as mseg->max_voxels // this is taken care in mriSegmentReallocateVoxels() max = nint(mseg->max_voxels*VOX_INCREASE); // if (mriSegmentReallocateVoxels(mriseg, label, // nint(mseg->max_voxels*VOX_INCREASE)) // != NO_ERROR) if (mriSegmentReallocateVoxels(mriseg, label, max) != NO_ERROR) { MRIsegmentFree(&mriseg) ; return(NULL) ; } } mseg->voxels[mseg->nvoxels].x = x ; mseg->voxels[mseg->nvoxels].y = y ; mseg->voxels[mseg->nvoxels].z = z ; mseg->nvoxels++ ; mseg->area += voxel_size ; // voxel_size = volume #if 0 // this is for only 1mm voxel case if (mseg->nvoxels != (int)mseg->area) DiagBreak() ; #endif MRISvox(mri_labeled, x, y, z) = label ; } } } } MRIcompactSegments(mriseg) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON && 0) MRIwrite(mri_labeled, "labeled.mgh") ; MRIfree(&mri_labeled) ; mriComputeSegmentStatistics(mriseg) ; return(mriseg) ; }
int main(int argc, char *argv[]) { char **av, *in_fname; int ac, nargs, i, j, x, y, z, width, height, depth; MRI *mri_flash[MAX_IMAGES], *mri_label, *mri_mask; int index; int msec, minutes, seconds, nvolumes, nvolumes_total ; struct timeb start ; float max_val, min_val, value; float *LDAweight = NULL; float **LDAmeans = NULL; /* Centroid for each considered class */ float *classSize =NULL; /* relative size of each class */ MATRIX **SWs; /* Within class scatter-matrix for each considered class */ MATRIX *AdjMatrix; /* Adjacency matrix of all classes */ FILE *fp; int num_classes; double cnr; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mri_ms_compute_CNR.c,v 1.10 2011/03/02 00:04:55 nicks 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 < 2) usage_exit(1) ; printf("command line parsing finished\n"); if (label_fname == NULL) { printf("Use -label option to specify file for segmentation \n"); usage_exit(0); } if (have_weight == 1 && weight_fname == NULL) { printf("Use -weight option to specify file for input LDA weights \n") ; usage_exit(0); } if (have_weight == 1 && synth_fname == NULL) { printf("Use -synth option to specify file for output synthesized volume \n") ; usage_exit(0); } if (ldaflag) { MINLABEL = MIN(class1, class2); MAXLABEL = MAX(class1, class2); } num_classes = MAXLABEL - MINLABEL + 1; printf("Total of %d classes considered in LDA training\n", num_classes); if (num_classes <= 1) { printf("Need to specify at least two classes to evaluate CNR\n"); usage_exit(0); } ////////////////////////////////////////////////////////////////////////////////// /*** Read in the input multi-echo volumes ***/ nvolumes = 0 ; for (i = 1 ; i < argc; i++) { in_fname = argv[i] ; printf("reading %s...\n", in_fname) ; mri_flash[nvolumes] = MRIread(in_fname) ; if (mri_flash[nvolumes] == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read volume %s", Progname, in_fname) ; /* conform will convert all data to UCHAR, which will reduce data resolution*/ printf("%s read in. \n", in_fname) ; if (conform) { MRI *mri_tmp ; printf("embedding and interpolating volume\n") ; mri_tmp = MRIconform(mri_flash[nvolumes]) ; mri_flash[nvolumes] = mri_tmp ; } /* Change all volumes to float type for convenience */ if (mri_flash[nvolumes]->type != MRI_FLOAT) { printf("Volume %d type is %d\n", nvolumes+1, mri_flash[nvolumes]->type); MRI *mri_tmp; printf("Change data to float type \n"); mri_tmp = MRIchangeType(mri_flash[nvolumes], MRI_FLOAT, 0, 1.0, 1); MRIfree(&mri_flash[nvolumes]); mri_flash[nvolumes] = mri_tmp; //swap } nvolumes++ ; } printf("All data read in\n"); /////////////////////////////////////////////////////////////////////////// nvolumes_total = nvolumes ; /* all volumes read in */ for (i = 0 ; i < nvolumes ; i++) { for (j = i+1 ; j < nvolumes ; j++) { if ((mri_flash[i]->width != mri_flash[j]->width) || (mri_flash[i]->height != mri_flash[j]->height) || (mri_flash[i]->depth != mri_flash[j]->depth)) ErrorExit(ERROR_BADPARM, "%s:\nvolumes %d (type %d) and %d (type %d) don't match (%d x %d x %d) vs (%d x %d x %d)\n", Progname, i, mri_flash[i]->type, j, mri_flash[j]->type, mri_flash[i]->width, mri_flash[i]->height, mri_flash[i]->depth, mri_flash[j]->width, mri_flash[j]->height, mri_flash[j]->depth) ; } } width = mri_flash[0]->width; height = mri_flash[0]->height; depth = mri_flash[0]->depth; if (label_fname != NULL) { mri_label = MRIread(label_fname); if (!mri_label) ErrorExit(ERROR_NOFILE, "%s: could not read input volume %s\n", Progname, label_fname); if ((mri_label->width != mri_flash[0]->width) || (mri_label->height != mri_flash[0]->height) || (mri_label->depth != mri_flash[0]->depth)) ErrorExit(ERROR_BADPARM, "%s: label volume size doesn't match data volumes\n", Progname); /* if(mri_label->type != MRI_UCHAR) ErrorExit(ERROR_BADPARM, "%s: label volume is not UCHAR type \n", Progname); */ } if (mask_fname != NULL) { mri_mask = MRIread(mask_fname); if (!mri_mask) ErrorExit(ERROR_NOFILE, "%s: could not read input volume %s\n", Progname, mask_fname); if ((mri_mask->width != mri_flash[0]->width) || (mri_mask->height != mri_flash[0]->height) || (mri_mask->depth != mri_flash[0]->depth)) ErrorExit(ERROR_BADPARM, "%s: mask volume size doesn't macth data volumes\n", Progname); if (mri_mask->type != MRI_UCHAR) ErrorExit(ERROR_BADPARM, "%s: mask volume is not UCHAR type \n", Progname); } else { mri_mask = MRIalloc(mri_flash[0]->width, mri_flash[0]->height, mri_flash[0]->depth, MRI_UCHAR); MRIcopyHeader(mri_flash[0], mri_mask); /* Simply set mask to be 1 everywhere */ for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { MRIvox(mri_mask, x, y,z) = 1; } } if (debug_flag && window_flag) { /* Limit LDA to a local window */ printf("Local window size = %d\n", window_size); window_size /= 2; for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if (MRIvox(mri_mask, x, y,z) == 0) continue; if (z < (Gz - window_size) || z >(Gz + window_size) || y <(Gy - window_size) || y > (Gy + window_size) || x < (Gx - window_size) || x > (Gx + window_size)) MRIvox(mri_mask, x, y,z) = 0; } } LDAweight = (float *)calloc(nvolumes_total, sizeof(float)); /* Allocate memory */ LDAmeans = (float **)malloc(num_classes*sizeof(float *)); SWs = (MATRIX **)malloc(num_classes*sizeof(MATRIX *)); classSize = (float *)malloc(num_classes*sizeof(float)); for (i=0; i< num_classes; i++) { LDAmeans[i] = (float *)malloc(nvolumes_total*sizeof(float)); SWs[i] = (MATRIX *)MatrixAlloc(nvolumes_total, nvolumes_total, MATRIX_REAL); if (SWs[i] == NULL || LDAmeans[i] == NULL) ErrorExit(ERROR_BADPARM, "%s: unable to allocate required memory \n", Progname); } if (ldaflag) { AdjMatrix = (MATRIX *)MatrixAlloc(num_classes, num_classes, MATRIX_REAL); /* The diagnoal entries of AdjMatrix is set to zero initially */ for (i=1; i <= num_classes;i++) for (j=i; j <= num_classes; j++) { AdjMatrix->rptr[i][j] = 0.0; AdjMatrix->rptr[j][i] = 0.0; } AdjMatrix->rptr[class1-MINLABEL +1][class2-MINLABEL+1] = 1.0; AdjMatrix->rptr[class1-MINLABEL +1][class1-MINLABEL+1] = 1.0; AdjMatrix->rptr[class2-MINLABEL +1][class2-MINLABEL+1] = 1.0; AdjMatrix->rptr[class2-MINLABEL +1][class1-MINLABEL+1] = 1.0; } else if (MINLABEL <=2 && MAXLABEL >= 76) { printf("Manually set adjacent matrix \n"); AdjMatrix = (MATRIX *)MatrixAlloc(num_classes, num_classes, MATRIX_REAL); /* The diagnoal entries of AdjMatrix is set to zero initially */ for (i=1; i <= num_classes;i++) for (j=i; j <= num_classes; j++) { AdjMatrix->rptr[i][j] = 0.0; AdjMatrix->rptr[j][i] = 0.0; } for (index = 0; index < CNR_pairs; index++) { i = ilist[index] - MINLABEL; j = jlist[index] - MINLABEL; AdjMatrix->rptr[i+1][j+1] = 1.0; AdjMatrix->rptr[j+1][i+1] = 1.0; } /* left-hemisphere */ /* AdjMatrix->rptr[2+1-MINLABEL][17+1-MINLABEL] = 1.0; AdjMatrix->rptr[17+1-MINLABEL][18+1-MINLABEL] = 1.0; AdjMatrix->rptr[3+1-MINLABEL][17+1-MINLABEL] = 1.0; AdjMatrix->rptr[5+1-MINLABEL][17+1-MINLABEL] = 1.0; AdjMatrix->rptr[4+1-MINLABEL][17+1-MINLABEL] = 1.0; AdjMatrix->rptr[18+1-MINLABEL][2+1-MINLABEL] = 1.0; AdjMatrix->rptr[18+1-MINLABEL][3+1-MINLABEL] = 1.0; AdjMatrix->rptr[18+1-MINLABEL][5+1-MINLABEL] = 1.0; AdjMatrix->rptr[18+1-MINLABEL][4+1-MINLABEL] = 1.0; AdjMatrix->rptr[10+1-MINLABEL][11+1-MINLABEL] = 1.0; AdjMatrix->rptr[10+1-MINLABEL][4+1-MINLABEL] = 1.0; AdjMatrix->rptr[10+1-MINLABEL][12+1-MINLABEL] = 1.0; AdjMatrix->rptr[10+1-MINLABEL][2+1-MINLABEL] = 1.0; AdjMatrix->rptr[2+1-MINLABEL][3+1-MINLABEL] = 1.0; */ /* right-hemisphere */ /* AdjMatrix->rptr[53+1-MINLABEL][41+1-MINLABEL] = 1.0; AdjMatrix->rptr[53+1-MINLABEL][54+1-MINLABEL] = 1.0; AdjMatrix->rptr[53+1-MINLABEL][42+1-MINLABEL] = 1.0; AdjMatrix->rptr[53+1-MINLABEL][44+1-MINLABEL] = 1.0; AdjMatrix->rptr[53+1-MINLABEL][43+1-MINLABEL] = 1.0; AdjMatrix->rptr[54+1-MINLABEL][41+1-MINLABEL] = 1.0; AdjMatrix->rptr[54+1-MINLABEL][42+1-MINLABEL] = 1.0; AdjMatrix->rptr[54+1-MINLABEL][44+1-MINLABEL] = 1.0; AdjMatrix->rptr[54+1-MINLABEL][43+1-MINLABEL] = 1.0; AdjMatrix->rptr[49+1-MINLABEL][50+1-MINLABEL] = 1.0; AdjMatrix->rptr[49+1-MINLABEL][43+1-MINLABEL] = 1.0; AdjMatrix->rptr[49+1-MINLABEL][51+1-MINLABEL] = 1.0; AdjMatrix->rptr[49+1-MINLABEL][41+1-MINLABEL] = 1.0; AdjMatrix->rptr[41+1-MINLABEL][42+1-MINLABEL] = 1.0; for(i=1; i < num_classes;i++) for(j=i+1; j <= num_classes; j++){ if(AdjMatrix->rptr[i][j] > 0.5) AdjMatrix->rptr[j][i] = AdjMatrix->rptr[i][j]; else AdjMatrix->rptr[i][j] = AdjMatrix->rptr[j][i]; } */ /* AdjMatrix->rptr[2+1-MINLABEL][3+1-MINLABEL] = 1.0; AdjMatrix->rptr[2+1-MINLABEL][10+1-MINLABEL] = 1.0; AdjMatrix->rptr[2+1-MINLABEL][11+1-MINLABEL] = 1.0; AdjMatrix->rptr[2+1-MINLABEL][12+1-MINLABEL] = 1.0; AdjMatrix->rptr[2+1-MINLABEL][13+1-MINLABEL] = 1.0; AdjMatrix->rptr[2+1-MINLABEL][17+1-MINLABEL] = 1.0; AdjMatrix->rptr[2+1-MINLABEL][18+1-MINLABEL] = 1.0; AdjMatrix->rptr[3+1-MINLABEL][12+1-MINLABEL] = 1.0; AdjMatrix->rptr[3+1-MINLABEL][17+1-MINLABEL] = 1.0; AdjMatrix->rptr[3+1-MINLABEL][18+1-MINLABEL] = 1.0; AdjMatrix->rptr[4+1-MINLABEL][10+1-MINLABEL] = 1.0; AdjMatrix->rptr[4+1-MINLABEL][11+1-MINLABEL] = 1.0; AdjMatrix->rptr[10+1-MINLABEL][11+1-MINLABEL] = 1.0; AdjMatrix->rptr[10+1-MINLABEL][13+1-MINLABEL] = 1.0; AdjMatrix->rptr[12+1-MINLABEL][13+1-MINLABEL] = 1.0; AdjMatrix->rptr[12+1-MINLABEL][26+1-MINLABEL] = 1.0; AdjMatrix->rptr[17+1-MINLABEL][18+1-MINLABEL] = 1.0; */ /* right-hemisphere */ /* AdjMatrix->rptr[41+1-MINLABEL][42+1-MINLABEL] = 1.0; AdjMatrix->rptr[41+1-MINLABEL][49+1-MINLABEL] = 1.0; AdjMatrix->rptr[41+1-MINLABEL][50+1-MINLABEL] = 1.0; AdjMatrix->rptr[41+1-MINLABEL][51+1-MINLABEL] = 1.0; AdjMatrix->rptr[41+1-MINLABEL][52+1-MINLABEL] = 1.0; AdjMatrix->rptr[41+1-MINLABEL][53+1-MINLABEL] = 1.0; AdjMatrix->rptr[41+1-MINLABEL][54+1-MINLABEL] = 1.0; AdjMatrix->rptr[42+1-MINLABEL][51+1-MINLABEL] = 1.0; AdjMatrix->rptr[42+1-MINLABEL][53+1-MINLABEL] = 1.0; AdjMatrix->rptr[42+1-MINLABEL][54+1-MINLABEL] = 1.0; AdjMatrix->rptr[43+1-MINLABEL][49+1-MINLABEL] = 1.0; AdjMatrix->rptr[43+1-MINLABEL][50+1-MINLABEL] = 1.0; AdjMatrix->rptr[49+1-MINLABEL][50+1-MINLABEL] = 1.0; AdjMatrix->rptr[49+1-MINLABEL][52+1-MINLABEL] = 1.0; AdjMatrix->rptr[51+1-MINLABEL][52+1-MINLABEL] = 1.0; AdjMatrix->rptr[51+1-MINLABEL][58+1-MINLABEL] = 1.0; AdjMatrix->rptr[53+1-MINLABEL][54+1-MINLABEL] = 1.0; */ } else AdjMatrix = ComputeAdjMatrix(mri_label, mri_mask, MINLABEL, MAXLABEL); /* AdjMatrix may need manual adjusted to avoid meaningless comparisons * such as computing CNR between left WM and right WM */ for (i=1; i <= num_classes;i++) for (j=1; j <= num_classes; j++) { if (j==i) continue; /* the diagonal term will indicate whether the class is useful or not */ AdjMatrix->rptr[i][i] += AdjMatrix->rptr[i][j] + AdjMatrix->rptr[j][i]; } printf("Compute individual class statistics\n"); /* Compute class means and covariance matrix */ /* Note that here SWs will be covaraince matrix, not scatter matrix */ for (i=0; i < num_classes; i++) { if (AdjMatrix->rptr[i+1][i+1] < 0.5) continue; computeClassStats(LDAmeans[i], SWs[i], &classSize[i], mri_flash, mri_label, mri_mask, nvolumes_total, MINLABEL + i); } printf("class statistics computed \n"); if (fname != NULL) fp = fopen(fname, "w"); else fp = 0; printf("compute pair-wise CNR/Mahalanobis distances \n"); if (ldaflag) { for (i=0; i <num_classes-1;i++) for (j=i+1; j < num_classes; j++) { if (AdjMatrix->rptr[i+1][j+1] < 0.5) continue; cnr = computePairCNR(LDAmeans[i], LDAmeans[j], SWs[i], SWs[j], classSize[i], classSize[j], nvolumes_total, LDAweight, 1); if (fp) fprintf(fp, "%9.4f ", (float)cnr); printf("CNR of class %d and class %d is %g\n", i+MINLABEL, j+MINLABEL, cnr); } if (fp) { fprintf(fp, "\n"); fclose(fp); } } else { for (index = 0; index < CNR_pairs; index++) { i = ilist[index] - MINLABEL; j = jlist[index] - MINLABEL; if (AdjMatrix->rptr[i+1][j+1] < 0.5) continue; if (i== (2-MINLABEL) && j == (3-MINLABEL) && nvolumes_total > 1) cnr = computePairCNR(LDAmeans[i], LDAmeans[j], SWs[i], SWs[j], classSize[i], classSize[j], nvolumes_total, LDAweight, 1); else cnr = computePairCNR(LDAmeans[i], LDAmeans[j], SWs[i], SWs[j], classSize[i], classSize[j], nvolumes_total, 0, 0); if (fp) fprintf(fp, "%9.4f ", (float)cnr); printf("CNR of class %d and class %d is %g\n", i+MINLABEL, j+MINLABEL, cnr); } if (fp) { fprintf(fp, "\n"); fclose(fp); } } /* output weights for optimize CNR for class 2 and class 3 */ if (weight_fname != NULL) { output_weights_to_file(LDAweight, weight_fname, nvolumes_total); } free(classSize); for (i=0; i< num_classes; i++) { free(LDAmeans[i]); MatrixFree(&SWs[i]); } free(LDAmeans); free(SWs); MatrixFree(&AdjMatrix); if (nvolumes_total > 1 && ((MINLABEL <=2 && MAXLABEL >= 3) || ldaflag)) { if (ldaflag) { printf("LDA weights for %d-%d are: \n", class1, class2); } else { printf("LDA weights for 2-3 are: \n"); } for (i=0; i < nvolumes_total; i++) { printf("%g ", LDAweight[i]); } printf("\n"); if (synth_fname != NULL) { /* linear projection of input volumes to a 1D volume */ min_val = 10000.0; max_val = -10000.0; for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if (whole_volume == 0 && MRIvox(mri_mask, x, y, z) == 0) continue; value = 0.0; for (i=0; i < nvolumes_total; i++) { value += MRIFvox(mri_flash[i], x, y, z)*LDAweight[i]; } if (max_val < value) max_val = value; if (min_val > value) min_val = value; /* Borrow mri_flash[0] to store the float values first */ MRIFvox(mri_flash[0], x, y, z) = value; } printf("max_val = %g, min_val = %g \n", max_val, min_val); /* Scale output to [0, 255] */ for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if (whole_volume == 0 && MRIvox(mri_mask, x, y, z) == 0) continue; value = (MRIFvox(mri_flash[0], x, y, z) - min_val)*255.0/(max_val - min_val) + 0.5; /* +0.5 for round-off */ if (value > 255.0) value = 255.0; if (value < 0) value = 0; /* Borrow mri_flash[0] to store the float values first */ MRIvox(mri_mask, x, y, z) = (BUFTYPE) value; } /* Output synthesized volume */ MRIwrite(mri_mask, synth_fname); } } free(LDAweight); msec = TimerStop(&start) ; seconds = nint((float)msec/1000.0f) ; minutes = seconds / 60 ; seconds = seconds % 60 ; printf("LDA took %d minutes and %d seconds.\n", minutes, seconds) ; MRIfree(&mri_mask); MRIfree(&mri_label); for (i=0; i < nvolumes_total; i++) { MRIfree(&mri_flash[i]); } exit(0); }
int main(int argc, char *argv[]) { char **av; MRI *mri_T1, *mri_tmp, *mri_ctrl, *mri_in, *mri_out; MRI *mri_snr, *mri_bias; MRI *mri_mask1 = NULL; MRI *mri_mask2 = NULL; int ac, nargs; int width, height, depth, x, y, z; int mask1_set = 0; int mask2_set = 0; int i, j, k, cx, cy, cz, count; LTA *lta = 0; int transform_type; double mean, std, value, src, bias, norm; // HISTOGRAM *h; // float bin_size; // int nbins, bin_no; double mean1, std1, mean2, std2, count1, count2, slope, offset; VOL_GEOM vgtmp; LT *lt = NULL; MATRIX *m_tmp = NULL; Progname = argv[0]; nargs = handle_version_option (argc, argv, "$Id: mri_normalize_tp2.c,v 1.8 2011/03/02 00:04:23 nicks Exp $", "$Name: stable5 $"); if (nargs && argc - nargs == 1) exit (0); argc -= nargs ; 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(1); if (tp1_ctrl_fname == NULL || tp1_T1_fname == NULL) { printf("Use options to specify ctrl volume and T1 volume for tp1\n"); usage(1); } mri_in = MRIread(argv[1]) ; if (!mri_in) ErrorExit(ERROR_BADPARM, "%s: could not read input volume %s", Progname, argv[1]) ; mri_T1 = MRIread(tp1_T1_fname) ; if (!mri_T1) ErrorExit(ERROR_BADPARM, "%s: could not read T1 volume for tp1 %s", Progname, tp1_T1_fname) ; mri_ctrl = MRIread(tp1_ctrl_fname) ; if (!mri_ctrl) ErrorExit(ERROR_BADPARM, "%s: could not read control points volume for tp1 %s", Progname, tp1_ctrl_fname) ; if ((mri_in->width != mri_T1->width) || (mri_in->height != mri_T1->height) || (mri_in->depth != mri_T1->depth) || (mri_in->width != mri_ctrl->width) || (mri_in->height != mri_ctrl->height) || (mri_in->depth != mri_ctrl->depth) ) ErrorExit (ERROR_BADPARM, "%s: three input volumes have different sizes \n", Progname); if (mask1_fname) { mri_mask1 = MRIread(mask1_fname) ; if (!mri_mask1) ErrorExit(ERROR_BADPARM, "%s, could not read mask volume for tp1 %s", Progname, mask1_fname); mask1_set = 1; if ((mri_mask1->width != mri_in->width) || (mri_mask1->height != mri_in->height) || (mri_mask1->depth != mri_in->depth)) ErrorExit (ERROR_BADPARM, "%s: mask volumes have different sizes than other volumes \n", Progname); } if (mask2_fname) { mri_mask2 = MRIread(mask2_fname) ; if (!mri_mask2) ErrorExit (ERROR_BADPARM, "%s, could not read mask volume for tp2 %s", Progname, mask2_fname); mask2_set = 1; if ((mri_mask2->width != mri_T1->width) || (mri_mask2->height != mri_T1->height) || (mri_mask2->depth != mri_T1->depth) ) ErrorExit (ERROR_BADPARM, "%s: mask volumes have different sizes than other volumes \n", Progname); } width = mri_in->width ; height = mri_in->height ; depth = mri_in->depth ; //nbins = 200; //h = HISTOalloc(nbins); mri_out = MRIclone(mri_in, NULL) ; /* Read LTA transform and apply it to mri_ctrl */ if (xform_fname != NULL) { // read transform transform_type = TransformFileNameType(xform_fname); if (transform_type == MNI_TRANSFORM_TYPE || transform_type == TRANSFORM_ARRAY_TYPE || transform_type == REGISTER_DAT || transform_type == FSLREG_TYPE ) { printf("Reading transform ...\n"); lta = LTAreadEx(xform_fname) ; if (!lta) ErrorExit(ERROR_NOFILE, "%s: could not read transform file %s", Progname, xform_fname) ; if (transform_type == FSLREG_TYPE) { if (lta_src == 0 || lta_dst == 0) { fprintf (stderr, "ERROR: fslmat does not have information " "on the src and dst volumes\n"); fprintf (stderr, "ERROR: you must give options '-lta_src' and " "'-lta_dst' to specify the src and dst volume infos\n"); } LTAmodifySrcDstGeom (lta, lta_src, lta_dst); // add src and dst information LTAchangeType(lta, LINEAR_VOX_TO_VOX); //this is necessary } if (lta->xforms[0].src.valid == 0) { if (lta_src == 0) { fprintf (stderr, "The transform does not have the valid src volume info.\n"); fprintf (stderr, "Either you give src volume info by option -lta_src or\n"); fprintf(stderr, "make the transform to have the valid src info.\n"); ErrorExit(ERROR_BAD_PARM, "Bailing out...\n"); } else { LTAmodifySrcDstGeom(lta, lta_src, NULL); // add src information // getVolGeom(lta_src, <->src); } } if (lta->xforms[0].dst.valid == 0) { if (lta_dst == 0) { fprintf (stderr, "The transform does not have the valid dst volume info.\n"); fprintf (stderr, "Either you give src volume info by option -lta_dst or\n"); fprintf (stderr, "make the transform to have the valid dst info.\n"); fprintf (stderr, "If the dst was average_305, then you can set\n"); fprintf (stderr, "environmental variable USE_AVERAGE305 true\n"); fprintf (stderr, "without giving the dst volume for RAS-to-RAS transform.\n"); ErrorExit(ERROR_BAD_PARM, "Bailing out...\n"); } else { LTAmodifySrcDstGeom(lta, NULL, lta_dst); // add dst information } } } else { ErrorExit (ERROR_BADPARM, "transform is not of MNI, nor Register.dat, nor FSLMAT type"); } if (invert) { m_tmp = lta->xforms[0].m_L ; lta->xforms[0].m_L = MatrixInverse(lta->xforms[0].m_L, NULL) ; MatrixFree(&m_tmp) ; lt = <a->xforms[0]; if (lt->dst.valid == 0 || lt->src.valid == 0) { fprintf (stderr, "WARNING:***********************************************\n"); fprintf (stderr, "WARNING: dst volume infor is invalid. " "Most likely produce wrong inverse.\n"); fprintf (stderr, "WARNING:***********************************************\n"); } copyVolGeom(<->dst, &vgtmp); copyVolGeom(<->src, <->dst); copyVolGeom(&vgtmp, <->src); } // LTAchangeType(lta, LINEAR_VOX_TO_VOX); /* apply lta to the ctrl volume */ mri_tmp = MRIalloc(mri_ctrl->width, mri_ctrl->height, mri_ctrl->depth, mri_ctrl->type) ; MRIcopyHeader(mri_in, mri_tmp) ; // this function doesn't do NEAREST at all!! // I found the bug, in LTAtransformInterp() mri_tmp = LTAtransformInterp(mri_ctrl, mri_tmp, lta, SAMPLE_NEAREST); MRIfree(&mri_ctrl); mri_ctrl = mri_tmp; if (mask1_fname != NULL && mask2_fname == NULL) { printf("map mask for tp1 to get mask for tp2 ...\n"); mri_mask2 = MRIalloc(mri_in->width, mri_in->height, mri_in->depth, mri_mask1->type) ; MRIcopyHeader(mri_in, mri_mask2) ; mri_mask2 = LTAtransformInterp(mri_mask1, mri_mask2, lta, SAMPLE_NEAREST); mask2_set = 1; if (debug_flag) MRIwrite(mri_mask2, "mri_mask2.mgz"); } else if (mask2_fname != NULL && mask1_fname == NULL) { printf("map mask for tp2 to get mask for tp1 ...\n"); //need to invert lta first m_tmp = lta->xforms[0].m_L ; lta->xforms[0].m_L = MatrixInverse(lta->xforms[0].m_L, NULL) ; MatrixFree(&m_tmp) ; lt = <a->xforms[0]; copyVolGeom(<->dst, &vgtmp); copyVolGeom(<->src, <->dst); copyVolGeom(&vgtmp, <->src); mri_mask1 = MRIalloc(mri_T1->width, mri_T1->height, mri_T1->depth, mri_mask2->type) ; MRIcopyHeader(mri_T1, mri_mask1) ; mri_mask1 = LTAtransformInterp(mri_mask2, mri_mask1, lta, SAMPLE_NEAREST); mask1_set = 1; if (debug_flag) MRIwrite(mri_mask1, "mri_mask1.mgz"); } if (lta_src) MRIfree(<a_src); if (lta_dst) MRIfree(<a_dst); if (lta) LTAfree(<a); } /* if (xform_fname != NULL) */ if (debug_flag) { // MRIwrite(mri_snr, "snr.mgz"); MRIwrite(mri_ctrl, "ctrl.mgz"); } if (mask1_set == 0) { //create mask1 mri_mask1 = MRIalloc(mri_T1->width, mri_T1->height, mri_T1->depth, MRI_UCHAR) ; for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if (MRIgetVoxVal(mri_T1, x, y, z, 0) < noise_threshold) { MRIvox(mri_mask1,x,y,z) = 0; } else MRIvox(mri_mask1,x,y,z) = 1; } } if (mask2_set == 0) { //create mask2 mri_mask2 = MRIalloc(mri_in->width, mri_in->height, mri_in->depth, MRI_UCHAR) ; for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if (MRIgetVoxVal(mri_in, x, y, z, 0) < noise_threshold) { MRIvox(mri_mask2,x,y,z) = 0; } else MRIvox(mri_mask2,x,y,z) = 1; } } #if 0 /* compute the mean and std of T1 volume */ /* Using only high SNR points */ mri_snr = MRIalloc(mri_T1->width, mri_T1->height, mri_T1->depth, MRI_FLOAT) ; MRIcopyHeader(mri_T1, mri_snr) ; h->bin_size = bin_size = 0.5; for (bin_no = 0; bin_no < nbins; bin_no++) h->bins[bin_no] = (bin_no)*bin_size; for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if (MRIgetVoxVal(mri_T1, x, y, z, 0) < noise_threshold) { MRIFvox(mri_snr,x,y,z) = 0; continue; } mean = 0; std = 0; count = 0; for (i=-1; i<=1; i++) for (j=-1; j<=1; j++) for (k=-1;k<=1;k++) { cx = x+i; cy = y+j, cz = z+k; if (cx < 0 || cx >= width || cy < 0 || cy >= height || cz < 0 || cz >= depth) continue; count++; value = MRIgetVoxVal(mri_T1, cx, cy, cz, 0); mean += value; std += value*value; } mean /= (count + 1e-30); std /= (count + 1e-30); std = std - mean *mean; if (std <= 0) std = 0; value = mean/sqrt(std); MRIFvox(mri_snr,x,y,z) = value; bin_no = nint((float)value/(float)bin_size); if (bin_no >= nbins) bin_no = nbins - 1; h->counts[bin_no]++; } for (num = 0.0f, b = h->nbins - 1; b >= 1; b --) { num += h->counts[b]; if (num > 20000) /* this may make me only use WM points, is it good to use only WM to compute scale of intensity?? */ break; } printf("using SNR threshold %2.3f at bin %d\n", h->bins[b], b); mean1 = 0; std1 = 0; count1 = 0; for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if (MRIgetVoxVal(mri_T1, x, y, z, 0) < noise_threshold) { continue; } value = MRIFvox(mri_snr,x,y,z); if (value < h->bins[b]) continue; value = MRIgetVoxVal(mri_T1, x, y, z, 0); count1++; mean1 += value; std1 += value*value; } MRIfree(&mri_snr); #else printf("compute mean and std of tp1 volume within masked area...\n"); mean1 = 0; std1 = 0; count1 = 0; for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if (MRIgetVoxVal(mri_mask1, x, y, z, 0) <= 1e-30) { continue; } value = MRIgetVoxVal(mri_T1, x, y, z, 0); count1++; mean1 += value; std1 += value*value; } #endif mean1 /= (count1 + 1e-30); std1 /= (count1 + 1e-30); std1 = std1 - mean1*mean1; if (std1 <= 0) printf("warning: negative std for T1 volume. \n"); else printf("mean and variance for tp1 volume are %g and %g\n", mean1, std1); printf("now compute SNR and stats for input volume ... \n"); mri_snr = MRIalloc(mri_in->width, mri_in->height, mri_in->depth, MRI_FLOAT) ; MRIcopyHeader(mri_in, mri_snr) ; //HISTOclear(h,h); //h->bin_size = bin_size = 0.5; //for (bin_no = 0; bin_no < nbins; bin_no++) // h->bins[bin_no] = (bin_no)*bin_size; for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if (MRIgetVoxVal(mri_in, x, y, z, 0) < noise_threshold) { MRIFvox(mri_snr,x,y,z) = 0; continue; } mean = 0; std = 0; count = 0; for (i=-1; i<=1; i++) for (j=-1; j<=1; j++) for (k=-1;k<=1;k++) { cx = x+i; cy = y+j, cz = z+k; if (cx < 0 || cx >= width || cy < 0 || cy >= height || cz < 0 || cz >= depth) continue; count++; value = MRIgetVoxVal(mri_in, cx, cy, cz, 0); mean += value; std += value*value; } mean /= (count + 1e-30); std /= (count + 1e-30); std = std - mean *mean; if (std <= 0) std = 0; value = mean/sqrt(std); MRIFvox(mri_snr,x,y,z) = value; //bin_no = nint((float)value/(float)bin_size); //if (bin_no >= nbins) bin_no = nbins - 1; //h->counts[bin_no]++; } #if 0 for (num = 0.0f, b = h->nbins - 1; b >= 1; b --) { num += h->counts[b]; if (num > 20000) /* this may make me only use WM points, is it good to use only WM to compute scale of intensity?? */ break; } printf("using SNR threshold %2.3f at bin %d\n", h->bins[b], b); mean2 = 0; std2 = 0; count2 = 0; for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if (MRIgetVoxVal(mri_in, x, y, z, 0) < noise_threshold) { continue; } value = MRIFvox(mri_snr,x,y,z); if (value >= h->bins[b]) { count2++; mean2 += value; std2 += value*value; } } #else printf("compute mean and std of tp2 volume within masked area\n"); /* somehow mri_watershed seems to leave some unzero voxels around image border, so I will skip image boundaries no, that's not a problem of most recent mri_watershed; something wrong previously */ mean2 = 0; std2 = 0; count2 = 0; for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if (MRIgetVoxVal(mri_mask2, x, y, z, 0) <= 1e-30) { continue; } value = MRIgetVoxVal(mri_in, x, y, z, 0); count2++; mean2 += value; std2 += value*value; } #endif mean2 /= (count2 + 1e-30); std2 /= (count2 + 1e-30); std2 = std2 - mean2*mean2; if (std2 <= 0) printf("warning: negative std for input volume. \n"); else printf("mean and variance for input tp2 volume are %g and %g\n", mean2, std2); //compute intensity scale slope = sqrt(std1/std2); offset = mean1 - slope*mean2; printf("scale input volume by %g x + %g\n", slope, offset); // first change mri_in to FLOAT type mri_tmp = MRIchangeType(mri_in, MRI_FLOAT, 0, 1.0, 1); MRIfree(&mri_in); mri_in = mri_tmp; for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { value = MRIFvox(mri_in, x, y, z); MRIFvox(mri_in, x, y, z) = value*slope + offset; } // printf("compute SNR map of tp2 volume\n"); //already done above // mri_snr = MRIalloc(mri_ctrl->width, // mri_ctrl->height, mri_ctrl->depth, MRI_FLOAT) ; for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if (MRIgetVoxVal(mri_in, x, y, z, 0) < noise_threshold) { // MRIFvox(mri_snr,x,y,z) = 0; continue; } value = MRIFvox(mri_snr,x,y,z); if (value < 20) MRIvox(mri_ctrl, x, y, z) = 0; else if (MRIvox(mri_ctrl, x, y, z) > 0) { MRIvox(mri_ctrl, x, y, z) = 1; } } if (debug_flag) { MRIwrite(mri_snr, "snr.mgz"); // MRIwrite(mri_ctrl, "ctrl.mgz"); } // SNR >= 20 seems a good threshold // Now use ctrl points to normalize tp2 printf("normalize tp2...\n"); mri_bias = MRIbuildBiasImage(mri_in, mri_ctrl, NULL, bias_sigma) ; for (z = 0 ; z < depth ; z++) { for (y = 0 ; y < height ; y++) { for (x = 0 ; x < width ; x++) { src = MRIgetVoxVal(mri_in, x, y, z, 0) ; bias = MRIgetVoxVal(mri_bias, x, y, z, 0) ; if (!bias) /* should never happen */ norm = (float)src ; else norm = (float)src * 110.0 / (float)bias ; if (norm > 255.0f && mri_out->type == MRI_UCHAR) norm = 255.0f ; else if (norm < 0.0f && mri_out->type == MRI_UCHAR) norm = 0.0f ; MRIsetVoxVal(mri_out, x, y, z, 0, norm) ; } } } printf("writing normalized volume to %s...\n", argv[2]) ; MRIwrite(mri_out, argv[2]); MRIfree(&mri_in); MRIfree(&mri_bias); MRIfree(&mri_out); MRIfree(&mri_T1); MRIfree(&mri_ctrl); MRIfree(&mri_snr); //HISTOfree(&h); exit(0); } /* end main() */
MRI * correct_gmwm_boundaries(MRI *segmri, MRI *outmri) { int x, y, z, width, height, depth = 0; double val; MRI *tmpvol = NULL; MRI *allmaskdist, *label2, *label2distmap, *label3, *label3distmap, *label41, *label41distmap, *label42, *label42distmap = NULL; width = segmri->width ; height = segmri->height ; depth = segmri->depth ; // all lables tmpvol = MRIclone(segmri, NULL) ; for (z = 0 ; z < depth ; z++) for (y = 0 ; y < height ; y++) for (x = 0 ; x < width ; x++) { val = MRIgetVoxVal(segmri,x,y,z,0); if (val > 0) MRIsetVoxVal(tmpvol,x,y,z,0,1); } allmaskdist = MRIalloc(width, height, depth, MRI_FLOAT); allmaskdist = MRIextractDistanceMap(tmpvol, allmaskdist, 1, 3, 3, NULL); // label 2 label2 = MRIclone(segmri, NULL) ; for (z = 0 ; z < depth ; z++) for (y = 0 ; y < height ; y++) for (x = 0 ; x < width ; x++) { val = MRIgetVoxVal(segmri,x,y,z,0); if (val == 2) MRIsetVoxVal(label2,x,y,z,0,1); } label2distmap = MRIalloc(width, height, depth, MRI_FLOAT); label2distmap = MRIextractDistanceMap(label2, label2distmap, 1, 3, 3, NULL); // label 3 label3 = MRIclone(segmri, NULL) ; for (z = 0 ; z < depth ; z++) for (y = 0 ; y < height ; y++) for (x = 0 ; x < width ; x++) { val = MRIgetVoxVal(segmri,x,y,z,0); if (val == 3) MRIsetVoxVal(label3,x,y,z,0,1); } label3distmap = MRIalloc(width, height, depth, MRI_FLOAT); label3distmap = MRIextractDistanceMap(label3, label3distmap, 1, 3, 3, NULL); // label 41 label41 = MRIclone(segmri, NULL) ; for (z = 0 ; z < depth ; z++) for (y = 0 ; y < height ; y++) for (x = 0 ; x < width ; x++) { val = MRIgetVoxVal(segmri,x,y,z,0); if (val == 41) MRIsetVoxVal(label41,x,y,z,0,1); } label41distmap = MRIalloc(width, height, depth, MRI_FLOAT); label41distmap = MRIextractDistanceMap(label41, label41distmap, 1, 3, 3, NULL); // label 42 label42 = MRIclone(segmri, NULL) ; for (z = 0 ; z < depth ; z++) for (y = 0 ; y < height ; y++) for (x = 0 ; x < width ; x++) { val = MRIgetVoxVal(segmri,x,y,z,0); if (val == 42) MRIsetVoxVal(label42,x,y,z,0,1); } label42distmap = MRIalloc(width, height, depth, MRI_FLOAT); label42distmap = MRIextractDistanceMap(label42, label42distmap, 1, 3, 3, NULL); if (!outmri) outmri = MRIclone(segmri, NULL) ; for (z = 0 ; z < depth ; z++) for (y = 0 ; y < height ; y++) for (x = 0 ; x < width ; x++) { if(MRIgetVoxVal(label2,x,y,z,0) == 1) { double tmpval = MRIgetVoxVal(label2distmap,x,y,z,0); double tmpval2 = MRIgetVoxVal(label3distmap,x,y,z,0); // if (-0.5 <= lhwmvoldist(WM_L_ind(i)) && lhwmvoldist(WM_L_ind(i)) <= 0 && abs(lhwmvoldist(WM_L_ind(i))) <= lhgmvoldist(WM_L_ind(i)) && lhgmvoldist(WM_L_ind(i)) >= .5 && segvol(WM_L_ind(i)) == 2 && abs(maskvol(WM_L_ind(i))) <= 0.5) if (-0.5 <= tmpval && tmpval <= 0 && fabs(tmpval) <= tmpval2 && tmpval2 >= .5 && fabs(MRIgetVoxVal(allmaskdist,x,y,z,0)) <= 0.5) MRIsetVoxVal(outmri,x,y,z,0,3); } else if(MRIgetVoxVal(label41,x,y,z,0) == 1) { double tmpval = MRIgetVoxVal(label41distmap,x,y,z,0); double tmpval2 = MRIgetVoxVal(label42distmap,x,y,z,0); //if (-0.5 <= rhwmvoldist(WM_R_ind(i)) && rhwmvoldist(WM_R_ind(i)) <= 0 && abs(rhwmvoldist(WM_R_ind(i))) <= rhgmvoldist(WM_R_ind(i)) && rhgmvoldist(WM_R_ind(i)) >= .5 && segvol(WM_R_ind(i)) == 41 && abs(maskvol(WM_R_ind(i))) <= 0.5) if (-0.5 <= tmpval && tmpval <= 0 && fabs(tmpval) <= tmpval2 && tmpval2 >= .5 && fabs(MRIgetVoxVal(allmaskdist,x,y,z,0)) <= 0.5) MRIsetVoxVal(outmri,x,y,z,0,42); } } return(outmri) ; }
/*---------------------------------------------------------------*/ int main(int argc, char *argv[]) { int nargs, nthvtx, nnbrs1, nnbrs2, nthnbr, nbrvtxno1, nbrvtxno2; int nthface, annot1, annot2; VERTEX *vtx1, *vtx2; FACE *face1, *face2; float diff, maxdiff; 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(); if (checkoptsonly) return(0); SUBJECTS_DIR = getenv("SUBJECTS_DIR"); if (SUBJECTS_DIR == NULL) { printf("INFO: SUBJECTS_DIR not defined in environment\n"); //exit(1); } if (SUBJECTS_DIR1 == NULL) SUBJECTS_DIR1 = SUBJECTS_DIR; if (SUBJECTS_DIR2 == NULL) SUBJECTS_DIR2 = SUBJECTS_DIR; if (surf1path == NULL && surfname == NULL) surfname = "orig"; if (surf1path == NULL) { sprintf(tmpstr,"%s/%s/surf/%s.%s",SUBJECTS_DIR1,subject1,hemi,surfname); surf1path = strcpyalloc(tmpstr); } if (surf2path == NULL) { sprintf(tmpstr,"%s/%s/surf/%s.%s",SUBJECTS_DIR2,subject2,hemi,surfname); surf2path = strcpyalloc(tmpstr); } dump_options(stdout); //read-in each surface. notice that the random number generator is //seeded with the same value prior to each read. this is because in //the routine MRIScomputeNormals, if it finds a zero-length vertex //normal, is adds a random value to the x,y,z and recomputes the normal. //so if comparing identical surfaces, the seed must be the same so that //any zero-length vertex normals appear the same. setRandomSeed(seed) ; surf1 = MRISread(surf1path); if (surf1 == NULL) { printf("ERROR: could not read %s\n",surf1path); exit(1); } setRandomSeed(seed) ; surf2 = MRISread(surf2path); if (surf2 == NULL) { printf("ERROR: could not read %s\n",surf2path); exit(1); } printf("Number of vertices %d %d\n",surf1->nvertices,surf2->nvertices); printf("Number of faces %d %d\n",surf1->nfaces,surf2->nfaces); //Number of Vertices ---------------------------------------- if (surf1->nvertices != surf2->nvertices) { printf("Surfaces differ in number of vertices %d %d\n", surf1->nvertices,surf2->nvertices); exit(101); } //Number of Faces ------------------------------------------ if (surf1->nfaces != surf2->nfaces) { printf("Surfaces differ in number of faces %d %d\n", surf1->nfaces,surf2->nfaces); exit(101); } //surf1->faces[10000].area = 100; //surf1->vertices[10000].x = 100; if (ComputeNormalDist) { double dist, dx, dy, dz, dot ; MRI *mri_dist ; mri_dist = MRIalloc(surf1->nvertices,1,1,MRI_FLOAT) ; MRIScomputeMetricProperties(surf1) ; MRIScomputeMetricProperties(surf2) ; for (nthvtx=0; nthvtx < surf1->nvertices; nthvtx++) { vtx1 = &(surf1->vertices[nthvtx]); vtx2 = &(surf2->vertices[nthvtx]); dx = vtx2->x-vtx1->x ; dy = vtx2->y-vtx1->y ; dz = vtx2->z-vtx1->z ; dist = sqrt(dx*dx + dy*dy + dz*dz) ; dot = dx*vtx1->nx + dy*vtx1->ny + dz*vtx1->nz ; dist = dist * dot / fabs(dot) ; MRIsetVoxVal(mri_dist, nthvtx, 0, 0, 0, dist) ; } MRIwrite(mri_dist, out_fname) ; MRIfree(&mri_dist) ; exit(0); } maxdiff=0; //------------------------------------------------------------ if (CheckSurf) { printf("Comparing surfaces\n"); // Loop over vertices --------------------------------------- error_count=0; for (nthvtx=0; nthvtx < surf1->nvertices; nthvtx++) { vtx1 = &(surf1->vertices[nthvtx]); vtx2 = &(surf2->vertices[nthvtx]); if (vtx1->ripflag != vtx2->ripflag) { printf("Vertex %d differs in ripflag %c %c\n", nthvtx,vtx1->ripflag,vtx2->ripflag); if (++error_count>=MAX_NUM_ERRORS) break; } if (CheckXYZ) { diff=fabs(vtx1->x - vtx2->x); if (diff>maxdiff) maxdiff=diff; if (diff>thresh) { printf("Vertex %d differs in x %g %g\t(%g)\n", nthvtx,vtx1->x,vtx2->x,diff); if (++error_count>=MAX_NUM_ERRORS) break; } diff=fabs(vtx1->y - vtx2->y); if (diff>maxdiff) maxdiff=diff; if (diff>thresh) { printf("Vertex %d differs in y %g %g\t(%g)\n", nthvtx,vtx1->y,vtx2->y,diff); if (++error_count>=MAX_NUM_ERRORS) break; } diff=fabs(vtx1->z - vtx2->z); if (diff>maxdiff) maxdiff=diff; if (diff>thresh) { printf("Vertex %d differs in z %g %g\t(%g)\n", nthvtx,vtx1->z,vtx2->z,diff); if (++error_count>=MAX_NUM_ERRORS) break; } } if (CheckNXYZ) { diff=fabs(vtx1->nx - vtx2->nx); if (diff>maxdiff) maxdiff=diff; if (diff>thresh) { printf("Vertex %d differs in nx %g %g\t(%g)\n", nthvtx,vtx1->nx,vtx2->nx,diff); if (++error_count>=MAX_NUM_ERRORS) break; } diff=fabs(vtx1->ny - vtx2->ny); if (diff>maxdiff) maxdiff=diff; if (diff>thresh) { printf("Vertex %d differs in ny %g %g\t(%g)\n", nthvtx,vtx1->ny,vtx2->ny,diff); if (++error_count>=MAX_NUM_ERRORS) break; } diff=fabs(vtx1->nz - vtx2->nz); if (diff>maxdiff) maxdiff=diff; if (diff>thresh) { printf("Vertex %d differs in nz %g %g\t(%g)\n", nthvtx,vtx1->nz,vtx2->nz,diff); if (++error_count>=MAX_NUM_ERRORS) break; } } nnbrs1 = surf1->vertices[nthvtx].vnum; nnbrs2 = surf2->vertices[nthvtx].vnum; if (nnbrs1 != nnbrs2) { printf("Vertex %d has a different number of neighbors %d %d\n", nthvtx,nnbrs1,nnbrs2); if (++error_count>=MAX_NUM_ERRORS) break; } for (nthnbr=0; nthnbr < nnbrs1; nthnbr++) { nbrvtxno1 = surf1->vertices[nthvtx].v[nthnbr]; nbrvtxno2 = surf2->vertices[nthvtx].v[nthnbr]; if (nbrvtxno1 != nbrvtxno2) { printf("Vertex %d differs in the identity of the " "%dth neighbor %d %d\n",nthvtx,nthnbr,nbrvtxno1,nbrvtxno2); if (++error_count>=MAX_NUM_ERRORS) break; } } if (error_count>=MAX_NUM_ERRORS) break; }// loop over vertices if (maxdiff>0) printf("maxdiff=%g\n",maxdiff); if (error_count > 0) { printf("Exiting after finding %d errors\n",error_count); if (error_count>=MAX_NUM_ERRORS) { printf("Exceeded MAX_NUM_ERRORS loop guard\n"); } exit(103); } // Loop over faces ---------------------------------------- error_count=0; for (nthface=0; nthface < surf1->nfaces; nthface++) { face1 = &(surf1->faces[nthface]); face2 = &(surf2->faces[nthface]); if (CheckNXYZ) { diff=fabs(face1->nx - face2->nx); if (diff>maxdiff) maxdiff=diff; if (diff>thresh) { printf("Face %d differs in nx %g %g\t(%g)\n", nthface,face1->nx,face2->nx,diff); if (++error_count>=MAX_NUM_ERRORS) break; } diff=fabs(face1->ny - face2->ny); if (diff>maxdiff) maxdiff=diff; if (diff>thresh) { printf("Face %d differs in ny %g %g\t(%g)\n", nthface,face1->ny,face2->ny,diff); if (++error_count>=MAX_NUM_ERRORS) break; } diff=fabs(face1->nz - face2->nz); if (diff>maxdiff) maxdiff=diff; if (diff>thresh) { printf("Face %d differs in nz %g %g\t(%g)\n", nthface,face1->nz,face2->nz,diff); if (++error_count>=MAX_NUM_ERRORS) break; } } diff=fabs(face1->area - face2->area); if (diff>maxdiff) maxdiff=diff; if (diff>thresh) { printf("Face %d differs in area %g %g\t(%g)\n", nthface,face1->area,face2->area,diff); if (++error_count>=MAX_NUM_ERRORS) break; } if (face1->ripflag != face2->ripflag) { printf("Face %d differs in ripflag %c %c\n", nthface,face1->ripflag,face2->ripflag); if (++error_count>=MAX_NUM_ERRORS) break; } for (nthvtx = 0; nthvtx < 3; nthvtx++) { if (face1->v[nthvtx] != face2->v[nthvtx]) { printf("Face %d differs in identity of %dth vertex %d %d\n", nthface,nthvtx,face1->ripflag,face2->ripflag); if (++error_count>=MAX_NUM_ERRORS) break; } } // end loop over nthface vertex if (error_count>=MAX_NUM_ERRORS) break; } // end loop over faces if (maxdiff>0) printf("maxdiff=%g\n",maxdiff); if (error_count > 0) { printf("Exiting after finding %d errors\n",error_count); if (error_count>=MAX_NUM_ERRORS) { printf("Exceeded MAX_NUM_ERRORS loop guard\n"); } exit(103); } printf("Surfaces are the same\n"); exit(0); } // end check surf // ----------------------------------------------------------------- if (CheckCurv) { printf("Checking curv file %s\n",curvname); sprintf(tmpstr,"%s/%s/surf/%s.%s",SUBJECTS_DIR1,subject1,hemi,curvname); printf("Loading curv file %s\n",tmpstr); if (MRISreadCurvatureFile(surf1, tmpstr) != 0) { printf("ERROR: reading curvature file %s\n",tmpstr); exit(1); } sprintf(tmpstr,"%s/%s/surf/%s.%s",SUBJECTS_DIR2,subject2,hemi,curvname); printf("Loading curv file %s\n",tmpstr); if (MRISreadCurvatureFile(surf2, tmpstr) != 0) { printf("ERROR: reading curvature file %s\n",tmpstr); exit(1); } error_count=0; for (nthvtx=0; nthvtx < surf1->nvertices; nthvtx++) { vtx1 = &(surf1->vertices[nthvtx]); vtx2 = &(surf2->vertices[nthvtx]); diff=fabs(vtx1->curv - vtx2->curv); if (diff>maxdiff) maxdiff=diff; if (diff > thresh) { printf("curv files differ at vertex %d %g %g\t(%g)\n", nthvtx,vtx1->curv,vtx2->curv,diff); if (++error_count>=MAX_NUM_ERRORS) break; } } // end loop over vertices if (maxdiff>0) printf("maxdiff=%g\n",maxdiff); if (error_count > 0) { printf("Exiting after finding %d errors\n",error_count); if (error_count>=MAX_NUM_ERRORS) { printf("Exceeded MAX_NUM_ERRORS loop guard\n"); } exit(103); } printf("Curv files are the same\n"); exit(0); } // end check curv // --------------------------------------------------------- if (CheckAParc) { printf("Checking AParc %s\n",aparcname); sprintf(tmpstr,"%s/%s/label/%s.%s.annot", SUBJECTS_DIR1,subject1,hemi,aparcname); printf("Loading aparc file %s\n",tmpstr); fflush(stdout); if (MRISreadAnnotation(surf1, tmpstr)) { printf("ERROR: MRISreadAnnotation() failed %s\n",tmpstr); exit(1); } if (aparc2name) aparcname = aparc2name; sprintf(tmpstr,"%s/%s/label/%s.%s.annot", SUBJECTS_DIR2,subject2,hemi,aparcname); printf("Loading aparc file %s\n",tmpstr); fflush(stdout); if (MRISreadAnnotation(surf2, tmpstr)) { printf("ERROR: MRISreadAnnotation() failed %s\n",tmpstr); exit(1); } error_count=0; for (nthvtx=0; nthvtx < surf1->nvertices; nthvtx++) { annot1 = surf1->vertices[nthvtx].annotation; annot2 = surf2->vertices[nthvtx].annotation; if (annot1 != annot2) { printf("aparc files differ at vertex %d: 1:%s 2:%s\n", nthvtx, CTABgetAnnotationName(surf1->ct,annot1), CTABgetAnnotationName(surf2->ct,annot2)); if (++error_count>=MAX_NUM_ERRORS) break; } } // end loop over vertices if (error_count > 0) { printf("Exiting after finding %d errors\n",error_count); if (error_count>=MAX_NUM_ERRORS) { printf("Exceeded MAX_NUM_ERRORS loop guard\n"); } exit(103); } printf("\n" "AParc files are the same\n" "------------------------\n"); exit(0); } return 0; }
/*------------------------------------------------------- Translate MHT data to an MRI volume in various different ways so that it can be visualized. Does not attempt to be a proper spatial transform to MRI space, (because what to do when mht->vres is large?) just a way to read out the MHT data in 3D ---------------------------------------------------------*/ MRI * MRIFromMHTandMRIS(MHT * mht, MRIS * mris, MFMM_Option_t mfmm_option) { MRI * amri; int mhtvx, mhtvy, mhtvz; // MHT "voxels" int mrix , mriy , mriz ; // MRI voxels MHBT * bucket; MHB * bin; int binnum; int fno_usage; // int outval; #define HALFMHTFOV 200 #define HALFMRIFOV 128 fno_usage = mht->fno_usage; amri = MRIalloc(256, 256, 256, MRI_SHORT); for (mriz = 0; mriz < 255; mriz++) { for (mriy = 0; mriy < 255; mriy++) { for (mrix = 0; mrix < 255; mrix++) { MRISvox(amri, mrix, mriy, mriz) = 100; } } } // goto done; for (mriz = 0; mriz < 255; mriz++) { mhtvz = HALFMHTFOV - HALFMRIFOV + mriz; for (mriy = 0; mriy < 255; mriy++) { mhtvy = HALFMHTFOV - HALFMRIFOV + mriy; for (mrix = 0; mrix < 255; mrix++) { mhtvx = HALFMHTFOV - HALFMRIFOV + mrix; bucket = MHTgetBucketAtVoxIx(mht, mhtvx, mhtvy, mhtvz); outval = 0; if (bucket) { if (MFMM_None == mfmm_option) { outval = 1; goto outval_done; } for (binnum = 0; binnum < bucket->nused; binnum++ ){ bin = &(bucket->bins[binnum]); switch (mfmm_option) { case MFMM_None: break; case MFMM_Num: outval = bin->fno; goto outval_done; case MFMM_NumDiv16: outval = bin->fno >> 4; goto outval_done; case MFMM_Count: outval++; break; } } } outval_done: if (outval > MAXSHORT) outval = MAXSHORT; // MRI?vox is a type-specific macro! MRISvox(amri, mrix, mriy, mriz) = outval; } // for mrix } // for mriy } // for mriz //done: return amri; }
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; }
MRI * correct_putamen_pallidum_boundaries(MRI *segmri, MRI *outmri) { int x, y, z, width, height, depth = 0; double val; MRI *label42, *label3, *label12, *label12distmap, *label13, *label13distmap, *label51, *label51distmap, *label52, *label52distmap = NULL; width = segmri->width ; height = segmri->height ; depth = segmri->depth ; // label 42 label42 = MRIclone(segmri, NULL) ; for (z = 0 ; z < depth ; z++) for (y = 0 ; y < height ; y++) for (x = 0 ; x < width ; x++) { val = MRIgetVoxVal(segmri,x,y,z,0); if (val == 42) MRIsetVoxVal(label42,x,y,z,0,1); } // label 3 label3 = MRIclone(segmri, NULL) ; for (z = 0 ; z < depth ; z++) for (y = 0 ; y < height ; y++) for (x = 0 ; x < width ; x++) { val = MRIgetVoxVal(segmri,x,y,z,0); if (val == 3) MRIsetVoxVal(label3,x,y,z,0,1); } // label 12 label12 = MRIclone(segmri, NULL) ; for (z = 0 ; z < depth ; z++) for (y = 0 ; y < height ; y++) for (x = 0 ; x < width ; x++) { val = MRIgetVoxVal(segmri,x,y,z,0); if (val == 12) MRIsetVoxVal(label12,x,y,z,0,1); } label12distmap = MRIalloc(width, height, depth, MRI_FLOAT); label12distmap = MRIextractDistanceMap(label12, label12distmap, 1, 3, 3, NULL); // label 13 label13 = MRIclone(segmri, NULL) ; for (z = 0 ; z < depth ; z++) for (y = 0 ; y < height ; y++) for (x = 0 ; x < width ; x++) { val = MRIgetVoxVal(segmri,x,y,z,0); if (val == 13) MRIsetVoxVal(label13,x,y,z,0,1); } label13distmap = MRIalloc(width, height, depth, MRI_FLOAT); label13distmap = MRIextractDistanceMap(label13, label13distmap, 1, 3, 3, NULL); // label 51 label51 = MRIclone(segmri, NULL) ; for (z = 0 ; z < depth ; z++) for (y = 0 ; y < height ; y++) for (x = 0 ; x < width ; x++) { val = MRIgetVoxVal(segmri,x,y,z,0); if (val == 51) MRIsetVoxVal(label51,x,y,z,0,1); } label51distmap = MRIalloc(width, height, depth, MRI_FLOAT); label51distmap = MRIextractDistanceMap(label51, label51distmap, 1, 3, 3, NULL); // label 52 label52 = MRIclone(segmri, NULL) ; for (z = 0 ; z < depth ; z++) for (y = 0 ; y < height ; y++) for (x = 0 ; x < width ; x++) { val = MRIgetVoxVal(segmri,x,y,z,0); if (val == 52) MRIsetVoxVal(label52,x,y,z,0,1); } label52distmap = MRIalloc(width, height, depth, MRI_FLOAT); label52distmap = MRIextractDistanceMap(label52, label52distmap, 1, 3, 3, NULL); for (z = 0 ; z < depth ; z++) for (y = 0 ; y < height ; y++) for (x = 0 ; x < width ; x++) { if(MRIgetVoxVal(label42,x,y,z,0) == 1) { // if (rhputvoldist(Rcort_ind(i))<=.5 || rhpalvoldist(Rcort_ind(i)) <= .5) if (MRIgetVoxVal(label51distmap,x,y,z,0) <= .5 || MRIgetVoxVal(label52distmap,x,y,z,0) <= .5) MRIsetVoxVal(outmri,x,y,z,0,41); } if(MRIgetVoxVal(label3,x,y,z,0) == 1) { // if (lhputvoldist(Lcort_ind(i))<=.5 || lhpalvoldist(Lcort_ind(i)) <= .5) if (MRIgetVoxVal(label12distmap,x,y,z,0) <= .5 || MRIgetVoxVal(label13distmap,x,y,z,0) <= .5) MRIsetVoxVal(outmri,x,y,z,0,2); } } return(outmri) ; }
int main ( int argc, char** argv ) { MRI* mri = NULL; int zX = 256; int zY = 256; int zZ = 256; int err = NO_ERROR; int nX = 0; int nY = 0; int nZ = 0; float sizeX = 1.0; float sizeY = 1.0; float sizeZ = 1.0; int setMethod = SET_METHOD_XYZ; int setValue = 0; char fnVol[256] = "new_volume.mgz"; int i; char* arg = NULL; for ( i = 1; i < argc; i++ ) { arg = argv[i]; if ( argv[i] && *argv[i] != '-' ) { printf( "ERROR: Unrecognized argument %s\n", argv[i] ); PrintUsage( NULL ); exit( 1 ); } while ( arg[0] == '-' ) arg = arg+1; if ( strlen(arg) <= 0 ) continue; if ( strcmp(arg,"h") == 0 || strcmp(arg,"help") == 0 ) { PrintUsage( NULL ); exit( 0 ); } if ( strcmp(arg,"f") == 0 || strcmp(arg,"filename") == 0 ) { if ( i+1 >= argc ) { PrintUsage( "No argument to filename option." ); exit( 1 ); } strcpy( fnVol, argv[i+1] ); i++; } if ( strcmp(arg,"x") == 0 || strcmp(arg,"width") == 0 ) { if ( i+1 >= argc ) { PrintUsage( "No argument to width option." ); exit( 1 ); } zX = atoi(argv[i+1]); i++; } if ( strcmp(arg,"y") == 0 || strcmp(arg,"height") == 0 ) { if ( i+1 >= argc ) { PrintUsage( "No argument to height option." ); exit( 1 ); } zY = atoi(argv[i+1]); i++; } if ( strcmp(arg,"z") == 0 || strcmp(arg,"depth") == 0 ) { if ( i+1 >= argc ) { PrintUsage( "No argument to depth option." ); exit( 1 ); } zZ = atoi(argv[i+1]); i ++; } if ( strcmp(arg,"sizex") == 0 ) { if ( i+1 >= argc ) { PrintUsage( "No argument to sizex option." ); exit( 1 ); } sizeX = atof(argv[i+1]); i++; } if ( strcmp(arg,"sizey") == 0 ) { if ( i+1 >= argc ) { PrintUsage( "No argument to sizey option." ); exit( 1 ); } sizeY = atof(argv[i+1]); i++; } if ( strcmp(arg,"sizez") == 0 ) { if ( i+1 >= argc ) { PrintUsage( "No argument to sizez optoin." ); exit( 1 ); } sizeZ = atof(argv[i+1]); i++; } if ( strcmp(arg,"set-method") == 0 ) { if ( i+1 >= argc ) { PrintUsage( "No argument to set-method option." ); exit( 1 ); } if ( strcmp( argv[i+1], "xyz" ) == 0 ) { setMethod = SET_METHOD_XYZ; i++; printf( "set_method is xyz\n" ); } else if ( strcmp( argv[i+1], "random" ) == 0 ) { setMethod = SET_METHOD_RANDOM; i++; printf( "set_method is random\n" ); } else if ( strncmp( argv[i+1], "constant", 9 ) == 0 ) { if ( i+2 >= argc ) { PrintUsage( "No value argument to constant method option." ); exit( 1 ); } setMethod = SET_METHOD_CONSTANT; setValue = atoi( argv[i+2] ); i+=2; printf( "set_method is constant, %d\n", setValue ); } else { PrintUsage( "Unrecognized argument to set-method option" ); exit( 1 ); } } } printf( "Creating volume %s\n" " width = %d height = %d depth = %d\n" " xsize = %f ysize = %f zsize = %f\n" " set method = %s, constant = %d\n", fnVol, zX, zY, zZ, sizeX, sizeY, sizeZ, sSetMethods[setMethod], setValue ); mri = MRIalloc( zX, zY, zZ, MRI_UCHAR ); if ( NULL == mri ) { fprintf( stderr, "Couldn't create volume.\n" ); return 1; } MRIsetResolution( mri, sizeX, sizeY, sizeZ ); switch ( setMethod ) { case SET_METHOD_CONSTANT: MRIvalueFill( mri, 0 ); break; case SET_METHOD_RANDOM: for ( nZ = 0; nZ < zZ; nZ++ ) { for ( nY = 0; nY < zY; nY++ ) { for ( nX = 0; nX < zX; nX++ ) { MRIvox( mri, nX, nY, nZ ) = (int)((random()/(float)RAND_MAX)*255.0); } } } break; case SET_METHOD_XYZ: for ( nZ = 0; nZ < zZ; nZ++ ) { for ( nY = 0; nY < zY; nY++ ) { for ( nX = 0; nX < zX; nX++ ) { MRIvox( mri, nX, nY, nZ ) = (((float)nZ/(float)zZ)*255.0/3.0) + (((float)nY/(float)zY)*255.0/3.0) + (((float)nX/(float)zX)*255.0/3.0) ; } } } break; default: for ( nZ = (zZ/2) - (zZ/4); nZ < (zZ/2) + (zZ/4); nZ++ ) { for ( nY = (zY/2) - (zY/4); nY < (zY/2) + (zY/4); nY++ ) { for ( nX = (zX/2) - (zX/4); nX < (zX/2) + (zX/4); nX++ ) { MRIvox( mri, nX, nY, nZ ) = 255; } } } } err = MRIwrite( mri, fnVol ); if ( NO_ERROR != err ) { fprintf( stderr, "Couldn't write volume.\n" ); return 1; } MRIfree( &mri ); return 0; }
MRI * correct_largestCC_and_fill_holes(MRI *segmri, MRI *outmri) { int i, x, y, z, width, height, depth = 0, val; width = segmri->width ; height = segmri->height ; depth = segmri->depth ; // char fname[STR_LEN]; if (!outmri) printf("no outmri volume exists!\n") ; //outmri = MRIclone(segmri, NULL) ; //outmri = MRIalloc(width, height, depth, MRI_INT); int *segidlist; int nsegids = 0; segidlist = MRIsegIdListNot0(segmri, &nsegids, 0); MRI *currlabelvol = MRIalloc(width, height, depth, MRI_INT); int currlabel = 0; for (i = 0; i < nsegids; i++) { currlabel = segidlist[i]; if (currlabel > 0) { // label volume for (x = 0 ; x < width ; x++) for (y = 0 ; y < height ; y++) for (z = 0 ; z < depth ; z++) if (MRIgetVoxVal(segmri,x,y,z,0) == currlabel) MRIsetVoxVal(currlabelvol,x,y,z,0,1); else MRIsetVoxVal(currlabelvol,x,y,z,0,0); // choose largest connected components // sprintf(fname, "/tmp/%d.%s", currlabel, "before-largest-conn-component.mgz") ; // MRIwrite(currlabelvol, fname) ; GetLargestCC6(currlabelvol); // Note: how to fill the background???!! -- WM // sprintf(fname, "/tmp/%d.%s", currlabel, "largest-conn-component.mgz") ; // MRIwrite(currlabelvol, fname) ; // remove holes on that component RemoveHoles(currlabelvol); // sprintf(fname, "/tmp/%d.%s", currlabel, "holes-removed.mgz") ; // MRIwrite(currlabelvol, fname) ; //fill ouput volume with new labels for (x = 0 ; x < width ; x++) for (y = 0 ; y < height ; y++) for (z = 0 ; z < depth ; z++) { val = MRIgetVoxVal(currlabelvol,x,y,z,0); if (val == 1) MRIsetVoxVal(outmri,x,y,z,0,currlabel); } } } return(outmri) ; }
int main(int argc, char *argv[]) { char **av, *in_fname; int ac, nargs, i, j, x, y, z, width, height, depth; MRI *mri_flash[MAX_IMAGES], *mri_label, *mri_mask, *mri_tmp; int msec, minutes, seconds, nvolumes, nvolumes_total ; struct timeb start ; float max_val, min_val, value; float *LDAmean1, *LDAmean2, *LDAweight; int label; double sum_white, sum_gray; int count_white, count_gray; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mri_ms_LDA.c,v 1.4 2011/03/02 00:04:23 nicks 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 < 2) usage_exit(1) ; printf("command line parsing finished\n"); if (have_weight == 0 && ldaflag == 0) { printf("Use -lda option to specify two class labels to optimize CNR on \n"); usage_exit(0); } if (have_weight == 0 && label_fname == NULL) { printf("Use -label option to specify file for segmentation \n"); usage_exit(0); } if (have_weight == 1 && weight_fname == NULL) { printf("Use -weight option to specify file for input LDA weights \n") ; usage_exit(0); } if (have_weight == 1 && synth_fname == NULL) { printf("Use -synth option to specify file for output synthesized volume \n") ; usage_exit(0); } ////////////////////////////////////////////////////////////////////////////////// /*** Read in the input multi-echo volumes ***/ nvolumes = 0 ; for (i = 1 ; i < argc; i++) { in_fname = argv[i] ; printf("reading %s...\n", in_fname) ; mri_flash[nvolumes] = MRIread(in_fname) ; if (mri_flash[nvolumes] == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read volume %s", Progname, in_fname) ; /* conform will convert all data to UCHAR, which will reduce data resolution*/ printf("%s read in. \n", in_fname) ; if (conform) { printf("embedding and interpolating volume\n") ; mri_tmp = MRIconform(mri_flash[nvolumes]) ; MRIfree(&mri_flash[nvolumes]); mri_flash[nvolumes] = mri_tmp ; } /* Change all volumes to float type for convenience */ if (mri_flash[nvolumes]->type != MRI_FLOAT) { printf("Volume %d type is %d\n", nvolumes+1, mri_flash[nvolumes]->type); printf("Change data to float type \n"); mri_tmp = MRIchangeType(mri_flash[nvolumes], MRI_FLOAT, 0, 1.0, 1); MRIfree(&mri_flash[nvolumes]); mri_flash[nvolumes] = mri_tmp; //swap } nvolumes++ ; } printf("All data read in\n"); /////////////////////////////////////////////////////////////////////////// nvolumes_total = nvolumes ; /* all volumes read in */ for (i = 0 ; i < nvolumes ; i++) { for (j = i+1 ; j < nvolumes ; j++) { if ((mri_flash[i]->width != mri_flash[j]->width) || (mri_flash[i]->height != mri_flash[j]->height) || (mri_flash[i]->depth != mri_flash[j]->depth)) ErrorExit(ERROR_BADPARM, "%s:\nvolumes %d (type %d) and %d (type %d) don't match (%d x %d x %d) vs (%d x %d x %d)\n", Progname, i, mri_flash[i]->type, j, mri_flash[j]->type, mri_flash[i]->width, mri_flash[i]->height, mri_flash[i]->depth, mri_flash[j]->width, mri_flash[j]->height, mri_flash[j]->depth) ; } } width = mri_flash[0]->width; height = mri_flash[0]->height; depth = mri_flash[0]->depth; if (label_fname != NULL) { mri_label = MRIread(label_fname); if (!mri_label) ErrorExit(ERROR_NOFILE, "%s: could not read input volume %s\n", Progname, label_fname); if ((mri_label->width != mri_flash[0]->width) || (mri_label->height != mri_flash[0]->height) || (mri_label->depth != mri_flash[0]->depth)) ErrorExit(ERROR_BADPARM, "%s: label volume size doesn't match data volumes\n", Progname); /* if(mri_label->type != MRI_UCHAR) ErrorExit(ERROR_BADPARM, "%s: label volume is not UCHAR type \n", Progname); */ } if (mask_fname != NULL) { mri_mask = MRIread(mask_fname); if (!mri_mask) ErrorExit(ERROR_NOFILE, "%s: could not read input volume %s\n", Progname, mask_fname); if ((mri_mask->width != mri_flash[0]->width) || (mri_mask->height != mri_flash[0]->height) || (mri_mask->depth != mri_flash[0]->depth)) ErrorExit(ERROR_BADPARM, "%s: mask volume size doesn't macth data volumes\n", Progname); if (mri_mask->type != MRI_UCHAR) ErrorExit(ERROR_BADPARM, "%s: mask volume is not UCHAR type \n", Progname); } else { if (have_weight == 1) noise_threshold = - 1e20; printf("Threshold input vol1 at %g to create mask \n", noise_threshold); printf("this threshold is useful to process skull-stripped data \n"); mri_mask = MRIalloc(mri_flash[0]->width, mri_flash[0]->height, mri_flash[0]->depth, MRI_UCHAR); MRIcopyHeader(mri_flash[0], mri_mask); /* Simply set mask to be 1 everywhere */ for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if ((float)MRIgetVoxVal(mri_flash[0], x, y,z,0) < noise_threshold) MRIvox(mri_mask, x, y,z) = 0; else MRIvox(mri_mask, x, y,z) = 1; } } /* Normalize input volumes */ if (normflag) { printf("Normalize input volumes to zero mean, variance 1\n"); for (i=0; i <nvolumes_total; i++) { mri_flash[i] = MRInormalizeXH(mri_flash[i], mri_flash[i], mri_mask); } printf("Normalization done.\n"); } if (0) { printf("Using both hemi-sphere by changing rh-labels\n"); for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { label = (int)MRIgetVoxVal(mri_label, x, y,z,0); if (label == 41) /* white matter */ MRIsetVoxVal(mri_label, x, y, z, 0, 2); else if (label == 42) /* gm */ MRIsetVoxVal(mri_label, x, y, z, 0, 3); } } if (debug_flag && window_flag) { /* Limit LDA to a local window */ printf("Local window size = %d\n", window_size); window_size /= 2; for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if (MRIvox(mri_mask, x, y,z) == 0) continue; if (z < (Gz - window_size) || z >(Gz + window_size) || y <(Gy - window_size) || y > (Gy + window_size) || x < (Gx - window_size) || x > (Gx + window_size)) MRIvox(mri_mask, x, y,z) = 0; } } LDAmean1 = (float *)malloc(nvolumes_total*sizeof(float)); LDAmean2 = (float *)malloc(nvolumes_total*sizeof(float)); LDAweight = (float *)malloc(nvolumes_total*sizeof(float)); if (have_weight) { printf("Read in LDA weights from weight-file\n"); input_weights_to_file(LDAweight, weight_fname, nvolumes_total); } else { /* compute LDA weights */ printf("Compute LDA weights to maximize CNR for region %d and region %d\n", class1, class2); /* Compute class means */ update_LDAmeans(mri_flash, mri_label, mri_mask, LDAmean1, LDAmean2, nvolumes_total, class1, class2); printf("class means computed \n"); /* Compute Fisher's LDA weights */ computeLDAweights(LDAweight, mri_flash, mri_label, mri_mask, LDAmean1, LDAmean2, nvolumes_total, class1, class2); if (weight_fname != NULL) { output_weights_to_file(LDAweight, weight_fname, nvolumes_total); } } printf("LDA weights are: \n"); for (i=0; i < nvolumes_total; i++) { printf("%g ", LDAweight[i]); } printf("\n"); if (synth_fname != NULL) { /* linear projection of input volumes to a 1D volume */ min_val = 10000.0; max_val = -10000.0; for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if (whole_volume == 0 && MRIvox(mri_mask, x, y, z) == 0) continue; value = 0.0; for (i=0; i < nvolumes_total; i++) { value += MRIFvox(mri_flash[i], x, y, z)*LDAweight[i]; } // if(value < 0) value = 0; if (max_val < value) max_val = value; if (min_val > value) min_val = value; /* Borrow mri_flash[0] to store the float values first */ MRIFvox(mri_flash[0], x, y, z) = value; } printf("max_val = %g, min_val = %g \n", max_val, min_val); /* Check to make sure class1 has higher intensity than class2 */ if (have_weight == 0) { sum_white =0; count_white = 0; sum_gray = 0; count_gray = 0; for (z=0; z < depth; z++) { if (count_white > 300 && count_gray > 300) break; for (y=0; y< height; y++) { for (x=0; x < width; x++) { if ((int)MRIgetVoxVal(mri_label, x, y,z,0) == class1) { sum_white += MRIFvox(mri_flash[0], x, y, z); count_white += 1; } else if ((int)MRIgetVoxVal(mri_label, x, y,z,0) == class2) { sum_gray += MRIFvox(mri_flash[0], x, y, z); count_gray += 1; } } } } if (count_white > 1 && count_gray > 1) { if (sum_white *count_gray < sum_gray*count_white) { for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if (whole_volume == 0 && MRIvox(mri_mask, x, y, z) == 0) continue; value = MRIFvox(mri_flash[0], x, y, z); MRIFvox(mri_flash[0], x, y, z) = max_val - value; } max_val = max_val - min_val; min_val = 0; } } } /* The following is copied to be consistent with mri_synthesize */ /* Don't know why add min_val, minus should make more sense */ for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if (whole_volume == 0 && MRIvox(mri_mask, x, y, z) == 0) { MRIFvox(mri_flash[0], x, y, z) = 0; /*background always set to 0 */ continue; } /* Borrow mri_flash[0] to store the float values first */ if (shift_value > 0) { value = MRIFvox(mri_flash[0], x, y, z) + shift_value; if (value < 0) value = 0; MRIFvox(mri_flash[0], x, y, z) = value; } else if (mask_fname != NULL) MRIFvox(mri_flash[0], x, y, z) -= min_val; } MRIfree(&mri_mask); if (mri_flash[0]->type == out_type) { mri_mask = MRIcopy(mri_flash[0], mri_mask); } else { mri_mask = MRIchangeType(mri_flash[0], out_type, 0.1, 0.99, 0); } /* Scale output to [0, 255] */ if (0) { for (z=0; z < depth; z++) for (y=0; y< height; y++) for (x=0; x < width; x++) { if (whole_volume == 0 && MRIvox(mri_mask, x, y, z) == 0) continue; value = (MRIFvox(mri_flash[0], x, y, z) - min_val)*255.0/(max_val - min_val) + 0.5; /* +0.5 for round-off */ if (value > 255.0) value = 255.0; if (value < 0) value = 0; /* Borrow mri_flash[0] to store the float values first */ MRIvox(mri_mask, x, y, z) = (BUFTYPE) value; } } /* Output synthesized volume */ MRIwrite(mri_mask, synth_fname); } free(LDAmean1); free(LDAmean2); free(LDAweight); msec = TimerStop(&start) ; seconds = nint((float)msec/1000.0f) ; minutes = seconds / 60 ; seconds = seconds % 60 ; printf("LDA took %d minutes and %d seconds.\n", minutes, seconds) ; MRIfree(&mri_mask); if (label_fname) MRIfree(&mri_label); for (i=0; i < nvolumes_total; i++) { MRIfree(&mri_flash[i]); } exit(0); }