Esempio n. 1
0
image_metadata * read_minc(char *filename, float **image, int *sizes){
  VIO_Volume volume;
  VIO_Real dummy[3];
  image_metadata *meta;
  
  if( input_volume(filename, 3, NULL, NC_UNSPECIFIED, FALSE, 0.0, 0.0, TRUE, &volume, (minc_input_options *) NULL ) != VIO_OK )
      return( NULL );

    meta = (image_metadata *)calloc( 1 , sizeof(image_metadata) ) ;
    meta->start  = calloc(3,sizeof(float));
    meta->step   = calloc(3,sizeof(float));
    meta->length = calloc(3,sizeof(int));

    get_volume_sizes(volume,sizes);
    *image=malloc(sizes[0]*sizes[1]*sizes[2]*sizeof(**image));
    set_volume(*image, volume, sizes);

    meta->length[0]=sizes[0];
    meta->length[1]=sizes[1];
    meta->length[2]=sizes[2];    

    get_volume_starts(volume,dummy);
    meta->start[0]=dummy[0];
    meta->start[1]=dummy[1];
    meta->start[2]=dummy[2];

    get_volume_separations(volume,dummy);
    meta->step[0]=dummy[0];
    meta->step[1]=dummy[1];
    meta->step[2]=dummy[2];

    delete_volume(volume);
    
    return meta;
}
Esempio n. 2
0
/* regrid a point in a file using the input co-ordinate and data */
void regrid_point(VIO_Volume * totals, VIO_Volume * weights,
                  double x, double y, double z, int v_size, double *data_buf)
{

   int      sizes[MAX_VAR_DIMS];
   VIO_Real     steps[MAX_VAR_DIMS];
   VIO_Real     starts[MAX_VAR_DIMS];
   int      start_idx[3];
   int      stop_idx[3];
   double   value, weight;
   double   euc_dist;
   double   euc[3];
   double   c_pos[3];
   int      i, j, k, v;
   double   coord[3];                  /* target point in mm  coordinates, in X, Y, Z order */

   VIO_Transform dircos, invdircos;
   VIO_Vector   vector;
   VIO_Real     dir[3];

   /* the coord used below has to be in mm coordinates in the dircos space of the 
      target volume.  Hence the manipulations with the vols direction_cosines      */
   make_identity_transform(&dircos);

   get_volume_direction_cosine(*totals, perm[0], dir);
   fill_Vector(vector, dir[0], dir[1], dir[2]);
   set_transform_x_axis(&dircos, &vector);

   get_volume_direction_cosine(*totals, perm[1], dir);
   fill_Vector(vector, dir[0], dir[1], dir[2]);
   set_transform_y_axis(&dircos, &vector);

   get_volume_direction_cosine(*totals, perm[2], dir);
   fill_Vector(vector, dir[0], dir[1], dir[2]);
   set_transform_z_axis(&dircos, &vector);

   for(i = 0; i < 4; i++){
      for(j = 0; j < 4; j++){
         Transform_elem(invdircos, i, j) = Transform_elem(dircos, j, i);
         }
      }

   transform_point(&invdircos, x, y, z, &coord[0], &coord[1], &coord[2]);
   
   get_volume_sizes(*totals, sizes);   /* in volume voxel order, ie z,y,x with x fastest */
   get_volume_separations(*totals, steps);
   get_volume_starts(*totals, starts);

   /* figure out the neighbouring voxels start and stop (in voxel co-ordinates) */
   for(i = 0; i < 3; i++){            /* go through x, y and z */
      start_idx[i] =
         (int)rint((coord[i] - starts[perm[i]] - regrid_radius[i]) / steps[perm[i]]);
      stop_idx[i] = start_idx[i] + rint((regrid_radius[i] * 2) / steps[perm[i]]);

      /* flip if required */
      if(start_idx[i] > stop_idx[i]){
         value = start_idx[i];
         start_idx[i] = stop_idx[i];
         stop_idx[i] = value;
         }

      /* check that we aren't off the edge */
      if(start_idx[i] < 0){
         start_idx[i] = 0;
         }
      if(stop_idx[i] >= sizes[perm[i]]){
         stop_idx[i] = sizes[perm[i]] - 1;
         }
      }

   /* loop over the neighbours, getting euclidian distance */
   c_pos[0] = starts[perm[0]] + (start_idx[0] * steps[perm[0]]);
   for(i = start_idx[0]; i <= stop_idx[0]; i++){
      euc[0] = fabs(c_pos[0] - coord[0]);

      c_pos[1] = starts[perm[1]] + (start_idx[1] * steps[perm[1]]);
      for(j = start_idx[1]; j <= stop_idx[1]; j++){
         euc[1] = fabs(c_pos[1] - coord[1]);

         c_pos[2] = starts[perm[2]] + (start_idx[2] * steps[perm[2]]);
         for(k = start_idx[2]; k <= stop_idx[2]; k++){
            euc[2] = fabs(c_pos[2] - coord[2]);

            euc_dist = sqrt(SQR2(euc[0]) + SQR2(euc[1]) + SQR2(euc[2]));

            if((regrid_radius[0] == 0 || euc[0] <= regrid_radius[0]) &&
               (regrid_radius[1] == 0 || euc[1] <= regrid_radius[1]) &&
               (regrid_radius[2] == 0 || euc[2] <= regrid_radius[2])){

               /* calculate the weighting factor */
               switch (regrid_type){
               default:
                  fprintf(stderr, "Erk! unknown regrid_type. File: %s Line: %d\n",
                          __FILE__, __LINE__);
                  exit(EXIT_FAILURE);
                  break;
                  
               case NEAREST_FUNC:
               case LINEAR_FUNC:
                  weight = euc_dist;
                  break;
                  
               case KAISERBESSEL_FUNC:
                  weight =
                     gsl_sf_bessel_I0(regrid_sigma[0] *
                                      sqrt(1 - SQR2(euc[0] / regrid_radius[0]))) *
                     gsl_sf_bessel_I0(regrid_sigma[1] *
                                      sqrt(1 - SQR2(euc[1] / regrid_radius[1]))) *
                     gsl_sf_bessel_I0(regrid_sigma[2] *
                                      sqrt(1 - SQR2(euc[2] / regrid_radius[2]))) /
                     SQR3((regrid_radius[0] + regrid_radius[1] + regrid_radius[2]) / 3);
                  break;
                  
               case GAUSSIAN_FUNC:
                  weight = exp(-SQR2(euc[0]) / SQR2(regrid_sigma[0])) *
                           exp(-SQR2(euc[1]) / SQR2(regrid_sigma[1])) *
                           exp(-SQR2(euc[2]) / SQR2(regrid_sigma[2]));
                  break;
                  }
               
               /* set data values */
               if(regrid_type == NEAREST_FUNC){
                  value = get_volume_real_value(*weights, k, j, i, 0, 0);
                  if(weight < value){
                     set_volume_real_value(*weights, k, j, i, 0, 0, weight);
                     for(v = 0; v < v_size; v++){
                        set_volume_real_value(*totals, k, j, i, v, 0,
                                               data_buf[0 + v] * weight);
                        }
                     }
                  }
               else{
                  for(v = 0; v < v_size; v++){
                     value = get_volume_real_value(*totals, k, j, i, v, 0);
                     set_volume_real_value(*totals, k, j, i, v, 0,
                                          value + (data_buf[0 + v] * weight));
                     }
   
                  /* increment count value */
                  value = get_volume_real_value(*weights, k, j, i, 0, 0);
                  set_volume_real_value(*weights, k, j, i, 0, 0, value + weight);
                  }
               }

            c_pos[2] += steps[perm[2]];
            }

         c_pos[1] += steps[perm[1]];
         }

      c_pos[0] += steps[perm[0]];
      }

   }
