static int register_mri(MRI *mri_in, MRI *mri_ref, MORPH_PARMS *parms) { MRI *mri_in_red, *mri_ref_red ; mri_in_red = MRIreduceByte(mri_in, NULL) ; mri_ref_red = MRIreduceMeanAndStdByte(mri_ref,NULL); /* parms->write_iterations = 0 ; */ if (!parms->niterations) parms->niterations = 1000 ; if (transform_loaded) /* don't recompute rotation based on neck */ { if (MRIfindNeck(mri_in_red, mri_in_red, thresh_low, thresh_hi, NULL, -1,NULL) == NULL) ErrorExit(Gerror, "%s: could not find subject neck.\n", Progname) ; if (MRIfindNeck(mri_ref_red, mri_ref_red, thresh_low, thresh_hi, NULL,1, NULL) == NULL) ErrorExit(Gerror, "%s: could not find neck in reference volume.\n", Progname) ; } else { if (MRIfindNeck(mri_in_red, mri_in_red, thresh_low, thresh_hi, parms, -1, &parms->in_np) == NULL) ErrorExit(Gerror, "%s: could not find subject neck.\n", Progname) ; if (MRIfindNeck(mri_ref_red, mri_ref_red, thresh_low, thresh_hi, parms, 1, &parms->ref_np) == NULL) ErrorExit(Gerror, "%s: could not find neck in reference volume.\n", Progname) ; } if (full_res) {} else { parms->mri_ref = mri_ref_red ; parms->mri_in = mri_in_red ; /* for diagnostics */ } while (parms->lta->num_xforms < num_xforms) LTAdivide(parms->lta, mri_in_red) ; fprintf(stderr,"computing %d linear transformation%s...\n", parms->lta->num_xforms, parms->lta->num_xforms>1?"s":""); MRIlinearAlign(mri_in_red, mri_ref_red, parms) ; MRIfree(&mri_in_red) ; MRIfree(&mri_ref_red) ; return(NO_ERROR) ; }
static MRI * align_with_average(MRI *mri_src, MRI *mri_avg) { MRI *mri_aligned, *mri_in_red, *mri_ref_red ; MRI *mri_in_windowed, *mri_ref_windowed, *mri_in_tmp, *mri_ref_tmp ; int i ; MATRIX *m_L ; printf("initializing alignment using PCA...\n") ; if (Gdiag & DIAG_WRITE) { MRIwriteImageViews(mri_avg, "ref", 400) ; MRIwriteImageViews(mri_src, "before_pca", 400) ; } m_L = align_pca(mri_src, mri_avg) ; if (Gdiag & DIAG_SHOW) { printf("initial transform:\n") ; MatrixPrint(stdout, m_L) ; } if (Gdiag & DIAG_WRITE) { if (sinc_flag) mri_aligned = MRIsincTransform(mri_src, NULL, m_L,sinchalfwindow) ; else mri_aligned = MRIlinearTransform(mri_src, NULL, m_L) ; MRIwriteImageViews(mri_aligned, "after_pca", 400) ; MRIfree(&mri_aligned) ; } printf("aligning volume with average...\n") ; if (window_flag) { mri_in_windowed = MRIwindow(mri_src, NULL, WINDOW_HANNING,127,127,127,100.0f); mri_ref_windowed = MRIwindow(mri_avg,NULL,WINDOW_HANNING,127,127,127,100.0f); mri_src = mri_in_windowed ; mri_avg = mri_ref_windowed ; } MRIscaleMeanIntensities(mri_src, mri_avg, mri_src); mri_in_red = mri_in_tmp = MRIcopy(mri_src, NULL) ; mri_ref_red = mri_ref_tmp = MRIcopy(mri_avg, NULL) ; for (i = 0 ; i < nreductions ; i++) { mri_in_red = MRIreduceByte(mri_in_tmp, NULL) ; mri_ref_red = MRIreduceByte(mri_ref_tmp,NULL); MRIfree(&mri_in_tmp); MRIfree(&mri_ref_tmp) ; mri_in_tmp = mri_in_red ; mri_ref_tmp = mri_ref_red ; } parms.mri_ref = mri_avg ; parms.mri_in = mri_src ; /* for diagnostics */ MRIrigidAlign(mri_in_red, mri_ref_red, &parms, m_L) ; printf("transforming input volume...\n") ; MatrixPrint(stderr, parms.lta->xforms[0].m_L) ; printf("\n") ; if (sinc_flag) mri_aligned = MRIsincTransform(mri_src, NULL, parms.lta->xforms[0].m_L,sinchalfwindow) ; else mri_aligned = MRIlinearTransform(mri_src, NULL, parms.lta->xforms[0].m_L) ; if (Gdiag & DIAG_WRITE) MRIwriteImageViews(mri_aligned, "after_alignment", 400) ; MRIfree(&mri_in_red) ; MRIfree(&mri_ref_red) ; return(mri_aligned) ; }
int main(int argc, char *argv[]) { char *ref_fname, *in_fname, *out_fname, fname[STRLEN], **av ; MRI *mri_ref, *mri_in, *mri_orig, *mri_in_red, *mri_ref_red, *mri_in_tmp, *mri_ref_tmp, *mri_ref_orig, *mri_in_orig ; int ac, nargs, i, msec, minutes, seconds ; struct timeb start ; MATRIX *m_L ; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mri_linear_register.c,v 1.13 2011/03/02 00:04:22 nicks Exp $", "$Name: stable5 $"); if (nargs && argc - nargs == 1) exit (0); argc -= nargs; parms.mri_crop = NULL ; parms.l_intensity = 1.0f ; parms.niterations = 100 ; parms.levels = -1 ; /* use default */ parms.dt = 1e-6 ; /* was 5e-6 */ parms.tol = INTEGRATION_TOL*5 ; parms.dt = 5e-6 ; /* was 5e-6 */ parms.tol = 1e-3 ; parms.momentum = 0.8 ; parms.max_levels = MAX_LEVELS ; parms.factor = 1.0 ; parms.niterations = 25 ; Progname = argv[0] ; DiagInit(NULL, NULL, NULL) ; ErrorInit(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) ErrorExit(ERROR_BADPARM, "usage: %s <in brain> <template> <output file name>\n", Progname) ; in_fname = argv[1] ; ref_fname = argv[2] ; if (xform_mean_fname) { int sno, nsubjects ; FILE *fp ; parms.m_xform_mean = MatrixAsciiRead(xform_mean_fname, NULL) ; if (!parms.m_xform_mean) ErrorExit(Gerror, "%s: could not read parameter means from %s", Progname, xform_mean_fname) ; fp = fopen(xform_covariance_fname, "r") ; if (!fp) ErrorExit(ERROR_NOFILE, "%s: could not read covariances from %s", Progname, xform_covariance_fname) ; fscanf(fp, "nsubjects=%d", &nsubjects) ; printf("reading %d transforms...\n", nsubjects) ; parms.m_xforms = (MATRIX **)calloc(nsubjects, sizeof(MATRIX *)) ; if (!parms.m_xforms) ErrorExit(ERROR_NOMEMORY, "%s: could not allocate array of %d xforms", Progname, nsubjects) ; for (sno = 0 ; sno < nsubjects ; sno++) { parms.m_xforms[sno] = MatrixAsciiReadFrom(fp, NULL) ; if (!parms.m_xforms[sno]) ErrorExit(ERROR_NOMEMORY, "%s: could not allocate %dth xform", Progname, sno) ; } parms.m_xform_covariance = MatrixAsciiReadFrom(fp, NULL) ; if (!parms.m_xform_covariance) ErrorExit(Gerror, "%s: could not read parameter covariance from %s", Progname, xform_covariance_fname) ; fclose(fp) ; parms.l_priors = l_priors ; parms.nxforms = nsubjects ; } out_fname = argv[3] ; FileNameOnly(out_fname, fname) ; FileNameRemoveExtension(fname, fname) ; strcpy(parms.base_name, fname) ; fprintf(stderr, "logging results to %s.log\n", parms.base_name) ; TimerStart(&start) ; fprintf(stderr, "reading '%s'...\n", ref_fname) ; fflush(stderr) ; mri_ref = MRIread(ref_fname) ; if (!mri_ref) ErrorExit(ERROR_NOFILE, "%s: could not open reference volume %s.\n", Progname, ref_fname) ; if (mri_ref->type != MRI_UCHAR) { MRI *mri_tmp ; mri_tmp = MRIchangeType(mri_ref, MRI_UCHAR, 0.0, 0.999, FALSE) ; MRIfree(&mri_ref) ; mri_ref = mri_tmp ; } if (var_fname) /* read in a volume of standard deviations */ { MRI *mri_var, *mri_tmp ; fprintf(stderr, "reading '%s'...\n", var_fname) ; mri_var = MRIread(var_fname) ; if (!mri_var) ErrorExit(ERROR_NOFILE, "%s: could not open variance volume %s.\n", Progname, var_fname) ; mri_tmp = MRIconcatenateFrames(mri_ref, mri_var, NULL) ; MRIfree(&mri_var) ; MRIfree(&mri_ref) ; mri_ref = mri_tmp ; } fprintf(stderr, "reading '%s'...\n", in_fname) ; fflush(stderr) ; mri_orig = mri_in = MRIread(in_fname) ; if (!mri_in) ErrorExit(ERROR_NOFILE, "%s: could not open input volume %s.\n", Progname, in_fname) ; if (mri_in->type != MRI_UCHAR) { MRI *mri_tmp ; mri_orig = mri_tmp = MRIchangeType(mri_in, MRI_UCHAR, 0.0, 0.999, FALSE) ; MRIfree(&mri_in) ; mri_in = mri_tmp ; } /* make sure they are the same size */ if (mri_in->width != mri_ref->width || mri_in->height != mri_ref->height || mri_in->depth != mri_ref->depth) { int width, height, depth ; MRI *mri_tmp ; width = MAX(mri_in->width, mri_ref->width) ; height = MAX(mri_in->height, mri_ref->height) ; depth = MAX(mri_in->depth, mri_ref->depth) ; mri_tmp = MRIalloc(width, height, depth, MRI_UCHAR) ; MRIextractInto(mri_in, mri_tmp, 0, 0, 0, mri_in->width, mri_in->height, mri_in->depth, 0, 0, 0) ; #if 0 MRIfree(&mri_in) ; #else parms.mri_in = mri_in ; #endif mri_in = mri_orig = mri_tmp ; mri_tmp = MRIallocSequence(width, height,depth,MRI_UCHAR,mri_ref->nframes); MRIextractInto(mri_ref, mri_tmp, 0, 0, 0, mri_ref->width, mri_ref->height, mri_ref->depth, 0, 0, 0) ; #if 0 MRIfree(&mri_ref) ; #else parms.mri_in = mri_in ; #endif mri_ref = mri_tmp ; } if (!FZERO(tx) || !FZERO(ty) || !FZERO(tz)) { MRI *mri_tmp ; fprintf(stderr, "translating second volume by (%2.1f, %2.1f, %2.1f)\n", tx, ty, tz) ; mri_tmp = MRItranslate(mri_in, NULL, tx, ty, tz) ; MRIfree(&mri_in) ; mri_in = mri_tmp ; } if (!FZERO(rzrot)) { MRI *mri_tmp ; fprintf(stderr, "rotating second volume by %2.1f degrees around Z axis\n", (float)DEGREES(rzrot)) ; mri_tmp = MRIrotateZ_I(mri_in, NULL, rzrot) ; MRIfree(&mri_in) ; mri_in = mri_tmp ; } if (!FZERO(rxrot)) { MRI *mri_tmp ; fprintf(stderr, "rotating second volume by %2.1f degrees around X axis\n", (float)DEGREES(rxrot)) ; mri_tmp = MRIrotateX_I(mri_in, NULL, rxrot) ; MRIfree(&mri_in) ; mri_in = mri_tmp ; } if (!FZERO(ryrot)) { MRI *mri_tmp ; fprintf(stderr, "rotating second volume by %2.1f degrees around Y axis\n", (float)DEGREES(ryrot)) ; mri_tmp = MRIrotateY_I(mri_in, NULL, ryrot) ; MRIfree(&mri_in) ; mri_in = mri_tmp ; } if (!transform_loaded) /* wasn't preloaded */ parms.lta = LTAalloc(1, mri_in) ; if (!FZERO(blur_sigma)) { MRI *mri_kernel, *mri_tmp ; mri_kernel = MRIgaussian1d(blur_sigma, 100) ; mri_tmp = MRIconvolveGaussian(mri_in, NULL, mri_kernel) ; mri_in = mri_tmp ; MRIfree(&mri_kernel) ; } MRIscaleMeanIntensities(mri_in, mri_ref, mri_in); mri_ref_orig = mri_ref ; mri_in_orig = mri_in ; if (nreductions > 0) { mri_in_red = mri_in_tmp = MRIcopy(mri_in, NULL) ; mri_ref_red = mri_ref_tmp = MRIcopy(mri_ref, NULL) ; for (i = 0 ; i < nreductions ; i++) { mri_in_red = MRIreduceByte(mri_in_tmp, NULL) ; mri_ref_red = MRIreduceMeanAndStdByte(mri_ref_tmp,NULL); MRIfree(&mri_in_tmp); MRIfree(&mri_ref_tmp) ; mri_in_tmp = mri_in_red ; mri_ref_tmp = mri_ref_red ; } mri_in = mri_in_red ; mri_ref = mri_ref_red ; } /* for diagnostics */ if (full_res) { parms.mri_ref = mri_ref ; parms.mri_in = mri_in ; } else { parms.mri_ref = mri_ref_orig ; parms.mri_in = mri_in_orig ; } m_L = initialize_transform(mri_in, mri_ref, &parms) ; if (use_gradient) { MRI *mri_in_mag, *mri_ref_mag, *mri_grad, *mri_mag ; printf("computing gradient magnitude of input image...\n") ; mri_mag = MRIalloc(mri_in->width, mri_in->height, mri_in->depth,MRI_FLOAT); MRIcopyHeader(mri_in, mri_mag) ; mri_grad = MRIsobel(mri_in, NULL, mri_mag) ; MRIfree(&mri_grad) ; /* convert it to ubytes */ MRIvalScale(mri_mag, mri_mag, 0.0f, 255.0f) ; mri_in_mag = MRIclone(mri_in, NULL) ; MRIcopy(mri_mag, mri_in_mag) ; MRIfree(&mri_mag) ; /* now compute gradient of ref image */ printf("computing gradient magnitude of reference image...\n") ; mri_mag = MRIalloc(mri_ref->width, mri_ref->height, mri_ref->depth,MRI_FLOAT); MRIcopyHeader(mri_ref, mri_mag) ; mri_grad = MRIsobel(mri_ref, NULL, mri_mag) ; MRIfree(&mri_grad) ; /* convert it to ubytes */ MRIvalScale(mri_mag, mri_mag, 0.0f, 255.0f) ; mri_ref_mag = MRIclone(mri_ref, NULL) ; MRIcopy(mri_mag, mri_ref_mag) ; MRIfree(&mri_mag) ; register_mri(mri_in_mag, mri_ref_mag, &parms, m_L) ; MRIfree(&mri_in_mag) ; MRIfree(&mri_ref_mag) ; } register_mri(mri_in, mri_ref, &parms, m_L) ; if (check_crop_flag) /* not working yet! */ { printf("searching for cropped regions in the input image...\n") ; parms.mri_crop = find_cropping(mri_orig, mri_ref, &parms) ; MRIwrite(parms.mri_crop, "crop.mgh") ; register_mri(mri_in, mri_ref, &parms, m_L) ; } if (voxel_coords) { printf("transforming xform to voxel coordinates...\n") ; MRIrasXformToVoxelXform(mri_in_orig, mri_ref_orig, parms.lta->xforms[0].m_L, parms.lta->xforms[0].m_L); if (Gdiag & DIAG_WRITE) { MRI *mri_tmp ; mri_tmp = MRIlinearTransform(mri_in_orig, NULL,parms.lta->xforms[0].m_L); MRIwriteImageViews(mri_tmp, "morphed", IMAGE_SIZE) ; MRIfree(&mri_tmp) ; } } // save src and target info in lta getVolGeom(mri_in_orig, &parms.lta->xforms[0].src); getVolGeom(mri_ref_orig, &parms.lta->xforms[0].dst); fprintf(stderr, "writing output transformation to %s...\n", out_fname) ; if (invert_flag) { MATRIX *m_tmp ; m_tmp = MatrixInverse(parms.lta->xforms[0].m_L, NULL) ; MatrixFree(&parms.lta->xforms[0].m_L) ; // change src and dst getVolGeom(mri_in_orig, &parms.lta->xforms[0].dst); getVolGeom(mri_ref_orig, &parms.lta->xforms[0].src); parms.lta->xforms[0].m_L = m_tmp ; } // LTAwriteEx(parms.lta, out_fname) ; // if (mri_ref) MRIfree(&mri_ref) ; if (mri_in) MRIfree(&mri_in) ; msec = TimerStop(&start) ; seconds = nint((float)msec/1000.0f) ; minutes = seconds / 60 ; seconds = seconds % 60 ; fprintf(stderr, "registration took %d minutes and %d seconds.\n", minutes, seconds) ; exit(0) ; return(0) ; }