Ejemplo n.º 1
0
int write_minc(char *filename, float *image, image_metadata *meta,VIO_BOOL binary_mask){
  VIO_Volume volume;
  int i,j,k,index;
  float min=FLT_MAX,max=FLT_MIN;
  VIO_Real dummy[3];

  if(binary_mask)
  {
    volume = create_volume(3,NULL,NC_BYTE,FALSE,0.0,1.0);
    printf("Writing a binary volume...\n");
  }
  else 
    volume = create_volume(3,NULL,NC_FLOAT,FALSE,FLT_MIN,FLT_MAX);
  
  if(!volume)
    return STATUS_ERR;
  
  if(!binary_mask)
  {
    for (i=0;i<meta->length[0];i++){
      for (j=0;j<meta->length[1];j++){
        for (k=0;k<meta->length[2];k++){	  
          index=i*meta->length[2]*meta->length[1] + j*meta->length[2] + k;
          min=MIN(min,image[index]);
          max=MAX(max,image[index]);
        }
      }
    }
    set_volume_real_range(volume,min,max);
  } else {
    set_volume_real_range(volume,0.0,1.0);
  }
  
  set_volume_sizes(volume,meta->length);
  dummy[0]=meta->start[0];
  dummy[1]=meta->start[1];
  dummy[2]=meta->start[2];
  set_volume_starts(volume,dummy);
  dummy[0]=meta->step[0];
  dummy[1]=meta->step[1];
  dummy[2]=meta->step[2];
  set_volume_separations(volume,dummy);

  alloc_volume_data(volume);
    
  get_volume(image, volume, meta->length);

  if(!binary_mask)
    output_volume( filename, NC_FLOAT,FALSE,min, max,volume,meta->history,(minc_output_options *)NULL);
  else
    output_volume( filename, NC_BYTE,FALSE,0, 1.0,volume,meta->history,(minc_output_options *)NULL);
    
  delete_volume(volume);

  return STATUS_OK;
}
Ejemplo n.º 2
0
int write_volume(char *name, VIO_Volume vol, float *data){
  int i,j,k,index,sizes[5];
  float min=FLT_MAX,max=FLT_MIN;

  fprintf(stderr,"Writing %s\n",name);

  get_volume_sizes(vol,sizes);

  for (i=0;i<sizes[0];i++){
    for (j=0;j<sizes[1];j++){
      for (k=0;k<sizes[2];k++){	  
	index=i*sizes[2]*sizes[1] + j*sizes[2] + k;
	min=MIN(min,data[index]);
	max=MAX(max,data[index]);
      }
    }
  }
  
  set_volume_real_range(vol,min,max);

  get_volume(data, vol, sizes);

  output_volume( name, NC_FLOAT,FALSE,min,max,vol,NULL, (minc_output_options *)NULL);

  return STATUS_OK;
}
Ejemplo n.º 3
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);
   }
