Exemple #1
0
void scale_volume(VIO_Volume * vol, double o_min, double o_max, double min, double max)
{
   double   value, a, b;
   int      sizes[MAX_VAR_DIMS];
   int      i, j, k, v;
   VIO_progress_struct progress;

   get_volume_sizes(*vol, sizes);

   /* rescale the volume */
   a = (max - min) / (o_max - o_min);
   b = min - (o_min * a);
   initialize_progress_report(&progress, FALSE, sizes[Z_IDX], "Rescaling Volume");
   for(k = sizes[Z_IDX]; k--;){
      for(j = sizes[Y_IDX]; j--;){
         for(i = sizes[X_IDX]; i--;){
            for(v = sizes[V_IDX]; v--;){
               value = (get_volume_real_value(*vol, k, j, i, v, 0) * a) + b;

               set_volume_real_value(*vol, k, j, i, v, 0, value);
               }
            }
         }
      update_progress_report(&progress, k + 1);
      }
   terminate_progress_report(&progress);

   if(verbose){
      fprintf(stdout, " + rescaled data range: [%g:%g]\n", min, max);
      }

   set_volume_real_range(*vol, min, max);
   }
Exemple #2
0
/* perform an erosion on a volume */
Volume  *erosion_kernel(Kernel * K, Volume * vol)
{
   int      x, y, z, c;
   double   value;
   int      sizes[MAX_VAR_DIMS];
   progress_struct progress;
   Volume   tmp_vol;

   if(verbose){
      fprintf(stdout, "Erosion kernel\n");
      }
   get_volume_sizes(*vol, sizes);
   initialize_progress_report(&progress, FALSE, sizes[2], "Erosion");

   /* copy the volume */
   tmp_vol = copy_volume(*vol);

   for(z = -K->pre_pad[2]; z < sizes[0] - K->post_pad[2]; z++){
      for(y = -K->pre_pad[1]; y < sizes[1] - K->post_pad[1]; y++){
         for(x = -K->pre_pad[0]; x < sizes[2] - K->post_pad[0]; x++){

            value = get_volume_real_value(tmp_vol, z, y, x, 0, 0);
            for(c = 0; c < K->nelems; c++){
               if(get_volume_real_value(*vol,
                                        z + K->K[c][2],
                                        y + K->K[c][1],
                                        x + K->K[c][0],
                                        0 + K->K[c][3], 0 + K->K[c][4]) > value){
                  set_volume_real_value(*vol,
                                        z + K->K[c][2],
                                        y + K->K[c][1],
                                        x + K->K[c][0],
                                        0 + K->K[c][3],
                                        0 + K->K[c][4], value * K->K[c][5]);
                  }
               }

            value = get_volume_real_value(tmp_vol, z, y, x, 0, 0);
            }
         }
      update_progress_report(&progress, z + 1);
      }

   delete_volume(tmp_vol);
   terminate_progress_report(&progress);
   return (vol);
   }