Esempio n. 3
0
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 append_new_default_deformation_field(Arg_Data *globals)
{

  VIO_Volume
    new_field;
  VIO_Real
    zero,
    st[VIO_MAX_DIMENSIONS],
    wst[VIO_MAX_DIMENSIONS],
    step[VIO_MAX_DIMENSIONS],
    XYZstart[ VIO_MAX_DIMENSIONS ],
    XYZstep[ VIO_MAX_DIMENSIONS ],
    voxel[VIO_MAX_DIMENSIONS],
    point[VIO_N_DIMENSIONS],
    dir[3][3];

  int
    index[VIO_MAX_DIMENSIONS],
    xyzv[VIO_MAX_DIMENSIONS],
    i,
    count[VIO_MAX_DIMENSIONS],
    XYZcount[VIO_MAX_DIMENSIONS],
    count_extended[VIO_MAX_DIMENSIONS];

  VIO_General_transform
    *grid_trans;

   VectorR
    XYZdirections[ VIO_MAX_DIMENSIONS ];

  /* build a vector volume to store the Grid VIO_Transform */

   /*  ALLOC(new_field,1); not needed since create volume allocs it
       internally and returns a pointer*/

  if (globals->flags.debug) { print ("In append_new_default_deformation_field...\n"); }

  new_field = create_volume(4, dim_name_vector_vol, NC_DOUBLE, TRUE, 0.0, 0.0);

  get_volume_XYZV_indices(new_field, xyzv);

                                /* get the global voxel count and voxel size */
  for(i=0; i<VIO_N_DIMENSIONS; i++) {
    count[xyzv[i]] = globals->count[i];
    count_extended[xyzv[i]] = count[xyzv[i]];
    step[xyzv[i]]  = globals->step[i];
  }
                                /* add info for the vector dimension */
  count[xyzv[VIO_Z+1]] = 3;
  count_extended[xyzv[VIO_Z+1]] = 3;
  step[xyzv[VIO_Z+1]] = 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, now using floats */


  for(i=0; i<VIO_N_DIMENSIONS; i++) {
    dir[VIO_X][i]=globals->directions[VIO_X].coords[i];
    dir[VIO_Y][i]=globals->directions[VIO_Y].coords[i];
    dir[VIO_Z][i]=globals->directions[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]);


  for(i=0; i<VIO_MAX_DIMENSIONS; i++)  /* set the voxel origin, used in the vol def */
    voxel[i] = 0.0;

  set_volume_translation( new_field, voxel, globals->start);



  if (globals->flags.debug) {
    print("in append new def, the start is: %8.3f %8.3f %8.3f\n", globals->start[VIO_X], globals->start[VIO_Y], globals->start[VIO_Z]);
  }

                   /* now pad the volume along the spatial axis
                      to ensure good coverage of the data space
                      with the deformation field */

  for(i=0; i<VIO_N_DIMENSIONS; i++) {
    if (globals->count[i]>1) {
      voxel[xyzv[i]] = -2.5;
      count_extended[xyzv[i]] = globals->count[i]+5;
    }
    else {
      voxel[xyzv[i]] = 0.0;
      count_extended[xyzv[i]] = 1;
    }
  }

  if (globals->flags.debug) {
    print("in append_new_default_deformation_field:\n\tcount_extended= %d %d %d %d\n",
           count_extended[0],count_extended[1],count_extended[2],count_extended[3]);
  }

  set_volume_sizes(new_field, count_extended);
  for(i=0; i<VIO_MAX_DIMENSIONS; i++) count[i] = count_extended[i];

              /* reset the first voxel position with the new origin */
  convert_voxel_to_world(new_field, voxel,
                         &(point[VIO_X]), &(point[VIO_Y]), &(point[VIO_Z]));
  for(i=0; i<VIO_MAX_DIMENSIONS; i++) voxel[i] = 0;

  set_volume_translation(new_field, voxel, point);


  if (globals->flags.debug) {
    print (" point: %8.3f %8.3f %8.3f \n", point[VIO_X], point[VIO_Y], point[VIO_Z]);

    get_volume_starts(new_field, st);
    print (" start: %8.3f %8.3f %8.3f \n", st[xyzv[VIO_X]], st[xyzv[VIO_Y]], st[xyzv[VIO_Z]]);

    voxel[0] = 0;
    voxel[1] = 0;
    voxel[2] = 0;
    get_volume_translation(new_field, voxel, wst);
    print (" wstrt: %8.3f %8.3f %8.3f \n", wst[VIO_X], wst[VIO_Y], wst[VIO_Z]);
    print (" voxel: %8.3f %8.3f %8.3f \n", voxel[xyzv[VIO_X]], voxel[xyzv[VIO_Y]], voxel[xyzv[VIO_Z]]);


    for(i=0; i<3; i++) {
      get_volume_direction_cosine(new_field,xyzv[i], wst);
      print (" dirs: %8.3f %8.3f %8.3f \n", wst[VIO_X], wst[VIO_Y], wst[VIO_Z]);
    }



  }


              /* allocate space for the deformation field data */
  alloc_volume_data(new_field);

              /* Initilize the field to zero deformation */

  /* zero = CONVERT_VALUE_TO_VOXEL(new_field, 0.0); not needed, defs are now doubles */

  for(index[0]=0; index[0]<count[0]; index[0]++)
    for(index[1]=0; index[1]<count[1]; index[1]++)
      for(index[2]=0; index[2]<count[2]; index[2]++)
        for(index[3]=0; index[3]<count[3]; index[3]++)
          {
            SET_VOXEL(new_field, index[0],index[1],index[2],index[3],0, 0.0);  /* was set to 'zero', but now as a double,can be set to 0.0 */
          }

              /* build the new GRID_TRANSFORM */

  ALLOC(grid_trans, 1);

  create_grid_transform(grid_trans, new_field, NULL);

              /* append the deforamation to the current transformation */
  concat_general_transforms(globals->trans_info.transformation, grid_trans,
                            globals->trans_info.transformation);

  delete_volume(new_field);
  delete_general_transform(grid_trans);




}