int main(int argc, char *argv[])
{
   VIO_General_transform 
     transform, 
     *grid_transform_ptr, 
     forward_transform;
   VIO_Volume 
     target_vol,
     volume;
   volume_input_struct 
     input_info;
   VIO_Real
     voxel[VIO_MAX_DIMENSIONS],
     steps[VIO_MAX_DIMENSIONS],
     start[VIO_N_DIMENSIONS],
     target_steps[VIO_MAX_DIMENSIONS],
     wx,wy,wz, inv_x, inv_y, inv_z,
     def_values[VIO_MAX_DIMENSIONS];

   static int 
     clobber_flag = FALSE,
     verbose      = TRUE,
     debug        = FALSE;
   static char  
     *target_file;

   int 
     parse_flag,
     prog_count,
     sizes[VIO_MAX_DIMENSIONS],
     target_sizes[VIO_MAX_DIMENSIONS],
     xyzv[VIO_MAX_DIMENSIONS],
     target_xyzv[VIO_MAX_DIMENSIONS],
     index[VIO_MAX_DIMENSIONS],
     i,
     trans_count;
   VIO_progress_struct
     progress;


   static ArgvInfo argTable[] = {
     {"-like",       ARGV_STRING,   (char *) 0,     (char *) &target_file,
        "Specify target volume sampling information."},
     {"-no_clobber", ARGV_CONSTANT, (char *) FALSE, (char *) &clobber_flag,
        "Do not overwrite output file (default)."},
     {"-clobber",    ARGV_CONSTANT, (char *) TRUE,  (char *) &clobber_flag,
        "Overwrite output file."},
     {"-verbose",    ARGV_CONSTANT, (char *) TRUE,     (char *) &verbose,
        "Write messages indicating progress (default)"},
     {"-quiet",      ARGV_CONSTANT, (char *) FALSE,    (char *) &verbose,
        "Do not write log messages"},
     {"-debug",      ARGV_CONSTANT, (char *) TRUE,  (char *) &debug,
        "Print out debug info."},
     {NULL, ARGV_END, NULL, NULL, NULL}
   };


   prog_name = argv[0];
   target_file = malloc(1024);
   strcpy(target_file,"");

   /* Call ParseArgv to interpret all command line args (returns TRUE if error) */
   parse_flag = ParseArgv(&argc, argv, argTable, 0);

   /* Check remaining arguments */
   if (parse_flag || argc != 3) print_usage_and_exit(prog_name);

   /* Read in file that has a def field to invert */
   if (input_transform_file(argv[1], &transform) != OK) {
      (void) fprintf(stderr, "%s: Error reading transform file %s\n",
                     argv[0], argv[1]);
      exit(EXIT_FAILURE);
   }


   for(trans_count=0; trans_count<get_n_concated_transforms(&transform); trans_count++ ) {

     grid_transform_ptr = get_nth_general_transform(&transform, trans_count );
     
     if (grid_transform_ptr->type == GRID_TRANSFORM) {

       copy_general_transform(grid_transform_ptr,
                              &forward_transform);

       /* 
          this is the call that should be made
          with the latest version of internal_libvolume_io
        
          invert_general_transform(&forward_transform); */

       forward_transform.inverse_flag = !(forward_transform.inverse_flag);

       volume = grid_transform_ptr->displacement_volume;

       if (strlen(target_file)!=0) {
         if (debug) print ("Def field will be resampled like %s\n",target_file);
         
         if (!file_exists( target_file ) ) {
           (void) fprintf(stderr, "%s: Target file '%s' does not exist\n",
                          prog_name,target_file);
           exit(EXIT_FAILURE);
         }

         start_volume_input(target_file, 3, (char **)NULL, 
                            NC_UNSPECIFIED, FALSE, 0.0, 0.0,
                            TRUE, &target_vol, 
                            (minc_input_options *)NULL,
                            &input_info);
         get_volume_XYZV_indices(volume, xyzv);
         get_volume_separations (volume, steps);
         get_volume_sizes       (volume, sizes);

         get_volume_XYZV_indices(target_vol, target_xyzv);
         get_volume_separations (target_vol, target_steps);
         get_volume_sizes       (target_vol, target_sizes);

         for(i=0; i<VIO_MAX_DIMENSIONS; i++) {
           index[i] = 0;
           voxel[i] = 0.0;
         }
         convert_voxel_to_world(target_vol, voxel, &start[VIO_X], &start[VIO_Y], &start[VIO_Z]);

         if( volume != (void *) NULL ){
           free_volume_data( volume );
         }

         for(i=VIO_X; i<=VIO_Z; i++) {
           steps[ xyzv[i] ] = target_steps[ target_xyzv[i] ] ;
           sizes[ xyzv[i] ] = target_sizes[ target_xyzv[i] ] ;
         }
         set_volume_separations(volume, steps);
         set_volume_sizes(      volume, sizes);
         set_volume_starts(volume, start);
         alloc_volume_data( volume );
       }

       get_volume_sizes(volume, sizes);
       get_volume_XYZV_indices(volume,xyzv);

       for(i=0; i<VIO_MAX_DIMENSIONS; i++){
         index[i] = 0;
       }

       if (verbose){
        initialize_progress_report(&progress, FALSE, 
                                   sizes[xyzv[VIO_X]]*sizes[xyzv[VIO_Y]]*sizes[xyzv[VIO_Z]]+1,
                                   "Inverting def field");
       }
       prog_count = 0;

       for(index[xyzv[VIO_X]]=0; index[xyzv[VIO_X]]<sizes[xyzv[VIO_X]]; index[xyzv[VIO_X]]++)
         for(index[xyzv[VIO_Y]]=0; index[xyzv[VIO_Y]]<sizes[xyzv[VIO_Y]]; index[xyzv[VIO_Y]]++)
           for(index[xyzv[VIO_Z]]=0; index[xyzv[VIO_Z]]<sizes[xyzv[VIO_Z]]; index[xyzv[VIO_Z]]++) {
             
             index[ xyzv[VIO_Z+1] ] = 0;
             for(i=0; i<VIO_MAX_DIMENSIONS; i++) voxel[i] = (VIO_Real)index[i];
       
             convert_voxel_to_world(volume, voxel, &wx, &wy, &wz);
             
             if (sizes[ xyzv[VIO_Z] ] ==1)
                general_inverse_transform_point_in_trans_plane(&forward_transform,
                                            wx, wy, wz,
                                            &inv_x, &inv_y, &inv_z);
             else
               grid_inverse_transform_point(&forward_transform,
                                            wx, wy, wz,
                                            &inv_x, &inv_y, &inv_z);
             def_values[VIO_X] = inv_x - wx;
             def_values[VIO_Y] = inv_y - wy;
             def_values[VIO_Z] = inv_z - wz;

             for(index[xyzv[VIO_Z+1]]=0; index[xyzv[VIO_Z+1]]<3; index[xyzv[VIO_Z+1]]++)
               set_volume_real_value(volume,
                                     index[0],index[1],index[2],index[3],index[4],
                                     def_values[ index[ xyzv[VIO_Z+1] ]]);

             prog_count++;
             if (verbose)
               update_progress_report(&progress, prog_count);
           }
       
       if (verbose)
         terminate_progress_report(&progress);

       delete_general_transform(&forward_transform);

       grid_transform_ptr->inverse_flag = !(grid_transform_ptr->inverse_flag);
       
     }

   }
   

   /* Write out the transform */
   if (output_transform_file(argv[2], NULL, &transform) != OK) {
      (void) fprintf(stderr, "%s: Error writing transform file %s\n",
                     argv[0], argv[2]);
      exit(EXIT_FAILURE);
   }

   exit(EXIT_SUCCESS);
}
示例#2
0
static void transform_or_inverse_point_in_trans_plane(VIO_General_transform *transform,
                                          VIO_BOOL           inverse_flag,
                                          VIO_Real              x, 
                                          VIO_Real              y, 
                                          VIO_Real              z,
                                          VIO_Real              *x_transformed,  
                                          VIO_Real              *y_transformed,  
                                          VIO_Real              *z_transformed) {
  
  int      trans;
  
  switch( transform->type )
    {
    case LINEAR:
      if( inverse_flag )
        transform_point( transform->inverse_linear_transform,
                        x, y, z,
                        x_transformed, y_transformed, z_transformed );
      else
        transform_point( transform->linear_transform,
                        x, y, z,
                        x_transformed, y_transformed, z_transformed );
      break;
      
    case THIN_PLATE_SPLINE:
      if( inverse_flag )
        {
          thin_plate_spline_inverse_transform( transform->n_dimensions,
                                              transform->n_points,
                                              transform->points,
                                              transform->displacements,
                                              x, y, z,
                                              x_transformed, y_transformed,
                                              z_transformed );
        }
      else
        {
          thin_plate_spline_transform( transform->n_dimensions,
                                      transform->n_points,
                                      transform->points,
                                      transform->displacements,
                                      x, y, z,
                                      x_transformed, y_transformed,
                                      z_transformed );
        }
      break;
      
    case GRID_TRANSFORM:
      if( inverse_flag )
        {
          grid_inverse_transform_point_in_trans_plane( transform,
                                          x, y, z,
                                          x_transformed, y_transformed,
                                          z_transformed );
        }
      else
        {
          grid_transform_point_in_trans_plane( transform,
                                  x, y, z,
                                  x_transformed, y_transformed,
                                  z_transformed );
        }
      break;
      
    case USER_TRANSFORM:
      if( inverse_flag )
        {
          transform->user_inverse_transform_function(
                transform->user_data, x, y, z,
                x_transformed, y_transformed, z_transformed );
        }
      else
        {
          transform->user_transform_function(
                transform->user_data, x, y, z,
                x_transformed, y_transformed, z_transformed );
        }
      break;
      
    case CONCATENATED_TRANSFORM:
      *x_transformed = x;
      *y_transformed = y;
      *z_transformed = z;
      
      if( transform->inverse_flag )
        inverse_flag = !inverse_flag;
      
      if( inverse_flag )
        {
          for( trans = transform->n_transforms-1;  trans >= 0;  --trans )
            {
              general_inverse_transform_point_in_trans_plane(&transform->transforms[trans],
                  *x_transformed, *y_transformed, *z_transformed,
                  x_transformed, y_transformed, z_transformed );
            }
        }
      else
        {
          for(trans=0; trans<transform->n_transforms; trans++)
            {
              general_transform_point_in_trans_plane( &transform->transforms[trans],
                  *x_transformed, *y_transformed, *z_transformed,
                  x_transformed, y_transformed, z_transformed );
            }
        }
      break;
      
    default:
      handle_internal_error( "transform_or_invert_point" );
      break;
    }
}