Exemple #3
0
void set_volume(float *data, VIO_Volume vol, int *sizes){
  int i,j,k;

  for (i=0;i<sizes[0];i++)
    for (j=0;j<sizes[1];j++)
      for (k=0;k<sizes[2];k++)
        data[i*sizes[1]*sizes[2]+j*sizes[2]+k] = get_volume_real_value(vol,i,j,k,0,0);
}
Exemple #4
0
/* xcorr = sum((a*b)^2) / (sqrt(sum(a^2)) * sqrt(sum(b^2))   */
VIO_Volume *lcorr_kernel(Kernel * K, VIO_Volume * vol, VIO_Volume *cmp)
{
   int      x, y, z, c;
   double   value, v1, v2;
   double   ssum_v1, ssum_v2, sum_prd, denom;
   int      sizes[MAX_VAR_DIMS];
   progress_struct progress;
   Volume   tmp_vol;
   
   if(verbose){
      fprintf(stdout, "Local Correlation kernel\n");
      }
   get_volume_sizes(*vol, sizes);
   initialize_progress_report(&progress, FALSE, sizes[2], "Local Correlation");

   /* copy the volume */
   tmp_vol = copy_volume(*vol);
   
   /* zero the output volume */
   for(z = sizes[0]; z--;){
      for(y = sizes[1]; y--;){
         for(x = sizes[2]; x--;){
            set_volume_voxel_value(*vol, z, y, x, 0, 0, 0);
            }
         }
      }
   
   /* set output range */
   set_volume_real_range(*vol, 0.0, 1.0);
   
   for(z = -K->pre_pad[2]; z < sizes[0] - K->post_pad[2]; z++){
      for(y = -K->pre_pad[1]; y < sizes[1] - K->post_pad[1]; y++){
         for(x = -K->pre_pad[0]; x < sizes[2] - K->post_pad[0]; x++){
            
            /* init counters */
            ssum_v1 = ssum_v2 = sum_prd = 0;
            for(c = 0; c < K->nelems; c++){
               v1 = get_volume_real_value(tmp_vol,
                                          z + K->K[c][2],
                                          y + K->K[c][1],
                                          x + K->K[c][0], 0 + K->K[c][3],
                                          0 + K->K[c][4]) * K->K[c][5];
               v2 = get_volume_real_value(*cmp,
                                          z + K->K[c][2],
                                          y + K->K[c][1],
                                          x + K->K[c][0], 0 + K->K[c][3],
                                          0 + K->K[c][4]) * K->K[c][5];
               
               /* increment counters */
               ssum_v1 += v1*v1;
               ssum_v2 += v2*v2;
               sum_prd += v1*v2;
               }
            
            denom = sqrt(ssum_v1 * ssum_v2);
            value = (denom == 0.0) ? 0.0 : sum_prd / denom;
            
            set_volume_real_value(*vol, z, y, x, 0, 0, value);
            }
         }
      update_progress_report(&progress, z + 1);
      }
   terminate_progress_report(&progress);
   
   /* tidy up */
   delete_volume(tmp_vol);
   
   return (vol);
   }
Exemple #5
0
/* from the original 2 pass Borgefors alg      */
Volume  *distance_kernel(Kernel * K, Volume * vol, double bg)
{
   int      x, y, z, c;
   double   value, min;
   int      sizes[MAX_VAR_DIMS];
   progress_struct progress;
   Kernel  *k1, *k2;

   /* split the Kernel */
   k1 = new_kernel(K->nelems);
   k2 = new_kernel(K->nelems);
   split_kernel(K, k1, k2);

   setup_pad_values(k1);
   setup_pad_values(k2);

   if(verbose){
      fprintf(stdout, "Distance kernel - background %g\n", bg);
      fprintf(stdout, "forward direction kernel:\n");
      print_kernel(k1);
      fprintf(stdout, "\nreverse direction kernel:\n");
      print_kernel(k2);
      }

   get_volume_sizes(*vol, sizes);
   initialize_progress_report(&progress, FALSE, sizes[2] * 2, "Distance");

   /* forward raster direction */
   for(z = -K->pre_pad[2]; z < sizes[0] - K->post_pad[2]; z++){
      for(y = -K->pre_pad[1]; y < sizes[1] - K->post_pad[1]; y++){
         for(x = -K->pre_pad[0]; x < sizes[2] - K->post_pad[0]; x++){

            if(get_volume_real_value(*vol, z, y, x, 0, 0) != bg){

               /* find the minimum */
               min = DBL_MAX;
               for(c = 0; c < k1->nelems; c++){
                  value = get_volume_real_value(*vol,
                                                z + k1->K[c][2],
                                                y + k1->K[c][1],
                                                x + k1->K[c][0],
                                                0 + k1->K[c][3], 0 + k1->K[c][4]) + 1;
                  if(value < min){
                     min = value;
                     }
                  }

               set_volume_real_value(*vol, z, y, x, 0, 0, min);
               }
            }
         }
      update_progress_report(&progress, z + 1);
      }

   /* reverse raster direction */
   for(z = sizes[0] - k2->post_pad[2] - 1; z >= -k2->pre_pad[2]; z--){
      for(y = sizes[1] - k2->post_pad[1] - 1; y >= -k2->pre_pad[1]; y--){
         for(x = sizes[2] - k2->post_pad[0] - 1; x >= -k2->pre_pad[0]; x--){

            min = get_volume_real_value(*vol, z, y, x, 0, 0);
            if(min != bg){

               /* find the minimum distance to bg in the neighbouring vectors */
               for(c = 0; c < k2->nelems; c++){
                  value = get_volume_real_value(*vol,
                                                z + k2->K[c][2],
                                                y + k2->K[c][1],
                                                x + k2->K[c][0],
                                                0 + k2->K[c][3], 0 + k2->K[c][4]) + 1;
                  if(value < min){
                     min = value;
                     }
                  }

               set_volume_real_value(*vol, z, y, x, 0, 0, min);
               }
            }
         }
      update_progress_report(&progress, sizes[2] + z + 1);
      }

   free(k1);
   free(k2);
   terminate_progress_report(&progress);
   return (vol);
   }