Ejemplo n.º 4
0
/* ----------------------------- MNI Header -----------------------------------
@NAME       :  compute_chamfer
@INPUT/OUTPUT: chamfer
                   The original input volume will be destroyed and replaced
                   with the resulting chamfer distance volume.  The chamfer
                   will contains 0's where the mask was and values > 0.0
                   for all other voxels, where the value is an estimate of
                   the distance to the the nearest voxel of the mask.
@RETURNS    : ERROR if error, OK otherwise
@DESCRIPTION: Uses an idea from georges, who got it from claire, 
              who got it from Borgefors
@GLOBALS    : 
@CALLS      : 
@CREATED    : Nov 2, 1998 Louis
@MODIFIED   : 
---------------------------------------------------------------------------- */
VIO_Status compute_chamfer(VIO_Volume chamfer, VIO_Real max_val)
{

   VIO_Real
      mask_f[3][3][3],
      mask_b[3][3][3],
      zero, min,
      vox_min, vox_max,
      val, val2;
   int
      sizes[VIO_MAX_DIMENSIONS],
      i,j,k,
      ind0,ind1,ind2;
   
   VIO_progress_struct 
      progress;
   
   get_volume_sizes(chamfer, sizes);

   get_volume_voxel_range(chamfer, &vox_min, &vox_max);

   zero = CONVERT_VALUE_TO_VOXEL(chamfer,0.0);
   
   /* init chamfer to be  binary valued with 0.0 on the object,
      and infinity (or vox_max) elsewhere */
   
   if (debug) print ("initing chamfer vol (%d %d %d)\n",sizes[0],sizes[1],sizes[2]);
   for(ind0=0; ind0<sizes[0]; ind0++) {
      for(ind1=0; ind1<sizes[1]; ind1++) {
         for(ind2=0; ind2<sizes[2]; ind2++) {
            
            GET_VOXEL_3D(val, chamfer, ind0, ind1, ind2);
            if (val == zero) {
               SET_VOXEL_3D(chamfer, ind0, ind1, ind2, vox_max ); 
            }            
            else {
               SET_VOXEL_3D(chamfer, ind0, ind1, ind2, vox_min); 
            }
            
         }
      }
   }

   if (debug) print ("building mask\n");

   build_mask(chamfer, mask_f, mask_b);

   set_volume_real_range(chamfer, 0.0, max_val);
   zero = CONVERT_VALUE_TO_VOXEL(chamfer,0.0);

   if (verbose) initialize_progress_report( &progress, TRUE, sizes[0], 
                                           "forward pass");
   
   for(ind0=1; ind0<sizes[0]-1; ind0++) {
      for(ind1=1; ind1<sizes[1]-1; ind1++) {
         for(ind2=1; ind2<sizes[2]-1; ind2++) {

            GET_VALUE_3D(val, chamfer, ind0, ind1, ind2);
            
            if (val != zero) { /* then apply forward mask */

               min = val;

               for(i=-1; i<=+1; i++) {
                  for(j=-1; j<=+1; j++) {
                     for(k=-1; k<=+1; k++) {
                        
                        GET_VALUE_3D(val, chamfer, i+ind0, j+ind1, k+ind2);
                        
                        val2 = val + mask_f[i+1][j+1][k+1];
                        min = MIN (min, val2);
                        
                     }
                  }
               }
                           
               min = convert_value_to_voxel(chamfer, min);

               SET_VOXEL_3D(chamfer, ind0, ind1, ind2, min );              
               
            } /* if val != 0.0 */
            
         } /* ind2 */
      } /* ind1 */
      if (verbose) update_progress_report( &progress, ind0+1 );
   } /* ind0 */
   
   if (verbose) terminate_progress_report( &progress );


   if (verbose) initialize_progress_report( &progress, TRUE, sizes[0], 
                                           "reverse pass");
       
   for(ind0=sizes[0]-2; ind0>=1; ind0--) {
      for(ind1=sizes[1]-2; ind1>=1; ind1--) {
         for(ind2=sizes[2]-2; ind2>=1; ind2--) {
            
            GET_VALUE_3D(val, chamfer, ind0, ind1, ind2);
            
            if (val != zero) { /* then apply backwardmask */
                                
               min = val;

               for(i=-1; i<=1; i++) {
                  for(j=-1; j<=+1; j++) {
                     for(k=-1; k<=+1; k++) {
                        
                        GET_VALUE_3D(val, chamfer, i+ind0, j+ind1, k+ind2);
                        
                        val2 = val + mask_b[i+1][j+1][k+1];
                        min = MIN (min, val2);
                        
                     }
                  }
               }
                           
               min = convert_value_to_voxel(chamfer, min);

               SET_VOXEL_3D(chamfer, ind0, ind1, ind2, min );              
               
            } /* if val != 0.0 */
            
         } /* ind2 */
      } /* ind1 */
      if (verbose) update_progress_report( &progress, ind0+1 );
   } /* ind0 */
   
   if (verbose) terminate_progress_report( &progress );
   
   return (OK);
   
}
Ejemplo n.º 5
0
VIO_Status gradient3D_volume(FILE *ifd, 
                                VIO_Volume data, 
                                int xyzv[VIO_MAX_DIMENSIONS],
                                char *infile,
                                char *outfile, 
                                int ndim,
                                char *history,
                                int curvature_flg)

