void get_volume_XYZV_indices(VIO_Volume data, int xyzv[]){ int axis, i, vol_dims; char **data_dim_names; vol_dims = get_volume_n_dimensions(data); data_dim_names = get_volume_dimension_names(data); for(i=0; i<VIO_N_DIMENSIONS+1; i++) xyzv[i] = -1; for(i=0; i<vol_dims; i++) { if (convert_dim_name_to_spatial_axis(data_dim_names[i], &axis )) { xyzv[axis] = i; } else { /* not a spatial axis */ xyzv[VIO_Z+1] = i; } } delete_dimension_names(data, data_dim_names); }
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); }
static void resample_the_deformation_field(Arg_Data *globals) { VIO_Volume existing_field, new_field; VIO_Real vector_val[3], XYZstart[ VIO_MAX_DIMENSIONS ], wstart[ VIO_MAX_DIMENSIONS ], start[ VIO_MAX_DIMENSIONS ], XYZstep[ VIO_MAX_DIMENSIONS ], step[ VIO_MAX_DIMENSIONS ], step2[ VIO_MAX_DIMENSIONS ], s1[ VIO_MAX_DIMENSIONS ], voxel[ VIO_MAX_DIMENSIONS ], dir[3][3]; int i, siz[ VIO_MAX_DIMENSIONS ], index[ VIO_MAX_DIMENSIONS ], xyzv[ VIO_MAX_DIMENSIONS ], XYZcount[ VIO_MAX_DIMENSIONS ], count[ VIO_MAX_DIMENSIONS ]; VIO_General_transform *non_lin_part; VectorR XYZdirections[ VIO_MAX_DIMENSIONS ]; VIO_Real del_x, del_y, del_z, wx, wy,wz; VIO_progress_struct progress; char **data_dim_names; /* get the nonlinear part of the transformation */ existing_field = (VIO_Volume)NULL; non_lin_part = get_nth_general_transform(globals->trans_info.transformation, get_n_concated_transforms( globals->trans_info.transformation) -1); if (get_transform_type( non_lin_part ) == GRID_TRANSFORM){ existing_field = (VIO_Volume)(non_lin_part->displacement_volume); } else { for(i=0; i<get_n_concated_transforms(globals->trans_info.transformation); i++) print ("Transform %d is of type %d\n",i, get_transform_type( get_nth_general_transform(globals->trans_info.transformation, i) )); print_error_and_line_num("Cannot find the deformation field transform to resample", __FILE__, __LINE__); } /* build a vector volume to store the Grid VIO_Transform */ new_field = create_volume(4, dim_name_vector_vol, NC_DOUBLE, TRUE, 0.0, 0.0); get_volume_XYZV_indices(new_field, xyzv); for(i=0; i<VIO_N_DIMENSIONS; i++) step2[i] = globals->step[i]; /* get new start, count, step and directions, all returned in X, Y, Z order. */ set_up_lattice(existing_field, step2, XYZstart, wstart, XYZcount, XYZstep, XYZdirections); /* reset count and step to be in volume order */ for(i=0; i<VIO_N_DIMENSIONS; i++) { start[ i ] = wstart[ i ]; count[ xyzv[i] ] = XYZcount[ i ]; step[ xyzv[i] ] = XYZstep[ i ]; } /* add info for the vector dimension */ count[xyzv[VIO_Z+1]] = 3; step[xyzv[VIO_Z+1]] = 0.0; /* use the sign of the step returned to set the true step size */ for(i=0; i<VIO_N_DIMENSIONS; i++) { if (step[xyzv[i]]<0) step[xyzv[i]] = -1.0 * fabs(globals->step[i]); else step[xyzv[i]] = fabs(globals->step[i]); } for(i=0; i<VIO_MAX_DIMENSIONS; i++) /* set the voxel origin, used in the vol def */ voxel[i] = 0.0; set_volume_sizes( new_field, count); set_volume_separations( new_field, step); /* set_volume_voxel_range( new_field, -MY_MAX_VOX, MY_MAX_VOX); set_volume_real_range( new_field, -1.0*globals->trans_info.max_def_magnitude, globals->trans_info.max_def_magnitude); - no longer needed, because now using doubles*/ set_volume_translation( new_field, voxel, start); for(i=0; i<VIO_N_DIMENSIONS; i++) { dir[VIO_X][i]=XYZdirections[VIO_X].coords[i]; dir[VIO_Y][i]=XYZdirections[VIO_Y].coords[i]; dir[VIO_Z][i]=XYZdirections[VIO_Z].coords[i]; } set_volume_direction_cosine(new_field,xyzv[VIO_X],dir[VIO_X]); set_volume_direction_cosine(new_field,xyzv[VIO_Y],dir[VIO_Y]); set_volume_direction_cosine(new_field,xyzv[VIO_Z],dir[VIO_Z]); /* make sure that the vector dimension is named! */ data_dim_names = get_volume_dimension_names(new_field); if( strcmp( data_dim_names[ xyzv[VIO_Z+1] ] , MIvector_dimension ) != 0 ) { ALLOC((new_field)->dimension_names[xyzv[VIO_Z+1]], \ strlen(MIvector_dimension ) + 1 ); (void) strcpy( (new_field)->dimension_names[xyzv[VIO_Z+1]], MIvector_dimension ); } delete_dimension_names(new_field, data_dim_names); if (globals->flags.debug) { print ("in resample_deformation_field:\n"); print ("xyzv[axes] = %d, %d, %d, %d\n",xyzv[VIO_X],xyzv[VIO_Y],xyzv[VIO_Z],xyzv[VIO_Z+1]); get_volume_sizes(new_field, siz); get_volume_separations(new_field, s1); print ("seps: %7.3f %7.3f %7.3f %7.3f %7.3f \n",s1[0],s1[1],s1[2],s1[3],s1[4]); print ("size: %7d %7d %7d %7d %7d \n",siz[0],siz[1],siz[2],siz[3],siz[4]); } alloc_volume_data(new_field); if (globals->flags.verbose>0) initialize_progress_report( &progress, FALSE, count[xyzv[VIO_X]], "Interpolating new field" ); /* now resample the values from the input deformation */ for(i=0; i<VIO_MAX_DIMENSIONS; i++) { voxel[i] = 0.0; index[i] = 0; } for(index[xyzv[VIO_X]]=0; index[xyzv[VIO_X]]<count[xyzv[VIO_X]]; index[xyzv[VIO_X]]++) { voxel[xyzv[VIO_X]] = (VIO_Real)index[xyzv[VIO_X]]; for(index[xyzv[VIO_Y]]=0; index[xyzv[VIO_Y]]<count[xyzv[VIO_Y]]; index[xyzv[VIO_Y]]++) { voxel[xyzv[VIO_Y]] = (VIO_Real)index[xyzv[VIO_Y]]; for(index[xyzv[VIO_Z]]=0; index[xyzv[VIO_Z]]<count[xyzv[VIO_Z]]; index[xyzv[VIO_Z]]++) { voxel[xyzv[VIO_Z]] = (VIO_Real)index[xyzv[VIO_Z]]; convert_voxel_to_world(new_field, voxel, &wx,&wy,&wz); grid_transform_point(non_lin_part, wx, wy, wz, &del_x, &del_y, &del_z); /* get just the deformation part */ del_x = del_x - wx; del_y = del_y - wy; del_z = del_z - wz; /* del_x = del_y = del_z = 0.0; */ vector_val[0] = CONVERT_VALUE_TO_VOXEL(new_field, del_x); vector_val[1] = CONVERT_VALUE_TO_VOXEL(new_field, del_y); vector_val[2] = CONVERT_VALUE_TO_VOXEL(new_field, del_z); for(index[xyzv[VIO_Z+1]]=0; index[xyzv[VIO_Z+1]]<3; index[xyzv[VIO_Z+1]]++) { SET_VOXEL(new_field, \ index[0], index[1], index[2], index[3], index[4], \ vector_val[ index[ xyzv[ VIO_Z+1] ] ]); } } } if (globals->flags.verbose>0) update_progress_report( &progress,index[xyzv[VIO_X]]+1); } if (globals->flags.verbose>0) terminate_progress_report( &progress ); /* delete and free up old data */ delete_volume(non_lin_part->displacement_volume); /* set new volumes into transform */ non_lin_part->displacement_volume = new_field; }