Exemple #6
0
int  main(
    int   argc,
    char  *argv[] )
{
    STRING               volume_filename;
    STRING               output_filename;
    Real                 x, y, z, xc, yc, zc, xp, yp, zp, len, pos;
    Real                 value, scaling, min_value, max_value;
    int                  v[MAX_DIMENSIONS], sizes[MAX_DIMENSIONS];
    Real                 voxel[MAX_DIMENSIONS], scale;
    Volume               volume;

    initialize_argument_processing( argc, argv );

    if( !get_string_argument( "", &volume_filename ) ||
        !get_string_argument( "", &output_filename ) ||
        !get_real_argument( 0.0, &x ) ||
        !get_real_argument( 0.0, &y ) ||
        !get_real_argument( 0.0, &z ) ||
        !get_real_argument( 0.0, &scaling ) )
    {
        return( 1 );
    }

    len = sqrt( x * x + y * y + z * z );
    x /= len;
    y /= len;
    z /= len;

    if( input_volume( volume_filename, 3, File_order_dimension_names,
                      NC_UNSPECIFIED, FALSE, 0.0, 0.0,
                      TRUE, &volume, NULL ) != OK )
        return( 1 );

    get_volume_sizes( volume, sizes );
    get_volume_real_range( volume, &min_value, &max_value );

    voxel[0] = (Real) (sizes[0]-1) / 2.0;
    voxel[1] = (Real) (sizes[1]-1) / 2.0;
    voxel[2] = (Real) (sizes[2]-1) / 2.0;

    convert_voxel_to_world( volume, voxel, &xc, &yc, &zc );
    
    BEGIN_ALL_VOXELS( volume, v[0], v[1], v[2], v[3], v[4] )

        voxel[0] = (Real) v[0];
        voxel[1] = (Real) v[1];
        voxel[2] = (Real) v[2];

        convert_voxel_to_world( volume, voxel, &xp, &yp, &zp );

        pos = (xp - xc) * x + (yp - yc) * y + (zp - zc) * z;

        scale = 1.0 + pos * scaling;
        value = get_volume_real_value( volume, v[0], v[1], v[2], v[3], v[4] );
        value *= scale;
        if( value < min_value )
            value = min_value;
        else if( value > max_value )
            value = max_value;
        set_volume_real_value( volume, v[0], v[1], v[2], v[3], v[4], value );

    END_ALL_VOXELS

    (void) output_modified_volume( output_filename, NC_UNSPECIFIED, FALSE,
                          0.0, 0.0, volume, volume_filename,
                          "Scaled\n", NULL );

    return( 0 );
}
void interpolate_deformation_slice(VIO_Volume volume, 
                                          VIO_Real wx,Real wy,Real wz,
                                          VIO_Real def[])
{
  VIO_Real
    world[VIO_N_DIMENSIONS],
    v00,v01,v02,v03, 
    v10,v11,v12,v13, 
    v20,v21,v22,v23, 
    v30,v31,v32,v33;
  long 
    ind0, ind1, ind2;
  VIO_Real
    voxel[VIO_MAX_DIMENSIONS],
    frac[VIO_MAX_DIMENSIONS];
  int 
    i,
    xyzv[VIO_MAX_DIMENSIONS],
    sizes[VIO_MAX_DIMENSIONS];
  double temp_result;
  
  
  def[VIO_X] = def[VIO_Y] = def[VIO_Z] = 0.0;
  world[VIO_X] = wx; world[VIO_Y] = wy; world[VIO_Z] = wz;
  convert_world_to_voxel(volume, wx, wy, wz, voxel);
  
  /* Check that the coordinate is inside the volume */
  
  get_volume_sizes(volume, sizes);
  get_volume_XYZV_indices(volume, xyzv);

  if ((voxel[ xyzv[VIO_X] ] < 0) || (voxel[ xyzv[VIO_X] ] >=sizes[ xyzv[VIO_X]]) ||
      (voxel[ xyzv[VIO_Y] ] < 0) || (voxel[ xyzv[VIO_Y] ] >=sizes[ xyzv[VIO_Y]]) ||
      (voxel[ xyzv[VIO_Z] ] < 0) || (voxel[ xyzv[VIO_Z] ] >=sizes[ xyzv[VIO_Z]]))  {
    return ;
  }
  
  if (/*(sizes[ xyzv[VIO_Z] ] == 1) &&*/ xyzv[VIO_Z]==1) {
    
    /* Get the whole and fractional part of the coordinate */
    ind0 = FLOOR( voxel[ xyzv[VIO_Z] ] );
    ind1 = FLOOR( voxel[ xyzv[VIO_Y] ] );
    ind2 = FLOOR( voxel[ xyzv[VIO_X] ] );
    frac[VIO_Y] = voxel[ xyzv[VIO_Y] ] - ind1;
    frac[VIO_X] = voxel[ xyzv[VIO_X] ] - ind2;
    
    if (sizes[xyzv[VIO_X]] < 4 || sizes[xyzv[VIO_Y]] < 4) {
      def[VIO_X] = get_volume_real_value(volume, 0, ind0, ind1, ind2, 0);
      def[VIO_Y] = get_volume_real_value(volume, 1, ind0, ind1, ind2, 0);
      def[VIO_Z] = get_volume_real_value(volume, 2, ind0, ind1, ind2, 0);
      return;
    }

    if (ind1==0) 
      frac[VIO_Y] -= 1.0;
    else {
      ind1--;
      while ( ind1+3 >= sizes[xyzv[VIO_Y]] ) {
        ind1--;
        frac[VIO_Y] += 1.0;
      }
    }
    if (ind2==0) 
      frac[VIO_X] -= 1.0;
    else {
      ind2--;
      while ( ind2+3 >= sizes[xyzv[VIO_X]] ) {
        ind2--;
        frac[VIO_X] += 1.0;
      }
    }
    for(i=0; i<3; i++) {
      GET_VOXEL_4D(v00, volume, i, ind0, ind1, ind2);
      GET_VOXEL_4D(v01, volume, i, ind0, ind1, ind2+1);
      GET_VOXEL_4D(v02, volume, i, ind0, ind1, ind2+2);
      GET_VOXEL_4D(v03, volume, i, ind0, ind1, ind2+3);
      
      GET_VOXEL_4D(v10, volume, i, ind0, ind1+1, ind2);
      GET_VOXEL_4D(v11, volume, i, ind0, ind1+1, ind2+1);
      GET_VOXEL_4D(v12, volume, i, ind0, ind1+1, ind2+2);
      GET_VOXEL_4D(v13, volume, i, ind0, ind1+1, ind2+3);
      
      GET_VOXEL_4D(v20, volume, i, ind0, ind1+2, ind2);
      GET_VOXEL_4D(v21, volume, i, ind0, ind1+2, ind2+1);
      GET_VOXEL_4D(v22, volume, i, ind0, ind1+2, ind2+2);
      GET_VOXEL_4D(v23, volume, i, ind0, ind1+2, ind2+3);
      
      GET_VOXEL_4D(v30, volume, i, ind0, ind1+3, ind2);
      GET_VOXEL_4D(v31, volume, i, ind0, ind1+3, ind2+1);
      GET_VOXEL_4D(v32, volume, i, ind0, ind1+3, ind2+2);
      GET_VOXEL_4D(v33, volume, i, ind0, ind1+3, ind2+3);
      
      CUBIC_BIVAR(v00,v01,v02,v03, \
                  v10,v11,v12,v13, \
                  v20,v21,v22,v23, \
                  v30,v31,v32,v33, \
                  frac[VIO_Y],frac[VIO_X], temp_result);
      def[i] = CONVERT_VOXEL_TO_VALUE(volume,temp_result);
    }
    
    

  }
  else {
    print ("\n\nxyzv[] = %d %d %d %d\n",xyzv[0],xyzv[1],xyzv[2],xyzv[3]);
    print ("\n\nsizes[]= %d %d %d %d\n",sizes[0],sizes[1],sizes[2],sizes[3]);
    print_error_and_line_num("error in slice_interpolate", __FILE__, __LINE__);
  }

}
Exemple #8
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]];
      }

   }