{ 
  float 
    *fdata,                        /* floating point storage for blurred volume */
    *f_ptr,                        /* pointer to fdata */
    tmp,
    max_val, 
    min_val,
    
    *dat_vector,                /* temp storage of original row, col or slice vect. */
    *dat_vecto2,                /* storage of result of dat_vector*kern                 */
    *kern;                        /* convolution kernel                               */
  int                                
    total_voxels,                
    vector_size_data,                /* original size of row, col or slice vector        */
    array_size_pow2,                /* actual size of vector/kernel data used in FFT    */
                                /* routines - needs to be a power of two            */
    array_size;

  int   
    data_offset;                /* offset required to place original data (size n)  */
                                /*  into array (size m=2^n) so that data is centered*/

  register int 
    slice_limit,
    row,col,slice,                /* counters to access original data                 */
    vindex;                        /* counter to access vector and vecto2              */

  int 
    slice_size,                        /* size of each data step - in bytes                */
    row_size, col_size;
                

  char
    full_outfilename[256];        /* name of output file */

  progress_struct 
    progress;                        /* used to monitor progress of calculations         */

  VIO_Status 
    status;
  
  int
    sizes[3],                        /* number of rows, cols and slices */
    pos[3];                          /* Input order of rows, cols, slices */

  VIO_Real
    steps[3];                        /* size of voxel step from center to center in x,y,z */

  /*---------------------------------------------------------------------------------*/
  /*             start by setting up the raw data.                                   */
  /*---------------------------------------------------------------------------------*/



  get_volume_sizes(data, sizes);          /* rows,cols,slices */
  get_volume_separations(data, steps);
  
  slice_size = sizes[xyzv[VIO_Y]] * sizes[xyzv[VIO_X]];    /* sizeof one slice  */
  col_size   = sizes[xyzv[VIO_Y]];               /* sizeof one column */
  row_size   = sizes[xyzv[VIO_X]];               /* sizeof one row    */
  
  total_voxels = sizes[xyzv[VIO_Y]]*sizes[xyzv[VIO_X]]*sizes[xyzv[VIO_Z]];
  
  ALLOC(fdata, total_voxels);
  f_ptr = fdata;

         /* read in data of input file. */

  set_file_position(ifd,(long)0);
  status = io_binary_data(ifd,READ_FILE, fdata, sizeof(float), total_voxels);
  if (status != OK)
    print_error_and_line_num("problems reading binary data...\n",__FILE__, __LINE__);


  /*--------------------------------------------------------------------------------------*/
  /*                get ready to start up the transformation.                             */
  /*--------------------------------------------------------------------------------------*/
  
  initialize_progress_report( &progress, FALSE, sizes[xyzv[VIO_Z]] + sizes[xyzv[VIO_Y]] + sizes[xyzv[VIO_X]] + 1,
                             "Gradient volume" );


  /* note data is stored by rows (along x), then by cols (along y) then slices (along z) */
  

  /*--------------------------------------------------------------------------------------*/
  /*                start with rows - i.e. the d/dx volume                                */
  /*--------------------------------------------------------------------------------------*/
  
  /*-----------------------------------------------------------------------------*/
  /*             determine   size of data structures needed                      */
  
  vector_size_data = sizes[xyzv[VIO_X]]; 
  
  /*             array_size_pow2 will hold the size of the arrays for FFT convolution,
                 remember that ffts require arrays 2^n in length                          */
  
  array_size_pow2  = next_power_of_two(vector_size_data);
  array_size = 2*array_size_pow2+1;  /* allocate 2*, since each point is a    */
                                     /* complex number for FFT, and the plus 1*/
                                     /* is for the zero offset FFT routine    */

  ALLOC(dat_vector, array_size);
  ALLOC(dat_vecto2, array_size);
  ALLOC(kern      , array_size);
  
  /*    1st calculate kern array for FT of 1st derivitive */
  
  make_kernel_FT(kern,array_size_pow2, ABS(steps[xyzv[VIO_X]]));

  if (curvature_flg)                /* 2nd derivative kernel */
    muli_vects(kern,kern,kern,array_size_pow2);

  /*    calculate offset for original data to be placed in vector            */
  
  data_offset = (array_size_pow2-sizes[xyzv[VIO_X]])/2;
  
  max_val = -FLT_MAX;
  min_val =  FLT_MAX;


  /*    2nd now convolve this kernel with the rows of the dataset            */  
  
  slice_limit = 0;
  switch (ndim) {
  case 1: slice_limit = 0; break;
  case 2: slice_limit = sizes[xyzv[VIO_Z]]; break;
  case 3: slice_limit = sizes[xyzv[VIO_Z]]; break;
  }


  for (slice = 0; slice < slice_limit; slice++) {      /* for each slice */
    
    for (row = 0; row < sizes[xyzv[VIO_Y]]; row++) {           /* for each row   */
      
      f_ptr = fdata + slice*slice_size + row*sizes[xyzv[VIO_X]];
      memset(dat_vector,0,(2*array_size_pow2+1)*sizeof(float));
      
      for (col=0; col< sizes[xyzv[VIO_X]]; col++) {        /* extract the row */
        dat_vector[1 +2*(col+data_offset)  ] = *f_ptr++;
      }
      
      fft1(dat_vector,array_size_pow2,1);
      muli_vects(dat_vecto2,dat_vector,kern,array_size_pow2);
      fft1(dat_vecto2,array_size_pow2,-1);
      
      f_ptr = fdata + slice*slice_size + row*sizes[xyzv[VIO_X]];
      for (col=0; col< sizes[xyzv[VIO_X]]; col++) {        /* put the row back */
        
        vindex = 1 + 2*(col+data_offset);
       *f_ptr = dat_vecto2[vindex]/array_size_pow2;


        if (max_val<*f_ptr) max_val = *f_ptr;
        if (min_val>*f_ptr) min_val = *f_ptr;


        f_ptr++;
      }
      
      
    }
    update_progress_report( &progress, slice+1 );
  }
  
  FREE(dat_vector);
  FREE(dat_vecto2);
  FREE(kern      );
    

  f_ptr = fdata;

  set_volume_real_range(data, min_val, max_val);
  
  
  printf("Making byte volume dx..." );
  for(slice=0; slice<sizes[xyzv[VIO_Z]]; slice++) {
    pos[xyzv[VIO_Z]] = slice;
    for(row=0; row<sizes[xyzv[VIO_Y]]; row++) {
      pos[xyzv[VIO_Y]] = row;
      for(col=0; col<sizes[xyzv[VIO_X]]; col++) {
        pos[xyzv[VIO_X]] = col;
        tmp = CONVERT_VALUE_TO_VOXEL(data, *f_ptr);
        SET_VOXEL_3D( data, pos[0], pos[1], pos[2], tmp);
        f_ptr++;
      }
    }
  }


  if (!curvature_flg)
    sprintf(full_outfilename,"%s_dx.mnc",outfile);
  else
    sprintf(full_outfilename,"%s_dxx.mnc",outfile);

  if (debug)
    print ("dx: min = %f, max = %f\n",min_val, max_val);

  status = output_modified_volume(full_outfilename, NC_UNSPECIFIED, FALSE, 
                                  min_val, max_val, data, infile, history, NULL);

  if (status != OK)
    print_error_and_line_num("problems writing dx gradient data...\n",__FILE__, __LINE__);


  
  /*--------------------------------------------------------------------------------------*/
  /*                 now do cols - i.e. the d/dy volume                                   */
  /*--------------------------------------------------------------------------------------*/
  
  /*-----------------------------------------------------------------------------*/
  /*             determine   size of data structures needed                      */
  

  set_file_position(ifd,0);
  status = io_binary_data(ifd,READ_FILE, fdata, sizeof(float), total_voxels);
  if (status != OK)
    print_error_and_line_num("problems reading binary data...\n",__FILE__, __LINE__);




  
  f_ptr = fdata;

  vector_size_data = sizes[xyzv[VIO_Y]];
  
  /*             array_size_pow2 will hold the size of the arrays for FFT convolution,
                 remember that ffts require arrays 2^n in length                          */
  
  array_size_pow2  = next_power_of_two(vector_size_data);
  array_size = 2*array_size_pow2+1;  /* allocate 2*, since each point is a    */
                                     /* complex number for FFT, and the plus 1*/
                                     /* is for the zero offset FFT routine    */
  
  ALLOC(dat_vector, array_size);
  ALLOC(dat_vecto2, array_size);
  ALLOC(kern      , array_size);
  
  /*    1st calculate kern array for FT of 1st derivitive */
  
  make_kernel_FT(kern,array_size_pow2, ABS(steps[xyzv[VIO_Y]]));
  
  if (curvature_flg)                /* 2nd derivative kernel */
    muli_vects(kern,kern,kern,array_size_pow2);

  /*    calculate offset for original data to be placed in vector            */
  
  data_offset = (array_size_pow2-sizes[xyzv[VIO_Y]])/2;
  
  /*    2nd now convolve this kernel with the rows of the dataset            */
  
  max_val = -FLT_MAX;
  min_val =  FLT_MAX;

  switch (ndim) {
  case 1: slice_limit = 0; break;
  case 2: slice_limit = sizes[xyzv[VIO_Z]]; break;
  case 3: slice_limit = sizes[xyzv[VIO_Z]]; break;
  }

  for (slice = 0; slice < slice_limit; slice++) {      /* for each slice */
    
    for (col = 0; col < sizes[xyzv[VIO_X]]; col++) {           /* for each col   */
      
      /*         f_ptr = fdata + slice*slice_size + row*sizeof(float); */
      
      f_ptr = fdata + slice*slice_size + col;
      
      
      memset(dat_vector,0,(2*array_size_pow2+1)*sizeof(float));
      
      for (row=0; row< sizes[xyzv[VIO_Y]]; row++) {        /* extract the col */
        dat_vector[1 +2*(row+data_offset) ] = *f_ptr;
        f_ptr += row_size;
      }
      
      
      fft1(dat_vector,array_size_pow2,1);
      muli_vects(dat_vecto2,dat_vector,kern,array_size_pow2);
      fft1(dat_vecto2,array_size_pow2,-1);
      
      f_ptr = fdata + slice*slice_size + col;
      for (row=0; row< sizes[xyzv[VIO_Y]]; row++) {        /* put the col back */
        
        vindex = 1 + 2*(row+data_offset);
        
        *f_ptr = dat_vecto2[vindex]/array_size_pow2;
        
        if (max_val<*f_ptr) max_val = *f_ptr;
        if (min_val>*f_ptr) min_val = *f_ptr;

        f_ptr += row_size;
        
        
      }
      
    }
    update_progress_report( &progress, slice+sizes[xyzv[VIO_Z]]+1 );
    
  }
  
  FREE(dat_vector);
  FREE(dat_vecto2);
  FREE(kern      );
  
  f_ptr = fdata;
  
  set_volume_real_range(data, min_val, max_val);


  printf("Making byte volume dy..." );
  for(slice=0; slice<sizes[xyzv[VIO_Z]]; slice++) {
    pos[xyzv[VIO_Z]] = slice;
    for(row=0; row<sizes[xyzv[VIO_Y]]; row++) {
      pos[xyzv[VIO_Y]] = row;
      for(col=0; col<sizes[xyzv[VIO_X]]; col++) {
        pos[xyzv[VIO_X]] = col;
        tmp = CONVERT_VALUE_TO_VOXEL(data, *f_ptr);
        SET_VOXEL_3D( data, pos[0], pos[1], pos[2], tmp);
        f_ptr++;
      }
    }
  }

  if (!curvature_flg)
    sprintf(full_outfilename,"%s_dy.mnc",outfile);
  else
    sprintf(full_outfilename,"%s_dyy.mnc",outfile);


  if (debug)
    print ("dy: min = %f, max = %f\n",min_val, max_val);

  status = output_modified_volume(full_outfilename, NC_UNSPECIFIED, FALSE, 
                                  min_val, max_val, data, infile, history, NULL);
  if (status != OK)
    print_error_and_line_num("problems writing dy gradient data...",__FILE__, __LINE__);
  
  
  /*--------------------------------------------------------------------------------------*/
  /*                 now do slices - i.e. the d/dz volume                                 */
  /*--------------------------------------------------------------------------------------*/
  
  /*-----------------------------------------------------------------------------*/
  /*             determine   size of data structures needed                      */


  set_file_position(ifd,0);
  status = io_binary_data(ifd,READ_FILE, fdata, sizeof(float), total_voxels);
  if (status != OK)
    print_error_and_line_num("problems reading binary data...\n",__FILE__, __LINE__);
  f_ptr = fdata;
  
  vector_size_data = sizes[xyzv[VIO_Z]];

  /*             array_size_pow2 will hold the size of the arrays for FFT convolution,
                 remember that ffts require arrays 2^n in length                          */
  
  array_size_pow2  = next_power_of_two(vector_size_data);
  array_size = 2*array_size_pow2+1;  /* allocate 2*, since each point is a    */
                                     /* complex number for FFT, and the plus 1*/
                                     /* is for the zero offset FFT routine    */
  
  ALLOC(dat_vector, array_size);
  ALLOC(dat_vecto2, array_size);
  ALLOC(kern      , array_size);

  if (ndim==1 || ndim==3) {
    
    /*    1st calculate kern array for FT of 1st derivitive */
    
    make_kernel_FT(kern,array_size_pow2, ABS(steps[xyzv[VIO_Z]]));

    if (curvature_flg)                /* 2nd derivative kernel */
      muli_vects(kern,kern,kern,array_size_pow2);
    
    /*    calculate offset for original data to be placed in vector            */
    
    data_offset = (array_size_pow2-sizes[xyzv[VIO_Z]])/2;
    
    /*    2nd now convolve this kernel with the slices of the dataset            */
    
    max_val = -FLT_MAX;
    min_val =  FLT_MAX;
    
    
    for (col = 0; col < sizes[xyzv[VIO_X]]; col++) {      /* for each column */
      
      for (row = 0; row < sizes[xyzv[VIO_Y]]; row++) {           /* for each row   */
        
        f_ptr = fdata + col*col_size + row;
        
        memset(dat_vector,0,(2*array_size_pow2+1)*sizeof(float));
        
        for (slice=0; slice< sizes[xyzv[VIO_Z]]; slice++) {        /* extract the slice vector */
          dat_vector[1 +2*(slice+data_offset) ] = *f_ptr;
          f_ptr += slice_size;
        }
        
        fft1(dat_vector,array_size_pow2,1);
        muli_vects(dat_vecto2,dat_vector,kern,array_size_pow2);
        fft1(dat_vecto2,array_size_pow2,-1);
        
        f_ptr = fdata + col*col_size + row;
        
        for (slice=0; slice< sizes[xyzv[VIO_Z]]; slice++) {        /* put the vector back */
          
          vindex = 1 + 2*(slice+data_offset);
          
          *f_ptr = dat_vecto2[vindex]/array_size_pow2;
          
          if (max_val<*f_ptr) max_val = *f_ptr;
          if (min_val>*f_ptr) min_val = *f_ptr;
          
          f_ptr += slice_size;
        }
        
        
      }
      update_progress_report( &progress, col + 2*sizes[xyzv[VIO_Z]] + 1 );
      
    }
    
  }  /* if ndim */
  else {
    max_val = 0.00001;
    min_val = 0.00000;
    
    for (col = 0; col < sizes[xyzv[VIO_X]]; col++) {      /* for each column */
      for (row = 0; row < sizes[xyzv[VIO_Y]]; row++) {           /* for each row   */
        *f_ptr = 0.0;
        f_ptr++;
      }
    }
  }
  
  
  FREE(dat_vector);
  FREE(dat_vecto2);
  FREE(kern      );
  
  
/* set up the correct info to copy the data back out in mnc */

  f_ptr = fdata;
  
  set_volume_real_range(data, min_val, max_val);


  printf("Making byte volume dz..." );
  for(slice=0; slice<sizes[xyzv[VIO_Z]]; slice++) {
    pos[xyzv[VIO_Z]] = slice;
    for(row=0; row<sizes[xyzv[VIO_Y]]; row++) {
      pos[xyzv[VIO_Y]] = row;
      for(col=0; col<sizes[xyzv[VIO_X]]; col++) {
        pos[xyzv[VIO_X]] = col;
        tmp = CONVERT_VALUE_TO_VOXEL(data, *f_ptr);
        SET_VOXEL_3D( data, pos[0], pos[1], pos[2], tmp);
        f_ptr++;
      }
    }
  }

  if (!curvature_flg)
    sprintf(full_outfilename,"%s_dz.mnc",outfile);
  else
    sprintf(full_outfilename,"%s_dzz.mnc",outfile);


  if (debug)
    print ("dz: min = %f, max = %f\n",min_val, max_val);

  status = output_modified_volume(full_outfilename, NC_UNSPECIFIED, FALSE, 
                                  min_val, max_val, data, infile, history, NULL);

  if (status != OK)
    print_error_and_line_num("problems writing dz gradient data...",__FILE__, __LINE__);



  terminate_progress_report( &progress );

  FREE(fdata);

  return(status);
  
}
Ejemplo n.º 6
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);

}
Ejemplo n.º 7
0
void normalize_data_to_match_target(VIO_Volume d1, VIO_Volume m1, VIO_Real thresh1,
                                           VIO_Volume d2, VIO_Volume m2, VIO_Real thresh2,
                                           Arg_Data *globals)
{

  VectorR
    vector_step;

  PointR
    starting_position,
    slice,
    row,
    col,
    pos2,
    voxel;

  double
    tx,ty,tz;
  int
    i,j,k,
    r,c,s;

  VIO_Real
    min_range, max_range,
    data_vox, data_val,
    value1, value2;
  
  VIO_Real
    t1,t2,                        /* temporary threshold values     */
    s1,s2,s3;                   /* to store the sums for f1,f2,f3 */
  float 
    *ratios,
    result;                                /* the result */
  int 
    sizes[VIO_MAX_DIMENSIONS],ratios_size,count1,count2;

  VIO_Volume 
    vol;

  VIO_progress_struct
    progress;

  VIO_Data_types 
    data_type;


  set_feature_value_threshold(d1,d2, 
                              &thresh1, &thresh2,
                              &t1,      &t2);                              

  if (globals->flags.debug) {
    print ("In normalize_data_to_match_target, thresh = %10.3f %10.3f\n",t1,t2) ;
  }

  ratios_size = globals->count[ROW_IND] * globals->count[COL_IND] * globals->count[SLICE_IND];

  ALLOC(ratios, ratios_size);  

  fill_Point( starting_position, globals->start[VIO_X], globals->start[VIO_Y], globals->start[VIO_Z]);

  s1 = s2 = s3 = 0.0;
  count1 = count2 = 0;

  for(s=0; s<=globals->count[SLICE_IND]; s++) {

    SCALE_VECTOR( vector_step, globals->directions[SLICE_IND], s);
    ADD_POINT_VECTOR( slice, starting_position, vector_step );

    for(r=0; r<=globals->count[ROW_IND]; r++) {
      
      SCALE_VECTOR( vector_step, globals->directions[ROW_IND], r);
      ADD_POINT_VECTOR( row, slice, vector_step );
      
      SCALE_POINT( col, row, 1.0); /* init first col position */
      for(c=0; c<=globals->count[COL_IND]; c++) {
        
        convert_3D_world_to_voxel(d1, Point_x(col), Point_y(col), Point_z(col), &tx, &ty, &tz);
        
        fill_Point( voxel, tx, ty, tz ); /* build the voxel POINT */
        
        if (point_not_masked(m1, Point_x(col), Point_y(col), Point_z(col))) {

          value1 = get_value_of_point_in_volume( Point_x(col), Point_y(col), Point_z(col), d1);

          if ( value1 > t1 ) {

            count1++;

            DO_TRANSFORM(pos2, globals->trans_info.transformation, col);
            
            convert_3D_world_to_voxel(d2, Point_x(pos2), Point_y(pos2), Point_z(pos2), &tx, &ty, &tz);
            
            fill_Point( voxel, tx, ty, tz ); /* build the voxel POINT */
        
            if (point_not_masked(m2, Point_x(pos2), Point_y(pos2), Point_z(pos2))) {

              value2 = get_value_of_point_in_volume( Point_x(pos2), Point_y(pos2), Point_z(pos2), d2);

              if ( (value2 > t2)  && 
                   ((value2 < -1e-15) || (value2 > 1e-15)) ) {
                  
                ratios[count2++] = value1 / value2 ;

                s1 += value1*value2;
                s2 += value1*value1;
                s3 += value2*value2;
                  
                
              } /* if voxel in d2 */
            } /* if point in mask volume two */
          } /* if voxel in d1 */
        } /* if point in mask volume one */
        
        ADD_POINT_VECTOR( col, col, globals->directions[COL_IND] );
        
      } /* for c */
    } /* for r */
  } /* for s */
  

  if (count2 > 0) {

    if (globals->flags.debug) (void)print ("Starting qsort of ratios...");


    qs_list (ratios,0,count2);

    if (globals->flags.debug) (void)print ("Done.\n");

    result = ratios[ (int)(count2/2) ];        /* the median value */

    if (globals->flags.debug) (void)print ("Normalization: %7d %7d -> %10.8f\n",count1,count2,result);

    if ( fabs(result) < 1e-15) {
      print_error_and_line_num("Error computing normalization ratio `%f'.",__FILE__, __LINE__, result);
    }
    else {

      data_type = get_volume_data_type(d1);



      
      switch( data_type ) {
      case SIGNED_BYTE: 
      case UNSIGNED_BYTE: 
      case SIGNED_SHORT: 
      case UNSIGNED_SHORT: 
	
	/* build temporary working volume */
	
	vol = copy_volume_definition_no_alloc(d1, NC_UNSPECIFIED, FALSE, 0.0, 0.0);
	get_volume_minimum_maximum_real_value(d1, &min_range, &max_range);
	min_range /= result;
	max_range /= result;
	set_volume_real_range(vol, min_range, max_range);
	get_volume_sizes(d1, sizes);
	
	initialize_progress_report(&progress, FALSE, sizes[0]*sizes[1]*sizes[2] + 1,
				   "Normalizing source data" );
	count1 = 0;
	
	/* reset values in the data volume */
	
	for(i=0; i<sizes[0]; i++)
	  for(j=0; j<sizes[1]; j++) {
	    count1++;
	    update_progress_report( &progress, count1);
	    for(k=0; k<sizes[2]; k++) {
	      GET_VOXEL_3D( data_vox,  d1, i, j, k );
	      data_val = CONVERT_VOXEL_TO_VALUE(d1, data_vox);
	      data_val /= result;
	      data_vox = CONVERT_VALUE_TO_VOXEL( vol, data_val);
	      SET_VOXEL_3D( d1 , i, j, k, data_vox );
	    }
	  }
	
	terminate_progress_report( &progress );
	
	set_volume_real_range(d1, min_range, max_range);
	
	if (globals->flags.debug) (void)print ("After normalization min,max, thresh = %f %f %f\n",
					       min_range, max_range, t1/result);
	
	delete_volume(vol);
	break;
	
      default:			/* then volume should be either float or double */
	
	get_volume_sizes(d1, sizes);
	initialize_progress_report(&progress, FALSE, sizes[0]*sizes[1]*sizes[2] + 1,
				   "Normalizing source data" );
	count1 = 0;
	
	/* nomalize the values in the data volume */
	
	for(i=0; i<sizes[0]; i++)
	  for(j=0; j<sizes[1]; j++) {
	    count1++;
	    update_progress_report( &progress, count1);
	    
	    for(k=0; k<sizes[2]; k++) {	/* it should be possible to directly stream through the voxels, without indexing... */
	      GET_VOXEL_3D( data_vox,  d1, i, j, k );
	      data_val = CONVERT_VOXEL_TO_VALUE(d1, data_vox);
	      data_val /= result;
	      data_vox = CONVERT_VALUE_TO_VOXEL( d1, data_val);
	      SET_VOXEL_3D( d1 , i, j, k, data_vox );
	    }
	  }
	terminate_progress_report( &progress );
      }
    }
    
  }
  FREE(ratios);

  
}
Ejemplo n.º 8
0
void make_zscore_volume(VIO_Volume d1, VIO_Volume m1, 
                               VIO_Real *threshold)
{
  unsigned long
    count;
  int 
    stat_count,
    sizes[VIO_MAX_DIMENSIONS],
    s,r,c;
  VIO_Real
    wx,wy,wz,
    valid_min_dvoxel, valid_max_dvoxel,
    min,max,
    sum, sum2, mean, var, std,
    data_vox,data_val,
    thick[VIO_MAX_DIMENSIONS];

  PointR 
    voxel;

  VIO_Volume 
    vol;

  VIO_progress_struct
    progress;

  /* get default information from data and mask */

  /* build temporary working volume */
 
  vol = copy_volume_definition(d1, NC_UNSPECIFIED, FALSE, 0.0, 0.0);
  set_volume_real_range(vol, MIN_ZRANGE, MAX_ZRANGE);
  get_volume_sizes(d1, sizes);
  get_volume_separations(d1, thick);
  get_volume_voxel_range(d1, &valid_min_dvoxel, &valid_max_dvoxel);

  /* initialize counters and sums */

  count  = 0;
  sum  = 0.0;
  sum2 = 0.0;
  min = 1e38;
  max = -1e38;
  stat_count = 0;

  initialize_progress_report(&progress, FALSE, sizes[0]*sizes[1]*sizes[2] + 1,
                             "Tally stats" );

                                /* do first pass, to get mean and std */
  for(s=0; s<sizes[0]; s++) {
    for(r=0; r<sizes[1]; r++) {
      for(c=0; c<sizes[2]; c++) {

        stat_count++;
        update_progress_report( &progress, stat_count);
        convert_3D_voxel_to_world(d1, (VIO_Real)s, (VIO_Real)r, (VIO_Real)c, &wx, &wy, &wz);

        if (m1 != NULL) {
          convert_3D_world_to_voxel(m1, wx, wy, wz, &Point_x(voxel), &Point_y(voxel), &Point_z(voxel));
        }
        else {
          wx = 0.0; wy = 0.0; wz = 0.0;
        }

        if (point_not_masked(m1, wx,wy,wz)) {
          
          GET_VOXEL_3D( data_vox,  d1 , s, r, c );

          if (data_vox >= valid_min_dvoxel && data_vox <= valid_max_dvoxel) { 

            data_val = CONVERT_VOXEL_TO_VALUE(d1, data_vox);
            
            if (data_val > *threshold) {
              sum  += data_val;
              sum2 += data_val*data_val;
              
              count++;
              
              if (data_val < min)
                min = data_val;
              else
                if (data_val > max)
                  max = data_val;
            }
          }
        }
      }
    }
  }
  terminate_progress_report( &progress );

  stat_count = 0;
  initialize_progress_report(&progress, FALSE, sizes[0]*sizes[1]*sizes[2] + 1,
                             "Zscore convert" );

                                /* calc mean and std */
  mean = sum / (float)count;
  var  = ((float)count*sum2 - sum*sum) / ((float)count*((float)count-1));
  std  = sqrt(var);

  min = 1e38;
  max = -1e38;

                                /* replace the voxel values */
  for(s=0; s<sizes[0]; s++) {
    for(r=0; r<sizes[1]; r++) {
      for(c=0; c<sizes[2]; c++) {
        
        stat_count++;
        update_progress_report( &progress, stat_count);

        GET_VOXEL_3D( data_vox,  d1, s, r, c );
        
        if (data_vox >= valid_min_dvoxel && data_vox <= valid_max_dvoxel) { 
          
          data_val = CONVERT_VOXEL_TO_VALUE(d1, data_vox);
          
          if (data_val > *threshold) {

                                /* instead of   
                                   data_val = CONVERT_VALUE_TO_VOXEL(d1, data_vox);
                                   i will use
                                   data_val = CONVERT_VALUE_TO_VOXEL(d1, vol);

                                   since the values in vol are changed with respect to the
                                   new z-score volume */

            data_val = (data_val - mean) / std;
            if (data_val< MIN_ZRANGE) data_val = MIN_ZRANGE;
            if (data_val> MAX_ZRANGE) data_val = MAX_ZRANGE;

            data_vox = CONVERT_VALUE_TO_VOXEL( vol, data_val);
            

            if (data_val < min) {
              min = data_val;
            }
            else {
              if (data_val > max)
                max = data_val;
            }
          }
          else
            data_vox = -DBL_MAX;   /* should be fill_value! */
          
          SET_VOXEL_3D( d1 , s, r, c, data_vox );
        }
        
      }
    }
  }

  terminate_progress_report( &progress );

  set_volume_real_range(d1, MIN_ZRANGE, MAX_ZRANGE);        /* reset the data volume's range */

  *threshold = (*threshold - mean) / std;

  delete_volume(vol);
  
}
Ejemplo n.º 9
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);
   }
