int relabel_hypointensities_neighboring_gray(MRI *mri) { int x, y, z, label, changed, i ; MRI *mri_tmp = NULL ; for (changed = i = 0 ; i < 2 ; i++) { mri_tmp = MRIcopy(mri, mri_tmp) ; for (x = 0 ; x < mri->width ; x++) { for (y = 0 ; y < mri->height ; y++) { for (z = 0 ; z < mri->depth ; z++) { label = MRIgetVoxVal(mri_tmp, x, y, z, 0) ; if (label != WM_hypointensities) { continue ; } if (MRIneighbors(mri_tmp, x, y, z, Left_Cerebral_Cortex) > 0) { MRIsetVoxVal(mri, x, y, z, 0, Left_Cerebral_Cortex) ; changed++ ; } else if (MRIneighbors(mri_tmp,x,y,z,Right_Cerebral_Cortex) > 0) { MRIsetVoxVal(mri, x, y, z, 0, Right_Cerebral_Cortex) ; changed++ ; } } } } } printf("%d hypointense voxels neighboring cortex changed\n", changed) ; return(NO_ERROR) ; }
static int normalize_timepoints_with_samples(MRI *mri, GCA_SAMPLE *gcas, int nsamples, int nsoap) { int frame, i, x, y, z ; double target, val ; MRI *mri_ctrl, *mri_bias, *mri_target, *mri_frame ; mri_ctrl = MRIcloneDifferentType(mri, MRI_UCHAR) ; mri_bias = MRIcloneDifferentType(mri, MRI_FLOAT) ; mri_target = MRIcloneDifferentType(mri, MRI_FLOAT) ; for (i = 0 ; i < nsamples ; i++) { if (i == Gdiag_no) DiagBreak() ; x = nint(gcas[i].x) ; y = nint(gcas[i].y) ; z = nint(gcas[i].z) ; MRIsetVoxVal(mri_ctrl, x, y, z, 0, CONTROL_MARKED) ; for (target = 0.0, frame = 0 ; frame < mri->nframes ; frame++) target += MRIgetVoxVal(mri, x, y, z, frame) ; target /= mri->nframes ; MRIsetVoxVal(mri_target, x, y, z, 0, target) ; } // build a bias correction for each time point (which each has its own frame) for (frame = 0 ; frame < mri->nframes ; frame++) { MRIclear(mri_bias) ; for (i = 0 ; i < nsamples ; i++) { if (i == Gdiag_no) DiagBreak() ; x = nint(gcas[i].x) ; y = nint(gcas[i].y) ; z = nint(gcas[i].z) ; target = MRIgetVoxVal(mri_target, x, y, z, 0) ; val = MRIgetVoxVal(mri, x, y, z, frame) ; if (FZERO(val)) val = 1.0 ; MRIsetVoxVal(mri_bias, x, y, z, 0, target/val) ; } MRIbuildVoronoiDiagram(mri_bias, mri_ctrl, mri_bias) ; MRIsoapBubble(mri_bias, mri_ctrl, mri_bias, nsoap) ; mri_frame = MRIcopyFrame(mri, NULL, frame, 0) ; MRImultiply(mri_frame, mri_bias, mri_frame) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { char fname[STRLEN] ; sprintf(fname, "frame%d.mgz", frame) ; MRIwrite(mri_frame, fname) ; sprintf(fname, "bias%d.mgz", frame) ; MRIwrite(mri_bias, fname) ; sprintf(fname, "target%d.mgz", frame) ; MRIwrite(mri_target, fname) ; } MRIcopyFrame(mri_frame, mri, 0, frame) ; } MRIfree(&mri_bias) ; MRIfree(&mri_target) ; MRIfree(&mri_ctrl) ; return(NO_ERROR) ; }
MRI * MRIcropVolumeToLabel(MRI *mri_src, MRI *mri_dst, LABEL *area, MRI_SURFACE *mris_white, MRI_SURFACE *mris_pial) { MHT *mht_white, *mht_pial ; int x, y, z ; VERTEX *v_white, *v_pial ; Real xs, ys, zs ; mht_white = MHTfillVertexTableRes(mris_white, NULL, CURRENT_VERTICES, 5.0) ; mht_pial = MHTfillVertexTableRes(mris_pial, NULL, CURRENT_VERTICES, 5.0) ; if (mri_dst == NULL) mri_dst = MRIclone(mri_src, NULL) ; MRISclearMarks(mris_white) ; MRISclearMarks(mris_pial) ; LabelMarkSurface(area, mris_white) ; LabelMarkSurface(area, mris_pial) ; for (x = 0 ; x < mri_src->width ; x++) { for (y = 0 ; y < mri_src->height ; y++) { for (z = 0 ; z < mri_src->depth ; z++) { if (x == Gx && y == Gy && z == Gz) DiagBreak() ; if (MRIgetVoxVal(mri_src, x, y, z, 0) > 0) { MRISsurfaceRASFromVoxel(mris_white, mri_dst, x, y, z, &xs, &ys, &zs) ; v_white = MHTfindClosestVertexInTable(mht_white, mris_white, xs, ys, zs, 1) ; v_pial = MHTfindClosestVertexInTable(mht_pial, mris_pial, xs, ys, zs, 1) ; if ((v_white && v_white->marked == 1) || (v_pial && v_pial->marked == 1)) { MRIsetVoxVal(mri_dst, x, y, z, 0, 255) ; } else MRIsetVoxVal(mri_dst, x, y, z, 0, 0) ; } } } } MHTfree(&mht_white) ; MHTfree(&mht_pial) ; return(mri_dst) ; }
static int normalize_PD(MRI *mri_PD, float target) { double mean_PD, scale, val ; int x, y, z ; for (mean_PD = 0.0, x = 0 ; x < mri_PD->width ; x++) { for (y = 0 ; y < mri_PD->height ; y++) { for (z = 0 ; z < mri_PD->depth ; z++) { mean_PD += (double)MRIgetVoxVal(mri_PD, x, y, z,0) ; } } } mean_PD /= (mri_PD->width * mri_PD->height * mri_PD->depth) ; scale = target / mean_PD ; printf("mean PD %2.0f, scaling by %2.2f to set mean to %2.0f\n", mean_PD, scale, target) ; for (mean_PD = 0.0, x = 0 ; x < mri_PD->width ; x++) { for (y = 0 ; y < mri_PD->height ; y++) { for (z = 0 ; z < mri_PD->depth ; z++) { val = (double)MRIgetVoxVal(mri_PD, x, y, z,0) ; val *= scale ; MRIsetVoxVal(mri_PD, x, y, z,0, val); } } } return(NO_ERROR) ; }
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) ; }
/*! \fn MRI *RFstat2P(MRI *rf, RFS *rfs, MRI *binmask, int TwoSided, MRI *p) \brief Converts a stat to a p value. If TwoSided, then computes a p value based on an unsigned stat, but the sign is still passed to p. */ MRI *RFstat2P(MRI *rf, RFS *rfs, MRI *binmask, int TwoSided, MRI *p) { int c,r,s,f=0,m; double v,pval; if (RFname2Code(rfs) == -1) return(NULL); p = MRIclone(rf,p); for (c=0; c < rf->width; c++) { for (r=0; r < rf->height; r++) { for (s=0; s < rf->depth; s++) { if (binmask != NULL) { m = (int)MRIgetVoxVal(binmask,c,r,s,0); if (!m) continue; } for (f=0; f < rf->nframes; f++) { v = MRIgetVoxVal(rf,c,r,s,f); if(TwoSided) pval = SIGN(v)*2*RFstat2PVal(rfs,fabs(v)); else pval = RFstat2PVal(rfs,v); MRIsetVoxVal(p,c,r,s,f,pval); } } } } return(p); }
MRI * MRIcombineDistanceTransforms(MRI *mri_src1, MRI *mri_src2, MRI *mri_dst) { int x, y, z, f ; float val1, val2 ; if (mri_dst == NULL) { mri_dst = MRIclone(mri_src1, NULL) ; } for (f = 0 ; f < mri_dst->nframes ; f++) for (x = 0 ; x < mri_dst->width ; x++) for (y = 0 ; y < mri_dst->height ; y++) for (z = 0 ; z < mri_dst->depth ; z++) { val1 = MRIgetVoxVal(mri_src1, x, y, z, f) ; val2 = MRIgetVoxVal(mri_src2, x, y, z, f) ; if (val2 < 0 && val1 > 0) { val1 = val2 ; // in the interior of 1 } else if (val2 > 0 && val1 > val2) // exterior of both, but closer to border of 2 { val1 = val2 ; } else if (val2 < 0 && val1 < val2) { val1 = val2 ; // interior of both, but closer to border of 2 } MRIsetVoxVal(mri_dst, x, y, z, f, val1) ; } return(mri_dst) ; }
static int normalize_timepoints_with_parzen_window(MRI *mri, double cross_time_sigma) { int frame1, frame2, x, y, z ; double val0, val, total, g, norm, total_norm ; norm = 1 / sqrt(2 * M_PI * SQR(cross_time_sigma)) ; for (x = 0 ; x < mri->width ; x++) for (y = 0 ; y < mri->height ; y++) for (z = 0 ; z < mri->depth ; z++) { if (x == Gx && y == Gy && z == Gz) DiagBreak() ; for (frame1 = 0 ; frame1 < mri->nframes ; frame1++) { val0 = MRIgetVoxVal(mri, x, y, z, frame1) ; for (total = total_norm = 0.0, frame2 = 0 ; frame2 < mri->nframes ; frame2++) { val = MRIgetVoxVal(mri, x, y, z, frame2) ; g = norm * exp( - SQR(val-val0) / (2 * SQR(cross_time_sigma))) ; total += g*val ; total_norm += g ; } total /= total_norm ; MRIsetVoxVal(mri, x, y, z, frame1, total) ; } } return(NO_ERROR) ; }
/*-------------------------------------------------------------------*/ MRI *RFp2Stat(MRI *p, RFS *rfs, MRI *binmask, MRI *rf) { int c,r,s,f,m; double v,pval; if (RFname2Code(rfs) == -1) return(NULL); rf = MRIclone(p,rf); for (c=0; c < rf->width; c++) { for (r=0; r < rf->height; r++) { for (s=0; s < rf->depth; s++) { if (binmask != NULL) { m = (int)MRIgetVoxVal(binmask,c,r,s,0); if (!m) continue; } for (f=0; f < rf->nframes; f++) { pval = MRIgetVoxVal(p,c,r,s,f); v = RFp2StatVal(rfs,pval); MRIsetVoxVal(rf,c,r,s,f,v); } } } } return(rf); }
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) ; }
/*-------------------------------------------------------------------*/ MRI *RFrescale(MRI *rf, RFS *rfs, MRI *binmask, MRI *rfout) { int c,r,s,f,m; double v, gmean, gstddev, gmax; if (RFname2Code(rfs) == -1) return(NULL); RFexpectedMeanStddev(rfs); // expected RFglobalStats(rf, binmask, &gmean, &gstddev, &gmax); //actual rfout = MRIclone(rf,rfout); for (c=0; c < rf->width; c++) { for (r=0; r < rf->height; r++) { for (s=0; s < rf->depth; s++) { if (binmask != NULL) { m = (int)MRIgetVoxVal(binmask,c,r,s,0); if (!m) continue; } for (f=0; f < rf->nframes; f++) { v = MRIgetVoxVal(rf,c,r,s,f); v = (v - gmean)*(rfs->stddev/gstddev) + rfs->mean; MRIsetVoxVal(rfout,c,r,s,f,v); } } } } return(rfout); }
/*------------------------------------------------------------------------------- MRIbinarize2() - same as MRIbinarize() but passes theshold, low, and hi as doubles instead of UCHARs. -------------------------------------------------------------------------------*/ MRI * MRIbinarize2(MRI *mri_src, MRI *mri_dst, double threshold, double low_val, double hi_val) { int width, height, depth, x, y, z, f ; double val; if (!mri_dst) mri_dst = MRIclone(mri_src, NULL) ; width = mri_src->width ; height = mri_src->height ; depth = mri_src->depth ; for (f = 0 ; f < mri_src->nframes ; f++) { for (z = 0 ; z < depth ; z++) { for (y = 0 ; y < height ; y++) { for (x = 0 ; x < width ; x++) { val = MRIgetVoxVal(mri_src, x, y, z, f); if (val > threshold) val = hi_val ; else val = low_val ; MRIsetVoxVal(mri_dst, x, y, z, f, val) ; } } } } return(mri_dst) ; }
static int apply_bias_field(MRI *mri, int nbias, float *bias_coefs[3][2]) { int x, y, z, n ; double xb, yb, zb, x0, y0, z0, w0x, w0y, w0z ; float val ; x0 = mri->width/2 ; y0 = mri->height/2 ; z0 = mri->depth/2 ; w0x = 2/x0 ; w0y = 2/y0 ; w0z = 2/z0 ; for (x = 0 ; x < mri->width ; x++) { for (xb = 1.0, n=1 ; n <= nbias ; n++) xb += bias_coefs[0][0][n-1] * cos(w0x*n*(x-x0)) + bias_coefs[0][1][n-1] * sin(w0x*n*(x-x0)) ; for (y = 0 ; y < mri->height ; y++) { for (yb = 1.0, n=1 ; n <= nbias ; n++) yb += bias_coefs[1][0][n-1] * cos(w0y*n*(y-y0)) + bias_coefs[1][1][n-1] * sin(w0y*n*(y-y0)) ; for (z = 0 ; z < mri->depth ; z++) { for (zb = 1.0, n=1 ; n <= nbias ; n++) zb += bias_coefs[2][0][n-1] * cos(w0z*n*(z-z0)) + bias_coefs[2][1][n-1] * sin(w0z*n*(z-z0)) ; val = MRIgetVoxVal(mri, x, y, z, 0) ; val = val * xb * yb * zb ; MRIsetVoxVal(mri, x, y, z, 0, val) ; } } } return(NO_ERROR) ; }
int MRIeraseSmallSegments(MRI_SEGMENTATION *mriseg, MRI *mri_seg, int min_voxels) { int s, v, nerased = 0, x, y, z ; MRI_SEGMENT *mseg ; if (DIAG_VERBOSE_ON && 0) fprintf(stdout, "compacting segments...\n") ; for (s = 0 ; s < mriseg->max_segments ; s++) { mseg = &mriseg->segments[s] ; if (mseg->nvoxels < min_voxels) { if (mseg->voxels) for (v = 0 ; v < mseg->nvoxels ; v++) { x = mseg->voxels[v].x ; y = mseg->voxels[v].y ; z = mseg->voxels[v].z ; if (x == Gx && y == Gy && z == Gz) printf("MRIeraseSmallSegments: erasing (%d, %d %d)\n", x, y, z) ; MRIsetVoxVal(mri_seg, x, y, z,0, 0) ; nerased++ ; } } } return(nerased) ; }
/*! \fn int CCSegment(MRI *seg, int segid, int segidunknown) Constraints a sementation ID to consist of voxels that are spatially contiguous (6 face neighbors, not edge or corner). The voxels in the largest cluster are not changed. The voxels in the other clusters are set to segidunknown. */ int CCSegment(MRI *seg, int segid, int segidunknown) { MRI_SEGMENTATION *sgmnt; int k,kmax,index,c,r,s; sgmnt = MRIsegment(seg,segid-.5,segid+.5); printf(" Found %d clusters\n",sgmnt->nsegments); kmax = 0; for (k=0; k < sgmnt->nsegments; k++) if (sgmnt->segments[k].nvoxels > sgmnt->segments[kmax].nvoxels) { kmax = k; } for (k=0; k < sgmnt->nsegments; k++) { printf(" %d k %f\n",k,sgmnt->segments[k].area); if (k==kmax) { continue; } for (index = 0; index < sgmnt->segments[k].nvoxels; index++) { c = sgmnt->segments[k].voxels[index].x; r = sgmnt->segments[k].voxels[index].y; s = sgmnt->segments[k].voxels[index].z; MRIsetVoxVal(seg,c,r,s,0,segidunknown); } } MRIsegmentFree(&sgmnt); return(0); }
/*-------------------------------------------------------------------*/ int RFsynth(MRI *rf, RFS *rfs, MRI *binmask) { int c,r,s,f; double v,m; if (RFname2Code(rfs) == -1) return(1); for (c=0; c < rf->width; c++) { for (r=0; r < rf->height; r++) { for (s=0; s < rf->depth; s++) { if (binmask != NULL) { m = MRIgetVoxVal(binmask,c,r,s,0); if (m < 0.5) continue; } for (f=0; f < rf->nframes; f++) { v = RFdrawVal(rfs); MRIsetVoxVal(rf,c,r,s,f,v); } } } } return(0); }
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 int copy_ctrl_points_to_volume(GCA_SAMPLE *gcas, int nsamples, MRI *mri_ctrl, int frame) { int i, xv, yv, zv, nregions ; nregions = mri_ctrl->nframes/2 ; for (i = 0 ; i < nsamples ; i++) { xv = gcas[i].x ; yv = gcas[i].y ; zv = gcas[i].z ; if (xv == Ggca_x && yv == Ggca_y && zv == Ggca_z) DiagBreak() ; MRIsetVoxVal(mri_ctrl, xv, yv, zv, frame, gcas[i].label) ; MRIsetVoxVal(mri_ctrl, xv, yv, zv, frame+nregions, gcas[i].means[0]) ; } return(NO_ERROR) ; }
static int discard_PD(MRI *mri_PD, short thresh, short target) { int x, y, z ; double val ; for (x = 0 ; x < mri_PD->width ; x++) { for (y = 0 ; y < mri_PD->height ; y++) { for (z = 0 ; z < mri_PD->depth ; z++) { val = MRIgetVoxVal(mri_PD, x, y, z,0) ; if (val > thresh) MRIsetVoxVal(mri_PD, x, y, z,0, target); else MRIsetVoxVal(mri_PD, x, y, z,0,0); } } } return(NO_ERROR) ; }
/*--------------------------------------------------------------------------*/ static void PutVertical ( MRI *mri_vol, /* output image volume */ long x, /* x coordinate of the selected line */ long y, /* y coordinate of the selected line */ double Line[] /* output linear array */ ) { /* begin PutVertical */ long z; for (z = 0L; z < mri_vol->depth; z++) { MRIsetVoxVal(mri_vol, x, y, z, 0, (float)Line[z]); } return; } /* end PutVertical */
/*--------------------------------------------------------------------------*/ static void PutRow ( MRI *mri_vol, /* output image volume */ long y, /* y coordinate of the selected line */ long z, /* Slice number of the line */ double *Line /* input linear array */ ) { /* begin PutRow */ long x; for (x = 0L; x < mri_vol->width; x++) { MRIsetVoxVal(mri_vol, x, y, z, 0, (float)Line[x]); } } /* end PutRow */
/*--------------------------------------------------------------------------*/ static void PutColumn ( MRI *mri_vol, /* output image volume */ long x, /* x coordinate of the selected line */ long z, /* Slice number of the line */ double Line[] /* input linear array */ ) { /* begin PutColumn */ long y; for (y = 0L; y < mri_vol->height; y++) { MRIsetVoxVal(mri_vol, x, y, z, 0, (float)Line[y]); } } /* end PutColumn */
static MRI * MRIsynthesizeWithFAF(MRI *mri_T1, MRI *mri_PD, MRI *mri_dst, double TR, double alpha, double TE, int nfaf, float *faf_coefs[3][2]) { int x, y, z, width, height, depth, n ; Real flash, T1, PD ; double xb, yb, zb, x0, y0, z0, w0x, w0y, w0z ; x0 = mri_T1->width/2 ; y0 = mri_T1->height/2 ; z0 = mri_PD->depth/2 ; w0x = 2/x0 ; w0y = 2/y0 ; w0z = 2/z0 ; if (!mri_dst) mri_dst = MRIclone(mri_T1, NULL) ; mri_dst->tr = TR ; mri_dst->flip_angle = alpha ; mri_dst->te = TE ; mri_dst->ti = 0 ; width = mri_T1->width ; height = mri_T1->height ; depth = mri_T1->depth ; for (x = 0 ; x < width ; x++) { for (xb = 1.0, n=1 ; n <= nfaf ; n++) xb += faf_coefs[0][0][n-1] * cos(w0x*n*(x-x0)) + faf_coefs[0][1][n-1] * sin(w0x*n*(x-x0)) ; for (y = 0 ; y < height ; y++) { for (yb = 1.0, n=1 ; n <= nfaf ; n++) yb += faf_coefs[1][0][n-1] * cos(w0y*n*(y-y0)) + faf_coefs[1][1][n-1] * sin(w0y*n*(y-y0)) ; for (z = 0 ; z < depth ; z++) { for (zb = 1.0, n=1 ; n <= nfaf ; n++) zb += faf_coefs[2][0][n-1] * cos(w0z*n*(z-z0)) + faf_coefs[2][1][n-1] * sin(w0z*n*(z-z0)) ; if (x == Gx && y == Gy && z == Gz) DiagBreak() ; MRIsampleVolume(mri_T1, x, y, z, &T1) ; if (T1 <= 0) T1 = 1 ; if (T1 < 900 && T1 > 600) DiagBreak() ; MRIsampleVolume(mri_PD, x, y, z, &PD) ; flash = FLASHforwardModel(T1, PD, TR, xb*yb*zb*alpha, TE) ; MRIsetVoxVal(mri_dst, x, y, z, 0, flash) ; } } } return(mri_dst) ; }
/* figure out what to do with voxels that were turned 'off' by the topology correction. This is a hack, but for now just make them the most likely of the nbr voxel labels. */ static int resegment_erased_voxels(MRI *mri_T1, MRI *mri_in, MRI *mri_out, int target_label) { int x, y, z, label_in, label_out, xi, yi, zi, xk, yk, zk, label, changed=0 ; HISTOGRAM *histos[MAX_CMA_LABEL+1] ; double p, max_p, val ; build_label_histograms(mri_in, mri_T1, histos) ; for (x = 0 ; x < mri_in->width ; x++) { for (y = 0 ; y < mri_in->height ; y++) { for (z = 0 ; z < mri_in->depth ; z++) { label_in = nint(MRIgetVoxVal(mri_in, x, y, z, 0)) ; label_out = nint(MRIgetVoxVal(mri_out, x, y, z, 0)) ; if (label_in == target_label) { // find most likely nbr label max_p = 0 ; label_out = label_in ; for (xk = -1 ; xk <= 1 ; xk++) { xi = x + xk ; if (xi < 0 || xi >= mri_in->width) continue ; for (yk = -1 ; yk <= 1 ; yk++) { yi = y + yk ; if (yi < 0 || yi >= mri_in->height) continue ; for (zk = -1 ; zk <= 1 ; zk++) { zi = z + zk ; if (zi < 0 || zi >= mri_in->depth) continue ; label = nint(MRIgetVoxVal(mri_in, xi, yi, zi, 0)) ; if (label == label_in) continue ; // would be topologically incorrect val = MRIgetVoxVal(mri_T1, xi, yi, zi, 0) ; p = HISTOvalToCount(histos[label], val) ; if (p > max_p) { max_p = p ; label_out = label ; } } } } changed++ ; MRIsetVoxVal(mri_out, x, y, z, 0, label_out) ; } } } } printf("%d voxels resegmented to be ML\n", changed) ; return(NO_ERROR) ; }
static MRI * apply_bias(MRI *mri_orig, MRI *mri_norm, MRI *mri_bias) { MATRIX *m_vox2vox; VECTOR *v1, *v2; int x, y, z ; double xd, yd, zd, bias, val_orig, val_norm ; if (mri_norm == NULL) mri_norm = MRIclone(mri_orig, NULL) ; m_vox2vox = MRIgetVoxelToVoxelXform(mri_orig, mri_bias) ; v1 = VectorAlloc(4, MATRIX_REAL); v2 = VectorAlloc(4, MATRIX_REAL); VECTOR_ELT(v1, 4) = 1.0 ; VECTOR_ELT(v2, 4) = 1.0 ; for (x = 0 ; x < mri_orig->width ; x++) { V3_X(v1) = x ; for (y = 0 ; y < mri_orig->height ; y++) { V3_Y(v1) = y ; for (z = 0 ; z < mri_orig->depth ; z++) { V3_Z(v1) = z ; if (x == Gx && y == Gy && z == Gz) DiagBreak() ; val_orig = MRIgetVoxVal(mri_orig, x, y, z, 0) ; MatrixMultiply(m_vox2vox, v1, v2) ; xd = V3_X(v2) ; yd = V3_Y(v2) ; zd = V3_Z(v2); MRIsampleVolume(mri_bias, xd, yd, zd, &bias) ; val_norm = val_orig * bias ; if (mri_norm->type == MRI_UCHAR) { if (val_norm > 255) val_norm = 255 ; else if (val_norm < 0) val_norm = 0 ; } MRIsetVoxVal(mri_norm, x, y, z, 0, val_norm) ; } } } MatrixFree(&m_vox2vox) ; VectorFree(&v1) ; VectorFree(&v2) ; return(mri_norm) ; }
static int remap_T1(MRI *mri_T1, float mean, float scale) { int x, y, z ; float val ; for (x = 0 ; x < mri_T1->width ; x++) { for (y = 0 ; y < mri_T1->height ; y++) { for (z = 0 ; z < mri_T1->depth ; z++) { if (x == Gx && y == Gy && z == Gz) DiagBreak() ; val = (float)MRIgetVoxVal(mri_T1, x, y, z,0) ; val = mean * (tanh(scale * (val-mean))+1.5) ; MRIsetVoxVal(mri_T1, x, y, z,0, val) ; } } } return(NO_ERROR) ; }
int MRIsetSegmentValue(MRI *mri, MRI_SEGMENTATION *mriseg, int s, float val) { int v, x, y, z ; MRI_SEGMENT *mseg ; mseg = &mriseg->segments[s] ; for (v = 0 ; v < mseg->nvoxels ; v++) { x = mseg->voxels[v].x ; y = mseg->voxels[v].y ; z = mseg->voxels[v].z ; MRIsetVoxVal(mri, x, y, z,0, val) ; } return(NO_ERROR) ; }
MRI * MRIremoveFilledBrightStuff(MRI *mri_T1, MRI *mri_labeled, MRI *mri_dst, int filled_label, float thresh) { int x, y, z, width, height, depth, nwhite, ntested, nchanged ; BUFTYPE val ; float intensity_thresh ; if (!mri_dst) { mri_dst = MRIcopy(mri_labeled, NULL) ; } width = mri_T1->width ; height = mri_T1->height ; depth = mri_T1->depth ; ntested = nchanged = 0 ; for (z = 0 ; z < depth ; z++) { for (y = 0 ; y < height ; y++) { for (x = 0 ; x < width ; x++) { val = MRIgetVoxVal(mri_T1, x, y, z, 0) ; ntested++ ; if (MRIgetVoxVal(mri_labeled, x, y, z, 0) == filled_label && val > thresh) { MRIsetVoxVal(mri_labeled, x, y, z, 0) ; nchanged++ ; } } } } if (Gdiag & DIAG_SHOW) { fprintf(stderr, " %8d voxels tested (%2.2f%%)\n", ntested, 100.0f*(float)ntested/ (float)(width*height*depth)); fprintf(stderr, " %8d voxels changed (%2.2f%%)\n", nchanged, 100.0f*(float)nchanged/ (float)(width*height*depth)); } return(mri_dst) ; }
static MRI * MRIsynthesize(MRI *mri_T1, MRI *mri_PD, MRI *mri_T2star, MRI *mri_dst, double TR, double alpha, double TE) { int x, y, z, width, height, depth ; Real flash, T1, PD ; if (!mri_dst) mri_dst = MRIclone(mri_T1, NULL) ; mri_dst->tr = TR ; mri_dst->flip_angle = alpha ; mri_dst->te = TE ; mri_dst->ti = 0 ; width = mri_T1->width ; height = mri_T1->height ; depth = mri_T1->depth ; for (x = 0 ; x < width ; x++) { for (y = 0 ; y < height ; y++) { for (z = 0 ; z < depth ; z++) { if (x == Gx && y == Gy && z == Gz) DiagBreak() ; MRIsampleVolume(mri_T1, x, y, z, &T1) ; if (T1 <= 0) T1 = 1 ; if (T1 < 900 && T1 > 600) DiagBreak() ; MRIsampleVolume(mri_PD, x, y, z, &PD) ; if (mri_T2star) { Real T2star ; MRIsampleVolume(mri_T2star, x, y, z, &T2star) ; flash = FLASHforwardModelT2star(T1, PD, T2star, TR, alpha, TE) ; } else flash = FLASHforwardModel(T1, PD, TR, alpha, TE) ; MRIsetVoxVal(mri_dst, x, y, z, 0, flash) ; if (!finite(flash)) DiagBreak() ; } } } return(mri_dst) ; }
static int saturate_PD(MRI *mri, float PDsat) { int x,y , z ; float mx, mn, val ; printf("saturating PD (%2.3f)\n", PDsat) ; MRIvalRange(mri, &mn, &mx) ; for (x = 0 ; x < mri->width ; x++) { for (y = 0 ; y < mri->height ; y++) { for (z = 0 ; z < mri->depth ; z++) { val = MRIgetVoxVal(mri, x, y, z, 0) ; val = 1000 * tanh(val / (PDsat * (mx-mn))) ; MRIsetVoxVal(mri, x, y, z, 0, val) ; } } } return(NO_ERROR) ; }