Exemple #9
0
int main(int argc, char *argv[])
{
   char   **infiles;
   int      n_infiles;
   char    *out_fn;
   char    *history;
   VIO_progress_struct progress;
   VIO_Volume   totals, weights;
   int      i, j, k, v;
   double   min, max;
   double   w_min, w_max;
   long     num_missed;
   double   weight, value;
   double   initial_weight;

   VIO_Real     dummy[3];

   int      sizes[MAX_VAR_DIMS];
   double   starts[MAX_VAR_DIMS];
   double   steps[MAX_VAR_DIMS];
   
   long     t = 0;

   /* start the time counter */
   current_realtime_seconds();
   
   /* get the history string */
   history = time_stamp(argc, argv);

   /* get args */
   if(ParseArgv(&argc, argv, argTable, 0) || (argc < 3)){
      fprintf(stderr,
              "\nUsage: %s [options] <in1.mnc> [<in2.mnc> [...]] <out.mnc>\n", argv[0]);
      fprintf(stderr,
              "       %s [options] -arb_path pth.conf <infile.raw> <out.mnc>\n", argv[0]);
      fprintf(stderr, "       %s -help\n\n", argv[0]);
      exit(EXIT_FAILURE);
      }

   /* get file names */
   n_infiles = argc - 2;
   infiles = (char **)malloc(sizeof(char *) * n_infiles);
   for(i = 0; i < n_infiles; i++){
      infiles[i] = argv[i + 1];
      }
   out_fn = argv[argc - 1];

   /* check for infiles and outfile */
   for(i = 0; i < n_infiles; i++){
      if(!file_exists(infiles[i])){
         fprintf(stderr, "%s: Couldn't find input file %s.\n\n", argv[0], infiles[i]);
         exit(EXIT_FAILURE);
         }
      }
   if(!clobber && file_exists(out_fn)){
      fprintf(stderr, "%s: %s exists, -clobber to overwrite.\n\n", argv[0], out_fn);
      exit(EXIT_FAILURE);
      }

   /* check for weights_fn if required */
   if(weights_fn != NULL){
      if(!clobber && file_exists(weights_fn)){
         fprintf(stderr, "%s: %s exists, -clobber to overwrite.\n\n", argv[0],
                 weights_fn);
         exit(EXIT_FAILURE);
         }
      }

   /* set up parameters for reconstruction */
   if(out_dtype == NC_UNSPECIFIED){
      out_dtype = in_dtype;
      }
   if(out_is_signed == DEF_BOOL){
      out_is_signed = in_is_signed;
      }

   /* check vector dimension size */
   if(vect_size < 1){
      fprintf(stderr, "%s: -vector (%d) must be 1 or greater.\n\n", argv[0], vect_size);
      exit(EXIT_FAILURE);
      }

   /* check sigma */
   if(regrid_sigma[0] <= 0 || regrid_sigma[1] <= 0 || regrid_sigma[2] <= 0 ){
      fprintf(stderr, "%s: -sigma must be greater than 0\n\n", argv[0]);
      exit(EXIT_FAILURE);
      }

   /* read in the output file config from a file is specified */
   if(out_config_fn != NULL){
      int      ext_args_c;
      char    *ext_args[32];           /* max possible is 32 arguments */

      ext_args_c = read_config_file(out_config_fn, ext_args);
      if(ParseArgv(&ext_args_c, ext_args, argTable,
                   ARGV_DONT_SKIP_FIRST_ARG | ARGV_NO_LEFTOVERS | ARGV_NO_DEFAULTS)){
         fprintf(stderr, "\nError in parameters in %s\n", out_config_fn);
         exit(EXIT_FAILURE);
         }
      }

   if(verbose){
      fprintf_vol_def(stdout, &out_inf);
      }

   /* transpose the geometry arrays */
   /* out_inf.*[] are in world xyz order, perm[] is the permutation
      array to map world xyz to the right voxel order in the volume */
   for(i = 0; i < WORLD_NDIMS; i++){
      sizes[i] = out_inf.nelem[perm[i]];  /* sizes, starts, steps are in voxel volume order. */
      starts[i] = out_inf.start[perm[i]];
      steps[i] = out_inf.step[perm[i]];
      }
   sizes[WORLD_NDIMS] = vect_size;

   /* create the totals volume */
   totals = create_volume((vect_size > 1) ? 4 : 3,
                          (vect_size > 1) ? std_dimorder_v : std_dimorder,
                          out_dtype, out_is_signed, 0.0, 0.0);
   set_volume_sizes(totals, sizes);
   set_volume_starts(totals, starts);
   set_volume_separations(totals, steps);
   for(i = 0; i < WORLD_NDIMS; i++){
      /* out_inf.dircos is in world x,y,z order, we have to use the perm array to 
         map each direction to the right voxel axis. */
      set_volume_direction_cosine(totals, i, out_inf.dircos[perm[i]]);
      }
   alloc_volume_data(totals);

   /* create the "weights" volume */
   weights = create_volume(3, std_dimorder, out_dtype, out_is_signed, 0.0, 0.0);
   set_volume_sizes(weights, sizes);
   set_volume_starts(weights, starts);
   set_volume_separations(weights, steps);
   for(i = 0; i < WORLD_NDIMS; i++){
      set_volume_direction_cosine(weights, i, out_inf.dircos[perm[i]]);
      }
   alloc_volume_data(weights);

   /* down below in regrid_loop, Andrew makes a nasty direct reference to the
      voxel_to_world transformation in the volume.  This
      transformation is not necessarily up to date, particularly when
      non-default direction cosines are used.  In volume_io, the
      direction cosines are set and a FLAG is also set to indicate
      that the voxel-to-world xform is not up to date.  If the stanrd
      volume_io general transform code is used, it checks internally
      to see if the matrix is up to date, and if not it is recomputed.

      So here, we'll (LC + MK) force an update by calling a general
      transform.  */

//   convert_world_to_voxel(weights, (Real) 0, (Real) 0, (Real) 0, dummy);
//   convert_world_to_voxel(totals, (Real) 0, (Real) 0, (Real) 0, dummy);

   fprintf(stderr, "2Sizes: [%d:%d:%d] \n", sizes[perm[0]], sizes[perm[1]], sizes[perm[2]]);
   
   /* initialize weights to be arbitray large value if using NEAREST */
   /* volume interpolation else initialize all to zero */
   if(regrid_type == NEAREST_FUNC && ap_coord_fn == NULL){
      initial_weight = LARGE_INITIAL_WEIGHT;
      }
   else{
      initial_weight = 0.0;
      }
   
   /* initialize weights and totals */   
   for(k = sizes[Z_IDX]; k--;){
      for(j = sizes[Y_IDX]; j--;){
         for(i = sizes[X_IDX]; i--;){
            set_volume_real_value(weights, k, j, i, 0, 0, initial_weight);
            for(v = vect_size; v--;){
               set_volume_real_value(totals, k, j, i, v, 0, 0.0);
               }
            }
         }
      }

   /* if regridding via an arbitrary path */
   if(ap_coord_fn != NULL){

      if(n_infiles > 1){
         fprintf(stderr, "%s: arb_path only works for one input file (so far).\n\n",
                 argv[0]);
         exit(EXIT_FAILURE);
         }

      /* print some pretty output */
      if(verbose){
         fprintf(stdout, " | Input data:      %s\n", infiles[0]);
         fprintf(stdout, " | Arb path:        %s\n", ap_coord_fn);
         fprintf(stdout, " | Output range:    [%g:%g]\n", out_range[0], out_range[1]);
         fprintf(stdout, " | Output file:     %s\n", out_fn);
         }

      regrid_arb_path(ap_coord_fn, infiles[0], max_buffer_size_in_kb,
                      &totals, &weights, vect_size, regrid_range[0], regrid_range[1]);
      }

   /* else if regridding via a series of input minc file(s) */
   else {
      for(i = 0; i < n_infiles; i++){
         if(verbose){
            fprintf(stdout, " | Input file:      %s\n", infiles[i]);
            }
         regrid_minc(infiles[i], max_buffer_size_in_kb,
                     &totals, &weights, vect_size, regrid_range[0], regrid_range[1]);
         }
      }

   /* initialise min and max counters and divide totals/weights */
   num_missed = 0;
   min = get_volume_real_value(totals, 0, 0, 0, 0, 0);
   max = get_volume_real_value(totals, 0, 0, 0, 0, 0);
   w_min = get_volume_real_value(weights, 0, 0, 0, 0, 0);
   w_max = get_volume_real_value(weights, 0, 0, 0, 0, 0);
   initialize_progress_report(&progress, FALSE, out_inf.nelem[Z_IDX], "Dividing through");
   
   for(i = sizes[perm[0]]; i--;){
      for(j = sizes[perm[1]]; j--;){
         for(k = sizes[perm[2]]; k--;){
            weight = get_volume_real_value(weights, k, j, i, 0, 0);
            if(weight < w_min){
               w_min = weight;
               }
            else if(weight > w_max){
               w_max = weight;
               }
            
            if(weight != 0){
               for(v = vect_size; v--;){
                  value = get_volume_real_value(totals, k, j, i, v, 0) / weight;
                  if(value < min){
                     min = value;
                     }
                  else if(value > max){
                     max = value;
                     }
                  
                  set_volume_real_value(totals, k, j, i, v, 0, value);
                  }
               }
            else {
               num_missed++;
               }
            }
         }
      update_progress_report(&progress, k + 1);
      }
   terminate_progress_report(&progress);

   /* set the volumes range */
   if(verbose){
      fprintf(stdout, " + data range:   [%g:%g]\n", min, max);
      fprintf(stdout, " + weight range: [%g:%g]\n", w_min, w_max);
      }
   set_volume_real_range(totals, min, max);
   set_volume_real_range(weights, w_min, w_max);

   if(num_missed > 0 && verbose){
      int      nvox;

      nvox = out_inf.nelem[X_IDX] * out_inf.nelem[Y_IDX] * out_inf.nelem[Z_IDX];
      fprintf(stdout,
              "\n-regrid_radius possibly too small, no data in %ld/%d[%2.2f%%] voxels\n\n",
              num_missed, nvox, ((float)num_missed / nvox * 100));
      }

   /* rescale data if required */
   if(out_range[0] != -DBL_MAX && out_range[1] != DBL_MAX){
      double   o_min, o_max;

      /* get the existing range */
      get_volume_real_range(totals, &o_min, &o_max);

      /* rescale it */
      scale_volume(&totals, o_min, o_max, out_range[0], out_range[1]);
      }

   /* output the result */
   if(verbose){
      fprintf(stdout, " | Outputting %s...\n", out_fn);
      }
   if(output_volume(out_fn, out_dtype, out_is_signed,
                    0.0, 0.0, totals, history, NULL) != VIO_OK){
      fprintf(stderr, "Problems outputing: %s\n\n", out_fn);
      }

   /* output weights volume if required */
   if(weights_fn != NULL){
      if(verbose){
         fprintf(stdout, " | Outputting %s...\n", weights_fn);
         }
      if(output_volume(weights_fn, out_dtype, out_is_signed,
                       0.0, 0.0, weights, history, NULL) != VIO_OK){
         fprintf(stderr, "Problems outputting: %s\n\n", weights_fn);
         }
      }

   delete_volume(totals);
   delete_volume(weights);
   
   t = current_realtime_seconds();
   printf("Total reconstruction time: %ld hours %ld minutes %ld seconds\n", t/3600, (t/60)%60, t%60);
   
   return (EXIT_SUCCESS);
   }
