int main( int ac, char* av[] ) { int N; VIO_General_transform xfm; if ( ac != 3 && ac != 4 ) { fprintf( stderr, "usage: %s N transform.xfm [tolerance]\n", av[0] ); return 1; } N = atoi( av[1] ); if ( input_transform_file( av[2], &xfm ) != VIO_OK ) { fprintf( stderr, "Failed to load transform '%s'\n", av[2] ); return 2; } if ( ac == 4 ) { tolerance = atof( av[3] ); printf( "Setting tolerance to %f.\n", tolerance ); } while (N-- > 0) { VIO_Real x = 500.0 * ( drand48() - 0.5 ); VIO_Real y = 500.0 * ( drand48() - 0.5 ); VIO_Real z = 500.0 * ( drand48() - 0.5 ); VIO_Real tx,ty,tz; VIO_Real a,b,c; general_transform_point( &xfm, x,y,z, &tx,&ty,&tz ); /* Check that general_inverse_transform_point() and invert_general_transform() behave sensibly. */ general_inverse_transform_point( &xfm, tx,ty,tz, &a,&b,&c ); assert_equal_point( x,y,z, a,b,c, "general_inverse_transform_point()" ); invert_general_transform( &xfm ); general_transform_point( &xfm, tx,ty,tz, &a,&b,&c ); assert_equal_point( x,y,z, a,b,c, "general_transform_point() / inverted xfm" ); general_inverse_transform_point( &xfm, x,y,z, &a,&b,&c ); assert_equal_point( tx,ty,tz, a,b,c, "general_inverse_transform_point() / inverted xfm" ); } return 0; }
/* Build the target lattice by transforming the source points through the current non-linear transformation stored in: Glinear_transform and Gsuper_d{x,y,z} deformation volumes both input (px,py,pz) and output (tx,ty,tz) coordinate lists are in WORLD COORDINATES */ void build_target_lattice_using_super_sampled_def( float px[], float py[], float pz[], float tx[], float ty[], float tz[], int len, int dim) { int i,j, sizes[VIO_MAX_DIMENSIONS], xyzv[VIO_MAX_DIMENSIONS]; VIO_Real def_vector[VIO_N_DIMENSIONS], voxel[VIO_MAX_DIMENSIONS], x,y,z; long index[VIO_MAX_DIMENSIONS]; get_volume_sizes(Gsuper_sampled_vol,sizes); get_volume_XYZV_indices(Gsuper_sampled_vol,xyzv); for(i=1; i<=len; i++) { /* apply linear part of the transformation */ general_transform_point(Glinear_transform, (VIO_Real)px[i], (VIO_Real)py[i], (VIO_Real)pz[i], &x, &y, &z); /* now get the non-linear part, using nearest neighbour interpolation in the super-sampled deformation volume. */ convert_world_to_voxel(Gsuper_sampled_vol, x,y,z, voxel); if ((voxel[ xyzv[VIO_X] ] >= -0.5) && (voxel[ xyzv[VIO_X] ] < sizes[xyzv[VIO_X]]-0.5) && (voxel[ xyzv[VIO_Y] ] >= -0.5) && (voxel[ xyzv[VIO_Y] ] < sizes[xyzv[VIO_Y]]-0.5) && (voxel[ xyzv[VIO_Z] ] >= -0.5) && (voxel[ xyzv[VIO_Z] ] < sizes[xyzv[VIO_Z]]-0.5) ) { for(j=0; j<3; j++) index[ xyzv[j] ] = (long) (voxel[ xyzv[j] ]+0.5); for(index[xyzv[VIO_Z+1]]=0; index[xyzv[VIO_Z+1]]<sizes[xyzv[VIO_Z+1]]; index[xyzv[VIO_Z+1]]++) GET_VALUE_4D(def_vector[ index[ xyzv[VIO_Z+1] ] ], \ Gsuper_sampled_vol, \ index[0], index[1], index[2], index[3]); x += def_vector[VIO_X]; y += def_vector[VIO_Y]; z += def_vector[VIO_Z]; } tx[i] = (float)x; ty[i] = (float)y; tz[i] = (float)z; } }
/* Build the target lattice by transforming the source points through the current non-linear transformation stored in: Gglobals->trans_info.transformation both input (px,py,pz) and output (tx,ty,tz) coordinate lists are in WORLD COORDINATES */ void build_target_lattice(float px[], float py[], float pz[], float tx[], float ty[], float tz[], int len, int dim) { int i; VIO_Real x,y,z; for(i=1; i<=len; i++) { general_transform_point(Gglobals->trans_info.transformation, (VIO_Real)px[i],(VIO_Real) py[i], (VIO_Real)pz[i], &x, &y, &z); tx[i] = (float)x; ty[i] = (float)y; tz[i] = (float)z; } }
int main(int argc, char *argv[]) { int v1, v2, v3, v4; int sizes[VIO_MAX_DIMENSIONS], grid_sizes[4]; int n_concat_transforms, i; VIO_STR arg_string; char *input_volume_name; char *input_xfm; VIO_STR outfile; VIO_Real w1, w2, w3; VIO_Real nw1, nw2, nw3; VIO_Real original[3], transformed[3]; VIO_Real value; VIO_Real cosine[3]; VIO_Real original_separation[3], grid_separation[4]; VIO_Real original_starts[3], grid_starts[4]; VIO_Volume eval_volume, new_grid; VIO_General_transform xfm, *voxel_to_world; VIO_STR *dimnames, dimnames_grid[4]; VIO_progress_struct progress; arg_string = time_stamp(argc, argv); /* Check arguments */ if(ParseArgv(&argc, argv, argTable, 0) || (argc != 4)){ fprintf(stderr, "\nUsage: %s [options] input.mnc input.xfm output_grid.mnc\n", argv[0]); fprintf(stderr, " %s -help\n\n", argv[0]); exit(EXIT_FAILURE); } input_volume_name = argv[1]; input_xfm = argv[2]; outfile = argv[3]; /* check for the infile and outfile */ if(access(input_volume_name, F_OK) != 0){ fprintf(stderr, "%s: Couldn't find %s\n\n", argv[0], input_volume_name); exit(EXIT_FAILURE); } if(access(input_xfm, F_OK) != 0) { fprintf(stderr, "%s: Couldn't find %s\n\n", argv[0], input_xfm); exit(EXIT_FAILURE); } if(access(outfile, F_OK) == 0 && !clobber){ fprintf(stderr, "%s: %s exists! (use -clobber to overwrite)\n\n", argv[0], outfile); exit(EXIT_FAILURE); } /*--- input the volume */ /* if( input_volume( input_volume_name, 3, NULL, MI_ORIGINAL_TYPE, FALSE, 0.0, 0.0, TRUE, &eval_volume,(minc_input_options *) NULL ) != OK ) return( 1 ); */ if (input_volume_header_only( input_volume_name, 3, NULL, &eval_volume,(minc_input_options *) NULL ) != VIO_OK ) { return( 1 ); } /* get information about the volume */ get_volume_sizes( eval_volume, sizes ); voxel_to_world = get_voxel_to_world_transform(eval_volume); dimnames = get_volume_dimension_names(eval_volume); get_volume_separations(eval_volume, original_separation); get_volume_starts(eval_volume, original_starts); /* create new 4D volume, last three dims same as other volume, first dimension being the vector dimension. */ for(i=1; i < 4; i++) { dimnames_grid[i] = dimnames[i-1]; grid_separation[i] = original_separation[i-1]; grid_sizes[i] = sizes[i-1]; grid_starts[i] = original_starts[i-1]; } dimnames_grid[0] = "vector_dimension"; grid_sizes[0] = 3; grid_separation[0] = 1; grid_starts[0] = 0; new_grid = create_volume(4, dimnames_grid, NC_SHORT, FALSE, 0.0, 0.0); //set_voxel_to_world_transform(new_grid, voxel_to_world); // initialize the new grid volume, otherwise the output will be // garbage... set_volume_real_range(new_grid, -100, 100); set_volume_sizes(new_grid, grid_sizes); set_volume_separations(new_grid, grid_separation); set_volume_starts(new_grid, grid_starts); /* for (i=0; i < 3; i++) { get_volume_direction_cosine(eval_volume, i, cosine); set_volume_direction_cosine(new_grid, i+1, cosine); } */ alloc_volume_data(new_grid); /* get the transforms */ if( input_transform_file( input_xfm, &xfm ) != VIO_OK ) return( 1 ); /* see how many transforms will be applied */ n_concat_transforms = get_n_concated_transforms( &xfm ); printf("Number of transforms to be applied: %d\n", n_concat_transforms); initialize_progress_report(&progress, FALSE, sizes[0], "Processing"); /* evaluate the transform at every voxel, keep the displacement in the three cardinal directions */ for( v1 = 0; v1 < sizes[0]; ++v1 ) { update_progress_report(&progress, v1 + 1); for( v2 = 0; v2 < sizes[1]; ++v2 ) { for( v3 = 0; v3 < sizes[2]; ++v3 ) { convert_3D_voxel_to_world(eval_volume, v1, v2, v3, &original[0], &original[1], &original[2]); general_transform_point(&xfm, original[0], original[1], original[2], &transformed[0], &transformed[1], &transformed[2]); for(i=0; i < 3; i++) { value = transformed[i] - original[i]; set_volume_real_value(new_grid, i, v1, v2, v3, 0, value); } } } } terminate_progress_report(&progress); printf("Outputting volume.\n"); output_volume(outfile, MI_ORIGINAL_TYPE, TRUE, 0.0, 0.0, new_grid, arg_string, NULL); return(0); }
int main( int ac, char* av[] ) { VIO_General_transform xfm; FILE *in; int line=1; if ( ac != 4 ) { fprintf( stderr, "usage: %s transform.xfm control_table.txt tolerance\n", av[0] ); return 1; } if ( input_transform_file( av[1], &xfm ) != VIO_OK ) { fprintf( stderr, "Failed to load transform '%s'\n", av[1] ); return 2; } tolerance = atof( av[3] ); if(!(in=fopen(av[2],"r"))) { fprintf( stderr, "Failed to load table '%s'\n", av[2] ); return 2; } /*Set the same seed number*/ while (!feof(in)) { VIO_Real x,y,z; VIO_Real tx,ty,tz; VIO_Real ttx,tty,ttz; VIO_Real a,b,c; VIO_Real ta,tb,tc; int check=1; char line_c[1024]; check=fscanf(in,"%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg",&x,&y,&z,&a,&b,&c,&ta,&tb,&tc); if(check<=0) break; if(check!=3 && check!=9) { fprintf( stderr,"Unexpected input file format at line %d , read %d values!\n",line,check); return 3; } if(general_transform_point( &xfm, x,y,z, &tx,&ty,&tz ) != VIO_OK) { fprintf( stderr, "Failed to transform point %f,%f,%f \n", x,y,z ); return 3; } if(general_inverse_transform_point( &xfm, x,y,z, &ttx,&tty,&ttz ) != VIO_OK) { fprintf( stderr, "Failed to invert transform point %f,%f,%f \n", tx,ty,tz ); return 3; } if(check==3) { fprintf( stdout,"%.20lg,%.20lg,%.20lg,%.20lg,%.20lg,%.20lg,%.20lg,%.20lg,%.20lg\n",x,y,z,tx,ty,tz,ttx,tty,ttz); } else { sprintf(line_c,"Line:%d Fwd ",line); assert_equal_point( tx,ty,tz, a,b,c, line_c ); sprintf(line_c,"Line:%d Inv ",line); assert_equal_point( ttx,tty,ttz, ta,tb,tc, line_c ); } line++; fgetc(in); } fclose(in); delete_general_transform(&xfm); return 0; }