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) ; }
static int normalize_timepoints(MRI *mri, double thresh, double cross_time_sigma) { int frame, x, y, z, skip, nvox ; double target, val ; MRI *mri_ctrl, *mri_bias, *mri_target, *mri_frame, *mri_kernel ; mri_ctrl = MRIcloneDifferentType(mri, MRI_UCHAR) ; mri_bias = MRIcloneDifferentType(mri, MRI_FLOAT) ; mri_target = MRIcloneDifferentType(mri, MRI_FLOAT) ; mri_kernel = MRIgaussian1d(cross_time_sigma, -1) ; for (nvox = 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 (target = 0.0, frame = 0 ; frame < mri->nframes ; frame++) target += MRIgetVoxVal(mri, x, y, z, frame) ; target /= mri->nframes ; if (FZERO(target)) continue ; // both vals 0 skip = 0 ; for (frame = 0 ; frame < mri->nframes ; frame++) { val = MRIgetVoxVal(mri, x, y, z, frame) ; if (fabs(val-target) > thresh) { skip = 1 ; break ; } } if (skip) continue ; nvox++ ; MRIsetVoxVal(mri_ctrl, x, y, z, 0, CONTROL_MARKED) ; MRIsetVoxVal(mri_target, x, y, z, 0, target) ; } printf("%d voxels found to base intensity correction on\n", nvox) ; // 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 (x = 0 ; x < mri->width ; x++) for (y = 0 ; y < mri->height ; y++) for (z = 0 ; z < mri->depth ; 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) ; MRIconvolveGaussian(mri_bias, mri_bias, mri_kernel) ; // 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_kernel) ; MRIfree(&mri_target) ; MRIfree(&mri_ctrl) ; return(NO_ERROR) ; }
static int write_surface_warp_into_volume(MRI_SURFACE *mris, MRI *mri, int niter) { int vno, xvi, yvi, zvi, frame ; VERTEX *v ; double dx, dy, dz, xv, yv, zv, xv1, yv1, zv1 ; MRI *mri_weights, *mri_ctrl, *mri_frame ; float wt ; mri_weights = MRIallocSequence(mri->width, mri->height, mri->depth, MRI_FLOAT, 1) ; mri_ctrl = MRIallocSequence(mri->width, mri->height, mri->depth, MRI_UCHAR, 1) ; MRIcopyHeader(mri, mri_weights) ; MRIcopyHeader(mri, mri_ctrl) ; // build a 3 frame volume with the voxel-coords warp (dx, dy, dz) in frames 0, 1 and 2 respectively for (vno = 0 ; vno < mris->nvertices ; vno++) { v = &mris->vertices[vno] ; if (v->ripflag) continue ; MRISsurfaceRASToVoxelCached(mris, mri, v->origx, v->origy, v->origz, &xv, &yv, &zv) ; MRISsurfaceRASToVoxelCached(mris, mri, v->x, v->y, v->z, &xv1, &yv1, &zv1) ; dx = xv1-xv ; dy = yv1-yv ; dz = zv1-zv ; xvi = nint(xv) ; yvi = nint(yv) ; zvi = nint(zv) ; if (vno == Gdiag_no) { printf("surface vertex %d: inflated (%2.0f, %2.0f, %2.0f), orig (%2.0f, %2.0f, %2.0f), " "dx=(%2.0f, %2.0f, %2.0f)\n", vno, xv1, yv1, zv1, xv, yv, zv, dx, dy, dz) ; DiagBreak() ; } if (xvi < 0 || xvi >= mri->width || yv < 0 || yv >= mri->height || zv < 0 || zv >= mri->depth) { continue ; } MRIinterpolateIntoVolumeFrame(mri, xv, yv, zv, 0, dx) ; MRIinterpolateIntoVolumeFrame(mri, xv, yv, zv, 1, dy) ; MRIinterpolateIntoVolumeFrame(mri, xv, yv, zv, 2, dz) ; MRIinterpolateIntoVolume(mri_weights, xv, yv, zv, 1.0) ; } #if 0 // set boundary conditions in the edge planes to be 0 warping for (xvi = 0 ; xvi < mri->width ; xvi++) for (yvi = 0 ; yvi < mri->height ; yvi++) { MRIsetVoxVal(mri_ctrl, xvi, yvi, 0, 0, CONTROL_MARKED) ; MRIsetVoxVal(mri, xvi, yvi, 0, 0, 0) ; MRIsetVoxVal(mri, xvi, yvi, 0, 1, 0) ; MRIsetVoxVal(mri, xvi, yvi, 0, 2, 0) ; MRIsetVoxVal(mri_ctrl, xvi, yvi, mri->depth-1, 0, CONTROL_MARKED) ; MRIsetVoxVal(mri, xvi, yvi, mri->depth-1, 0, 0) ; MRIsetVoxVal(mri, xvi, yvi, mri->depth-1, 1, 0) ; MRIsetVoxVal(mri, xvi, yvi, mri->depth-1, 2, 0) ; } for (xvi = 0 ; xvi < mri->width ; xvi++) for (zvi = 0 ; zvi < mri->depth ; zvi++) { MRIsetVoxVal(mri_ctrl, xvi, 0, zvi, 0, CONTROL_MARKED) ; MRIsetVoxVal(mri, xvi, 0, zvi, 0, 0) ; MRIsetVoxVal(mri, xvi, 0, zvi, 1, 0) ; MRIsetVoxVal(mri, xvi, 0, zvi, 2, 0) ; MRIsetVoxVal(mri_ctrl, xvi, mri->height-1, zvi, 0, CONTROL_MARKED) ; MRIsetVoxVal(mri, xvi, mri->height-1, zvi, 0, 0) ; MRIsetVoxVal(mri, xvi, mri->height-1, zvi, 1, 0) ; MRIsetVoxVal(mri, xvi, mri->height-1, zvi, 2, 0) ; } for (yvi = 0 ; yvi < mri->width ; yvi++) for (zvi = 0 ; zvi < mri->depth ; zvi++) { MRIsetVoxVal(mri_ctrl, 0, yvi, zvi, 0, CONTROL_MARKED) ; MRIsetVoxVal(mri, 0, yvi, zvi, 0, 0) ; MRIsetVoxVal(mri, 0, yvi, zvi, 1, 0) ; MRIsetVoxVal(mri, 0, yvi, zvi, 2, 0) ; MRIsetVoxVal(mri_ctrl, mri->width-1, yvi, zvi, 0, CONTROL_MARKED) ; MRIsetVoxVal(mri, mri->width-1, yvi, zvi, 0, 0) ; MRIsetVoxVal(mri, mri->width-1, yvi, zvi, 1, 0) ; MRIsetVoxVal(mri, mri->width-1, yvi, zvi, 2, 0) ; } #endif // normalize the warp field using a weighted average of all vertices that map to every voxel for (xvi = 0 ; xvi < mri->width ; xvi++) for (yvi = 0 ; yvi < mri->height ; yvi++) for (zvi = 0 ; zvi < mri->depth ; zvi++) { if (xvi == Gx && yvi == Gy && zvi == Gz) DiagBreak() ; wt = MRIgetVoxVal(mri_weights, xvi, yvi, zvi, 0) ; dx = MRIgetVoxVal(mri, xvi, yvi, zvi, 0) ; dy = MRIgetVoxVal(mri, xvi, yvi, zvi, 1) ; dz = MRIgetVoxVal(mri, xvi, yvi, zvi, 2) ; if (FZERO(wt)) continue ; dx /= wt ; dy /= wt ; dz /= wt ; MRIsetVoxVal(mri, xvi, yvi, zvi, 0, dx) ; MRIsetVoxVal(mri, xvi, yvi, zvi, 1, dy) ; MRIsetVoxVal(mri, xvi, yvi, zvi, 2, dz) ; MRIsetVoxVal(mri_ctrl, xvi, yvi, zvi, 0, CONTROL_MARKED) ; // it is a control point } if (Gdiag & DIAG_WRITE) { MRIwrite(mri, "warp0.mgz") ; MRIwrite(mri_ctrl, "ctrl.mgz") ; } for (frame = 0 ; frame < mri->nframes ; frame++) { printf("interpolating frame %d\n", frame+1) ; mri_frame = MRIcopyFrame(mri, NULL, frame, 0) ; MRIbuildVoronoiDiagram(mri_frame, mri_ctrl, mri_frame) ; MRIsoapBubble(mri_frame, mri_ctrl, mri_frame, niter, mri_frame->xsize*.05) ; #if 0 { int x, y, z ; float val ; for (x = 0 ; x < mri_frame->width ; x++) for (y = 0 ; y < mri_frame->height ; y++) for (z = 0 ; z < mri_frame->depth ; z++) { val = MRIgetVoxVal(mri_frame, x, y, z, 0) ; switch (frame) { default: case 0: val += x ; break ; case 1: val += y ; break ; case 2: val += z ; break ; } MRIsetVoxVal(mri_frame, x, y, z, 0, val) ; } } #endif MRIcopyFrame(mri_frame, mri, 0, frame) ; MRIfree(&mri_frame) ; } MRIfree(&mri_weights) ; MRIfree(&mri_ctrl) ; return(NO_ERROR) ; }