Exemple #10
0
/* ----------------------------- MNI Header -----------------------------------
@NAME       : average_smoothness
@INPUT      : tmp_lambda_file - tmp file with unaveraged smoothness values
@OUTPUT     : lambda_file - file where final values are to be placed
@RETURNS    : nothing
@DESCRIPTION: routine to create buffers for calculating smoothness of field
@CREATED    : Nov. 3, 1997, J. Taylor
@MODIFIED   : 
---------------------------------------------------------------------------- */
int average_smoothness(char *tmp_lambda_file, char *lambda_file, double scalar)
{
   Volume volume;
   nc_type in_nc_type;
   int in_signed_flag = FALSE;
   volume_input_struct volume_input;
   int v1, v2, v3;
   int num_dim;
   int sizes[MAX_DIMENSIONS];
   double avg, values[8];
   int i;

   if(start_volume_input(tmp_lambda_file, 3, NULL, NC_UNSPECIFIED, FALSE,
                         0.0, 0.0, TRUE, &volume,
                         (minc_input_options *) NULL, &volume_input) != OK){
      fprintf(stderr,"\nError opening %s.\n", tmp_lambda_file); 
      exit(EXIT_FAILURE);
   }

   in_nc_type = get_volume_nc_data_type(volume, &in_signed_flag);
   get_volume_sizes(volume, sizes);
   num_dim = get_volume_n_dimensions(volume);

   cancel_volume_input(volume, &volume_input);

   if( input_volume(tmp_lambda_file, 3, NULL, NC_FLOAT, FALSE, 0.0, 0.0,
                    TRUE, &volume, (minc_input_options *) NULL) != OK) {
      (void) fprintf(stderr, "Error reading file \"%s\"\n", tmp_lambda_file);
      return FALSE;
   }

   for(v1=0; v1<sizes[0]; v1++) {
      for(v2=0; v2<sizes[1]; v2++) {
         for(v3=0; v3<sizes[2]; v3++) {

            avg = 0.0;

            if((v1<sizes[0]-1) && (v2<sizes[1]-1) && (v3<sizes[2])-1) {

               values[0] = get_volume_real_value(volume, v1+1, v2, v3, 0, 0); 
               values[1] = get_volume_real_value(volume, v1, v2+1, v3, 0, 0);
               values[2] = get_volume_real_value(volume, v1, v2, v3+1, 0, 0);
               values[3] = get_volume_real_value(volume,v1+1, v2+1, v3, 0, 0);
               values[4] = get_volume_real_value(volume, v1+1,v2, v3+1, 0, 0);
               values[5] = get_volume_real_value(volume, v1, v2+1,v3+1, 0, 0);
               values[6] = get_volume_real_value(volume, v1, v2, v3, 0, 0);
               values[7] = get_volume_real_value(volume, v1+1, v2+1,v3+1,0,0);
            
               for(i=0; i<8; i++) {
                  if(values[i] != INVALID_DATA)
                     avg += values[i];
                  else {
                     avg = INVALID_DATA;
                     i = 8;
                  }
               }
            }
            else
               avg = INVALID_DATA;

            if (avg == 0.0)
               avg = INVALID_DATA;
            if (avg != INVALID_DATA)
                avg = scalar * 8.0 / pow(avg, (1.0 / num_dim));

            set_volume_real_value(volume, v1, v2, v3, 0, 0, avg);

         }
      }
   }

   if( output_modified_volume(lambda_file, in_nc_type, in_signed_flag,
                     0.0, 0.0, volume, tmp_lambda_file, NULL,
                     (minc_output_options *) NULL) != OK) {
      (void) fprintf(stderr, "Error writing file \"%s\"\n", lambda_file);
      return FALSE;
   }

   return TRUE;
}