Ejemplo n.º 10
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);
   }
Ejemplo n.º 11
0
int main(int argc, char *argv[])
{
   VIO_Volume 
     volume;
   VIO_Real
     variability,
     rand_val,
     voxel[VIO_MAX_DIMENSIONS];
   int 
     progress_count,
     sizes[VIO_MAX_DIMENSIONS],
     index[VIO_MAX_DIMENSIONS],
     i,j,k;
   VIO_progress_struct
     progress;

   union
     {
       long   l;
       char   c[4];
     } seedval;
   
   time_t t;
   char tmp;

   prog_name = argv[0];


   /* Check arguments */
   if (argc != 4) {
      (void) fprintf(stderr, "Usage: %s input.mnc output.mnc std_dev\n",
                     argv[0]);
      exit(EXIT_FAILURE);
   }


   if( input_volume( argv[1], 3, NULL, NC_UNSPECIFIED, FALSE,
                    0.0, 0.0, TRUE, &volume, (minc_input_options *)NULL ) != OK ) {
     (void)fprintf(stderr, "Error opening input volume file %s.\n",
                   argv[1]);
     exit(EXIT_FAILURE);
   }

   variability = atof( argv[3] );

                                /* initialize drand function */
   t = 2*time(NULL);
   seedval.l = t; 
   tmp = seedval.c[0]; seedval.c[0] = seedval.c[3]; seedval.c[3] = tmp; 
   tmp = seedval.c[1]; seedval.c[1] = seedval.c[2]; seedval.c[2] = tmp;
   srand48(seedval.l);



   set_volume_real_range(volume, -5.0*variability, 5.0*variability);

   get_volume_sizes(volume,sizes);
   initialize_progress_report(&progress, FALSE, 
                              sizes[VIO_X]*sizes[VIO_Y]*sizes[VIO_Z]+1,
                              "Randomizing volume");
   progress_count = 0;


   for(i=0; i<MAX_DIMENSIONS; i++) index[i] = 0;

   /* loop over all voxels */
   for(index[X]=0; index[X]<sizes[X]; index[X]++)
     for(index[Y]=0; index[Y]<sizes[Y]; index[Y]++)
       for(index[Z]=0; index[Z]<sizes[Z]; index[Z]++) {
             
         /* get a random value from a gaussian distribution  */

         rand_val = variability * gaussian_random_0_1();

         if (rand_val >  5.0*variability) rand_val =  5.0*variability;
         if (rand_val < -5.0*variability) rand_val = -5.0*variability;
         
         set_volume_real_value(volume,
                               index[0],index[1],index[2],index[3],index[4],
                               rand_val);
         
         progress_count++;
         update_progress_report(&progress, progress_count);
       }
   
   terminate_progress_report(&progress);

   

   /* Write out the random volume */
   if (output_volume(argv[2], NC_UNSPECIFIED, FALSE, 0.0, 0.0, volume, 
                     (char *)NULL, (minc_output_options *)NULL) != OK) {
     (void) fprintf(stderr, "%s: Error writing volume file %s\n",
                     argv[0], argv[2]);
      exit(EXIT_FAILURE);
   }

   exit(EXIT_SUCCESS);
}