int regio_write_surfacexform_to_register_dat(MATRIX *B, char *fname, MRI_SURFACE *mris, MRI *mri, char *subject, int float2int) { MATRIX *Ta, *Sa, *invTa, *A, *R, *S, *invS, *T, *m1, *m2 ; MRI *mri_surf = MRIallocHeader(mris->vg.width, mris->vg.height, mris->vg.depth, MRI_UCHAR,1) ; MRIcopyVolGeomToMRI(mri_surf, &mris->vg) ; T = MRIxfmCRS2XYZtkreg(mri) ; S = MRIgetVoxelToRasXform(mri) ; invS = MatrixInverse(S, NULL) ; Ta = MRIxfmCRS2XYZtkreg(mri_surf); Sa = MRIgetVoxelToRasXform(mri_surf); invTa = MatrixInverse(Ta,NULL); A = MatrixMultiply(Sa,invTa, NULL); m1 = MatrixMultiply(A, B, NULL) ; m2 = MatrixMultiply(invS, m1, NULL) ; R = MatrixMultiply(T, m2, NULL) ; regio_write_register(fname,subject,mri->xsize, mri->zsize,1,R,float2int); MatrixFree(&A) ; MatrixFree(&Ta) ; MatrixFree(&Sa) ; MatrixFree(&invTa) ; MatrixFree(&R) ; MatrixFree(&m1) ; MatrixFree(&m2) ; MatrixFree(&S) ; MatrixFree(&invS); MatrixFree(&T) ; MRIfree(&mri_surf) ; return(NO_ERROR) ; }
static int test(MRI *mri1, MRI *mri2, MRI *mri3, MATRIX *m_vol1_to_vol2_ras) { VECTOR *v_test, *v_vox ; float x_ras1, y_ras1, z_ras1, x_ras2, y_ras2, z_ras2, x_vox1, y_vox1, z_vox1, x_vox2, y_vox2, z_vox2 ; MATRIX *m_vol2_vox2ras, *m_vol2_ras2vox, *m_vol1_ras2vox, *m_vol1_vox2ras, *m_vol3_ras2vox, *m_vol3_vox2ras ; int val ; v_test = VectorAlloc(4, MATRIX_REAL) ; m_vol1_vox2ras = MRIgetVoxelToRasXform(mri1) ; m_vol2_vox2ras = MRIgetVoxelToRasXform(mri2) ; m_vol1_ras2vox = MRIgetRasToVoxelXform(mri1) ; m_vol2_ras2vox = MRIgetRasToVoxelXform(mri2) ; m_vol3_vox2ras = MRIgetVoxelToRasXform(mri3) ; m_vol3_ras2vox = MRIgetRasToVoxelXform(mri3) ; x_ras1 = 126.50 ; y_ras1 = -125.500 ; z_ras1 = 127.50 ; V3_X(v_test) = x_ras1 ; V3_Y(v_test) = y_ras1 ; V3_Z(v_test) = z_ras1 ; *MATRIX_RELT(v_test, 4, 1) = 1.0 ; v_vox = MatrixMultiply(m_vol1_ras2vox, v_test, NULL) ; x_vox1 = V3_X(v_vox) ; y_vox1 = V3_Y(v_vox) ; z_vox1 = V3_Z(v_vox) ; val = MRISvox(mri1, nint(x_vox1), nint(y_vox1), nint(z_vox1)) ; printf("VOL1: ras (%1.1f, %1.1f, %1.1f) --> VOX (%1.1f, %1.1f, %1.1f) = %d\n", x_ras1, y_ras1, z_ras1, x_vox1, y_vox1, z_vox1, val) ; x_ras2 = 76.5421 ; y_ras2 = 138.5352 ; z_ras2 = 96.0910 ; V3_X(v_test) = x_ras2 ; V3_Y(v_test) = y_ras2 ; V3_Z(v_test) = z_ras2 ; *MATRIX_RELT(v_test, 4, 1) = 1.0 ; v_vox = MatrixMultiply(m_vol2_ras2vox, v_test, NULL) ; x_vox2 = V3_X(v_vox) ; y_vox2 = V3_Y(v_vox) ; z_vox2 = V3_Z(v_vox) ; val = MRISvox(mri2, nint(x_vox2), nint(y_vox2), nint(z_vox2)) ; printf("VOL2: ras (%2.1f, %2.1f, %2.1f) --> VOX (%2.1f, %2.1f, %2.1f) = %d\n", x_ras2, y_ras2, z_ras2, x_vox2, y_vox2, z_vox2, val) ; MatrixFree(&v_test) ; return(NO_ERROR) ; }
MATRIX * regio_read_surfacexform_from_register_dat(char *fname, MRI_SURFACE *mris, MRI *mri, char **subject) { MATRIX *Ta, *Sa, *invT, *A, *R, *S, *invSa, *T, *m1, *m2, *B ; float pres, bres, intensity ; int float2int ; MRI *mri_surf = MRIallocHeader(mris->vg.width, mris->vg.height, mris->vg.depth, MRI_UCHAR,1) ; if (regio_read_register(fname, subject, &pres, &bres, &intensity,&B,&float2int) != 0) ErrorReturn(NULL, (ERROR_NOFILE, "regio_read_surfacexform_from_register_dat(%s) failed", fname)) ; MRIcopyVolGeomToMRI(mri_surf, &mris->vg) ; T = MRIxfmCRS2XYZtkreg(mri) ; S = MRIgetVoxelToRasXform(mri) ; Ta = MRIxfmCRS2XYZtkreg(mri_surf); Sa = MRIgetVoxelToRasXform(mri_surf); invSa = MatrixInverse(Sa, NULL) ; invT = MatrixInverse(T,NULL); A = MatrixMultiply(S,invT, NULL); m1 = MatrixMultiply(A, B, NULL) ; m2 = MatrixMultiply(invSa, m1, NULL) ; R = MatrixMultiply(Ta, m2, NULL) ; MatrixFree(&A) ; MatrixFree(&Ta) ; MatrixFree(&Sa) ; MatrixFree(&invT) ; MatrixFree(&B) ; MatrixFree(&m1) ; MatrixFree(&m2) ; MatrixFree(&S) ; MatrixFree(&invSa); MatrixFree(&T) ; MRIfree(&mri_surf) ; return(R) ; }
int main(int argc, char *argv[]) { char **av, *out_name ; int ac, nargs ; int msec, minutes, seconds ; struct timeb start ; GCA_MORPH *gcam ; MRI *mri = NULL ; MATRIX *m; /* rkt: check for and handle version tag */ nargs = handle_version_option (argc, argv, "$Id: mri_warp_convert.c,v 1.1 2012/02/13 23:05:52 jonp Exp $", "$Name: $"); if (nargs && argc - nargs == 1) { exit (0); } argc -= nargs; Progname = basename(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 < 3) { usage_exit(1) ; } // mri_convert expects a relative warp fprintf(stdout, "[%s]: reading warp file '%s'\n", Progname, argv[1]); fprintf(stdout, "assuming RELATIVE warp convention\n"); // TODO: add support for absolute warps as well, add option to specify convention mri = MRIread(argv[1]) ; if (mri == NULL) ErrorExit(ERROR_NOFILE, "%s: could not read warp volume %s\n", Progname,argv[1]) ; m = MRIgetVoxelToRasXform(mri) ; // NOTE: this assumes a standard siemens image orientation in which // case a neurological orientation means that the first frame is // flipped if ( MatrixDeterminant(m) > 0 ) { fprintf(stdout, "non-negative Jacobian determinant -- converting to radiological ordering\n"); } { // 2012/feb/08: tested with anisotropic voxel sizes MRI *mri2 = NULL ; int c=0,r=0,s=0; float v; mri2 = MRIcopy(mri,NULL); for(c=0; c < mri->width; c++) { for(r=0; r < mri->height; r++) { for(s=0; s < mri->depth; s++) { // only flip first frame (by negating relative shifts) v = MRIgetVoxVal(mri, c,r,s,0) / mri->xsize; if ( MatrixDeterminant(m) > 0 ) MRIsetVoxVal( mri2,c,r,s,0,-v); else MRIsetVoxVal( mri2,c,r,s,0, v); v = MRIgetVoxVal(mri, c,r,s,1) / mri->ysize; MRIsetVoxVal( mri2,c,r,s,1, v); v = MRIgetVoxVal(mri, c,r,s,2) / mri->zsize; MRIsetVoxVal( mri2,c,r,s,2, v); } } } MRIfree(&mri); mri = mri2; } MatrixFree(&m) ; // this does all the work! (gcamorph.c) gcam = GCAMalloc(mri->width, mri->height, mri->depth) ; GCAMinitVolGeom(gcam, mri, mri) ; // not sure if removing singularities is ever a bad thing #if 1 GCAMremoveSingularitiesAndReadWarpFromMRI(gcam, mri) ; #else GCAMreadWarpFromMRI(gcam, mri) ; #endif fprintf(stdout, "[%s]: writing warp file '%s'\n", Progname, argv[2]); out_name = argv[2] ; GCAMwrite(gcam, out_name) ; msec = TimerStop(&start) ; seconds = nint((float)msec/1000.0f) ; minutes = seconds / 60 ; seconds = seconds % 60 ; fprintf(stderr, "conversion took %d minutes and %d seconds.\n", minutes, seconds) ; exit(0) ; return(0) ; }