示例#1
0
文件: kernel_ops.c 项目: BIC-MNI/minc
/* binarise a volume between a range */
Volume  *binarise(Volume * vol, double floor, double ceil, double fg, double bg)
{
   int      x, y, z;
   int      sizes[MAX_VAR_DIMS];
   double   value;
   progress_struct progress;

   if(verbose){
      fprintf(stdout, "Binarising, range: [%g:%g] fg/bg: [%g:%g]\n", floor, ceil, fg, bg);
      }
   get_volume_sizes(*vol, sizes);

   initialize_progress_report(&progress, FALSE, sizes[2], "Binarise");
   for(z = sizes[0]; z--;){
      for(y = sizes[1]; y--;){
         for(x = sizes[2]; x--;){

            value = get_volume_voxel_value(*vol, z, y, x, 0, 0);
            if((value >= floor) && (value <= ceil)){
               set_volume_voxel_value(*vol, z, y, x, 0, 0, fg);
               }
            else {
               set_volume_voxel_value(*vol, z, y, x, 0, 0, bg);
               }

            }
         }
      update_progress_report(&progress, z + 1);
      }
   terminate_progress_report(&progress);

   return (vol);
   }
示例#2
0
文件: mincio.c 项目: BIC-MNI/BEaST
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;
}
示例#3
0
文件: kernel_ops.c 项目: BIC-MNI/minc
/* clamp a volume between a range */
Volume  *clamp(Volume * vol, double floor, double ceil, double bg)
{
   int      x, y, z;
   int      sizes[MAX_VAR_DIMS];
   double   value;
   progress_struct progress;

   if(verbose){
      fprintf(stdout, "Clamping, range: [%g:%g] bg: %g\n", floor, ceil, bg);
      }

   get_volume_sizes(*vol, sizes);

   initialize_progress_report(&progress, FALSE, sizes[2], "Clamping");
   for(z = sizes[0]; z--;){
      for(y = sizes[1]; y--;){
         for(x = sizes[2]; x--;){
            value = get_volume_voxel_value(*vol, z, y, x, 0, 0);
            if((value < floor) || (value > ceil)){
               set_volume_voxel_value(*vol, z, y, x, 0, 0, bg);
               }
            }
         }
      update_progress_report(&progress, z + 1);
      }

   terminate_progress_report(&progress);
   return (vol);
   }
示例#4
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);
   }
示例#5
0
文件: mincio.c 项目: BIC-MNI/BEaST
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;
}
示例#6
0
/* Build the target lattice by transforming the source points through the
   current non-linear transformation stored in:

        Glinear_transform and Gsuper_d{x,y,z} deformation volumes

   both input (px,py,pz) and output (tx,ty,tz) coordinate lists are in
   WORLD COORDINATES

*/
void    build_target_lattice_using_super_sampled_def(
    float px[], float py[], float pz[],
    float tx[], float ty[], float tz[],
    int len, int dim)
{
    int
    i,j,
    sizes[VIO_MAX_DIMENSIONS],
    xyzv[VIO_MAX_DIMENSIONS];
    VIO_Real
    def_vector[VIO_N_DIMENSIONS],
               voxel[VIO_MAX_DIMENSIONS],
               x,y,z;
    long
    index[VIO_MAX_DIMENSIONS];

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

    for(i=1; i<=len; i++) {

        /* apply linear part of the transformation */

        general_transform_point(Glinear_transform,
                                (VIO_Real)px[i], (VIO_Real)py[i], (VIO_Real)pz[i],
                                &x, &y, &z);

        /* now get the non-linear part, using
           nearest neighbour interpolation in
           the super-sampled deformation
           volume. */

        convert_world_to_voxel(Gsuper_sampled_vol,
                               x,y,z, voxel);

        if ((voxel[ xyzv[VIO_X] ] >= -0.5) && (voxel[ xyzv[VIO_X] ] < sizes[xyzv[VIO_X]]-0.5) &&
                (voxel[ xyzv[VIO_Y] ] >= -0.5) && (voxel[ xyzv[VIO_Y] ] < sizes[xyzv[VIO_Y]]-0.5) &&
                (voxel[ xyzv[VIO_Z] ] >= -0.5) && (voxel[ xyzv[VIO_Z] ] < sizes[xyzv[VIO_Z]]-0.5) ) {

            for(j=0; j<3; j++) index[ xyzv[j] ] = (long) (voxel[ xyzv[j] ]+0.5);

            for(index[xyzv[VIO_Z+1]]=0; index[xyzv[VIO_Z+1]]<sizes[xyzv[VIO_Z+1]]; index[xyzv[VIO_Z+1]]++)
                GET_VALUE_4D(def_vector[ index[ xyzv[VIO_Z+1] ]  ], \
                             Gsuper_sampled_vol, \
                             index[0], index[1], index[2], index[3]);


            x += def_vector[VIO_X];
            y += def_vector[VIO_Y];
            z += def_vector[VIO_Z];
        }

        tx[i] = (float)x;
        ty[i] = (float)y;
        tz[i] = (float)z;

    }
}
示例#7
0
VIO_BOOL vol_cog(VIO_Volume d1, VIO_Volume m1, float *centroid)
{

  VIO_Real
    sx,sy,sz,si,
    true_value,
    tx,ty,tz;
  int
    i,j,k,
    count[VIO_MAX_DIMENSIONS];
    

  sx = 0.0;                        /* init centroid vars */
  sy = 0.0;
  sz = 0.0;
  si = 0.0;

  get_volume_sizes(d1, count);
                                /* loop over all voxels */
  for(i=0; i<count[0]; i++)
    for(j=0; j<count[1]; j++)
      for(k=0; k<count[2]; k++) {
        
        convert_3D_voxel_to_world(d1, i,j,k, &tx, &ty, &tz);
        
              if (point_not_masked(m1, tx, ty, tz)) {
          
          GET_VALUE_3D( true_value, d1, i,j,k);
          
          sx +=  tx * true_value;
          sy +=  ty * true_value;
          sz +=  tz * true_value;
          si += true_value;
          
        } 
        
      }
                                /* calc centroids */
  if (si!=0.0) {
    centroid[0] = sx/ si;
    centroid[1] = sy/ si;
    centroid[2] = sz/ si;
    return(TRUE);
  }
  else {
    return(FALSE);
  }
}
示例#8
0
文件: kernel_ops.c 项目: BIC-MNI/minc
/* 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);
   }
示例#9
0
文件: kernel_ops.c 项目: BIC-MNI/minc
/* pad a volume using the background value */
Volume  *pad(Kernel * K, Volume * vol, double bg)
{
   int      x, y, z;
   int      sizes[MAX_VAR_DIMS];

   get_volume_sizes(*vol, sizes);

   /* z */
   for(y = 0; y < sizes[1]; y++){
      for(x = 0; x < sizes[2]; x++){
         for(z = 0; z < -K->pre_pad[2]; z++){
            set_volume_real_value(*vol, z, y, x, 0, 0, bg);
            }
         for(z = sizes[0] - K->post_pad[2]; z < sizes[0]; z++){
            set_volume_real_value(*vol, z, y, x, 0, 0, bg);
            }
         }
      }

   /* y */
   for(z = 0; z < sizes[0]; z++){
      for(x = 0; x < sizes[2]; x++){
         for(y = 0; y < -K->pre_pad[1]; y++){
            set_volume_real_value(*vol, z, y, x, 0, 0, bg);
            }
         for(y = sizes[1] - K->post_pad[1]; y < sizes[1]; y++){
            set_volume_real_value(*vol, z, y, x, 0, 0, bg);
            }
         }
      }

   /* x */
   for(z = 0; z < sizes[0]; z++){
      for(y = 0; y < sizes[1]; y++){
         for(x = 0; x < -K->pre_pad[0]; x++){
            set_volume_real_value(*vol, z, y, x, 0, 0, bg);
            }
         for(x = sizes[2] - K->post_pad[0]; x < sizes[2]; x++){
            set_volume_real_value(*vol, z, y, x, 0, 0, bg);
            }
         }
      }

   return (vol);
   }
示例#10
0
void calc_volume_range(VIO_Volume * vol, double *min, double *max)
{

   int      x, y, z;
   int      sizes[MAX_VAR_DIMS];
   double   value;
   VIO_progress_struct progress;

   *min = DBL_MAX;
   *max = -DBL_MIN;

   get_volume_sizes(*vol, sizes);

   initialize_progress_report(&progress, FALSE, sizes[2], "Finding Range");
   for(z = sizes[0]; z--;){
      for(y = sizes[1]; y--;){
         for(x = sizes[2]; x--;){

            value = get_volume_voxel_value(*vol, z, y, x, 0, 0);
            if(value < *min){
               *min = value;
               }
            else if(value > *max){
               *max = value;
               }
            }
         }
      update_progress_report(&progress, z + 1);
      }
   terminate_progress_report(&progress);

   if (*min == *max) {
       *max = *min + 1.0;
   }

   if(verbose){
      fprintf(stdout, "Found range of [%g:%g]\n", *min, *max);
      }
   }
VIO_BOOL vol_to_cov(VIO_Volume d1, VIO_Volume m1, float centroid[4], float covar[4][4], double *step)
{

  VectorR
    vector_step,
    slice_step,
    row_step,
    col_step;

  PointR 
    starting_offset,
    starting_origin,
    starting_position,
    slice,
    row,
    col,
    voxel;

  VIO_Real
    tx,ty,tz;
  int
    i,r,c,s,
    limits[VOL_NDIMS];

  float
    t,
    sxx,syy,szz,
    sxy,syz,sxz,
    sx,sy,sz,si; 
  VIO_Real
    thickness[3];
  int
    sizes[3];

  VIO_Real
    true_value;

  get_volume_separations(d1, thickness);
  get_volume_sizes(d1, sizes);
  
                                /* build sampling lattice info */
  for(i=0; i<3; i++) {        
    step[i] *= thickness[i] / fabs( thickness[i]);
  }

  fill_Vector( col_step,   step[COL_IND], 0.0,     0.0 );
  fill_Vector( row_step,   0.0,     step[ROW_IND], 0.0 );
  fill_Vector( slice_step, 0.0,     0.0,     step[SLICE_IND] );

  convert_3D_voxel_to_world(d1, 0.0, 0.0, 0.0, &tx, &ty, &tz); 

  fill_Point( starting_origin, tx, ty, tz);

  for(i=0; i<3; i++) {                /* for each dim, get # of steps in that direction,
                                   and set starting offset */
    t = sizes[i] * thickness[i] / step[i];
    limits[i] = abs( t );
    
    Point_coord( starting_offset, (i) ) = 
      ( (sizes[i]-1)*thickness[i] - (limits[i] * step[i] ) ) / 2.0;
  }
  
  ADD_POINTS( starting_position, starting_origin, starting_offset ); /*  */

                                /* calculate centroids first */

  sx = 0.0;
  sy = 0.0;
  sz = 0.0;
  si = 0.0;

  for(s=0; s<=limits[SLICE_IND]; s++) {

    SCALE_VECTOR( vector_step, slice_step, s);
    ADD_POINT_VECTOR( slice, starting_position, vector_step );

    for(r=0; r<=limits[ROW_IND]; r++) {

      SCALE_VECTOR( vector_step, row_step, r);
      ADD_POINT_VECTOR( row, slice, vector_step );

      SCALE_POINT( col, row, 1.0); /* init first col position */
      for(c=0; c<=limits[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))) {
          
          if (INTERPOLATE_TRUE_VALUE( d1, &voxel, &true_value )) {
            
            sx +=  Point_x(col) * true_value;
            sy +=  Point_y(col) * true_value;
            sz +=  Point_z(col) * true_value;
            
            si += true_value;
          }
          /* else requested voxel is just outside volume., so ignore it */

        } 
        
        ADD_POINT_VECTOR( col, col, col_step );
        
      }
    }
  }

  if (si!=0.0) {
    centroid[1] = sx/ si;
    centroid[2] = sy/ si;
    centroid[3] = sz/ si;
    
    sxx = syy = szz = 0.0;
    sxy = syz = sxz = 0.0;
    
                                /* now calculate variances and co-variances */

    for(s=0; s<=limits[VIO_Z]; s++) {
      
      SCALE_VECTOR( vector_step, slice_step, s);
      ADD_POINT_VECTOR( slice, starting_position, vector_step );
      
      for(r=0; r<=limits[VIO_Y]; r++) {
        
        SCALE_VECTOR( vector_step, row_step, r);
        ADD_POINT_VECTOR( row, slice, vector_step );
        
        SCALE_POINT( col, row, 1.0); /* init first col position */
        for(c=0; c<=limits[VIO_X]; 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))) {
            
            if (INTERPOLATE_TRUE_VALUE( d1, &voxel, &true_value )) {
              
                    sxx += (Point_x( col )-centroid[1]) * (Point_x( col )-centroid[1]) * true_value;
              syy += (Point_y( col )-centroid[2]) * (Point_y( col )-centroid[2]) * true_value;
              szz += (Point_z( col )-centroid[3]) * (Point_z( col )-centroid[3]) * true_value;
              sxy += (Point_x( col )-centroid[1]) * (Point_y( col )-centroid[2]) * true_value;
              syz += (Point_y( col )-centroid[2]) * (Point_z( col )-centroid[3]) * true_value;
              sxz += (Point_x( col )-centroid[1]) * (Point_z( col )-centroid[3]) * true_value;

            }
            /* else requested voxel is just outside volume., so ignore it */

          } 
          
          ADD_POINT_VECTOR( col, col, col_step );
        
        }
      }
    }
    
    covar[1][1] = sxx/si; covar[1][2] = sxy/si; covar[1][3] = sxz/si;
    covar[2][1] = sxy/si; covar[2][2] = syy/si; covar[2][3] = syz/si;
    covar[3][1] = sxz/si; covar[3][2] = syz/si; covar[3][3] = szz/si;
    
    return(TRUE);
    
  }
  else {
    return(FALSE);
  }
}
示例#12
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);

  
}
示例#13
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);
  
}
int main(int argc, char *argv[])
{
  int 
    count,
    i,j,k, p,r,s, flag,
    sizes1[3],sizes2[3], sizes3[3];
  VIO_Real
    thresh;
  VIO_Real
    mean1, std1, mean2, std2,
    corr, v1, v2, v3, s1, s2, s12,
    u,v,w,  x,y,z;
  VIO_Status status;

  VIO_Volume 
    data1, data2, mask;
  char *f1, *f2, *mf;

  if (argc<4) {
    print ("usage:  xcorr_vol.c vol1.mnc vol2.mnc threshold [mask.mnc]\n");
    exit(EXIT_FAILURE);
  }

  prog_name = argv[0];
  f1        = argv[1];
  f2        = argv[2];  
  thresh    = atof(argv[3]);
  if (argc==5)
    mf      = argv[4];

  status = input_volume(f1, 3, default_dim_names, NC_UNSPECIFIED, FALSE, 0.0,0.0,
                        TRUE, &data1, (minc_input_options *)NULL); 
  if (status!=VIO_OK) {
    print ("Error reading %s.\n",f1);
    exit(EXIT_FAILURE);
  }
  
  status = input_volume(f2, 3, default_dim_names, NC_UNSPECIFIED, FALSE, 0.0,0.0,
                        TRUE, &data2, (minc_input_options *)NULL); 
 
  if (status!=VIO_OK) {
    print ("Error reading %s.\n",f2);
    exit(EXIT_FAILURE);
  }

  if (argc==5) {
    status = input_volume(mf, 3, default_dim_names, NC_UNSPECIFIED, FALSE, 0.0,0.0,
                          TRUE, &mask, (minc_input_options *)NULL); 
    
    if (status!=VIO_OK) {
      print ("Error reading %s.\n",mf);
      exit(EXIT_FAILURE);
    }
    get_volume_sizes(mask,sizes3); 
  }
  else 
    mask = (VIO_Volume)NULL;
  
  get_volume_sizes(data1,sizes1);
  get_volume_sizes(data2,sizes2);
  
  if (sizes1[0] != sizes2[0] || sizes1[1] != sizes2[1] || sizes1[2] != sizes2[2]) {
    print ("Size mismatch between %s and %s.\n",f1,f2);
    print ("%d,%d,%d != %d,%d,%d\n", 
           sizes1[0],sizes1[1],sizes1[2],
           sizes2[0],sizes2[1],sizes2[2]);
    exit(EXIT_FAILURE);
  }
  
  get_zscore_values(data1, mask, thresh, &mean1, &std1); 
  get_zscore_values(data2, mask, thresh, &mean2, &std2); 

  if (std1==0.0 || std2==0.0) {
    print ("No standard deviation in one of %s and %s.\n",f1,f2);
    exit(EXIT_FAILURE);
  }

  count = 0;
  s1 = s2 = s12 = 0.0;
  for(i=0; i<sizes1[0]; i++) {
    for(j=0; j<sizes1[1]; j++) {
      for(k=0; k<sizes1[2]; k++) {

        flag = TRUE;

        if (mask != NULL) {
          convert_3D_voxel_to_world(data1, i,j,k, &x, &y, &z);
          convert_3D_world_to_voxel(mask,  x,y,z, &u, &v, &w);
          p = VIO_ROUND(u);
          r = VIO_ROUND(v);
          s = VIO_ROUND(w);
          if (p>=0 &&  p<sizes3[0] &&
              r>=0 &&  r<sizes3[1] &&
              s>=0 &&  s<sizes3[2]) {
            GET_VALUE_3D( v3 ,  mask, p, r, s);
            if (v3 < 0.5)
              flag = FALSE;
          }
          else 
            flag = FALSE;
        }

        if (flag ) {

          GET_VALUE_3D( v1 ,  data1, i, j, k);
          GET_VALUE_3D( v2 ,  data2, i, j, k);


          v1 = (v1 - mean1) / std1;
          v2 = (v2 - mean2) / std2;
          
          v1 = v1 - v2;
          s12 += fabs(v1);
          
          count++;


        }
      }
    }
  }

  if (count==0) {
    exit(EXIT_FAILURE);
    print ("No masked voxels\n");
  }
  else {
    corr = s12 / count;

    print ("%15.12f\n",corr);
    exit(EXIT_SUCCESS);
  }

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

  /* get default information from data and mask */

  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 = FLT_MAX;
  max = -FLT_MAX;

                                /* 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++) {

        convert_3D_voxel_to_world(d1, (VIO_Real)s, (VIO_Real)r, (VIO_Real)c, &wx, &wy, &wz);

        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;
            }
          }
        }
      }
    }
  }


                                /* calc mean and std */
  *mean = sum / (float)count;
  var  = ((float)count*sum2 - sum*sum) / ((float)count*((float)count-1));
  *std  = sqrt(var);
 
}
示例#16
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]];
      }

   }
示例#17
0
float go_get_samples_with_offset(
    VIO_Volume data,                  /* The volume of data */
    VIO_Volume mask,                  /* The target mask */
    float *x, float *y, float *z,     /* the positions of the sub-lattice */
    VIO_Real  dx, VIO_Real  dy, VIO_Real dz,  /* the local displacement to apply  */
    int obj_func,                     /* the type of obj function req'd   */
    int len,                          /* number of sub-lattice nodes      */
    int *sample_target_count,         /* number of nonmasked  sub-lattice nodes */
    float normalization,              /* normalization factor for obj func*/
    float *a1,                        /* feature value for (x,y,z) nodes  */
    VIO_BOOL *m1,                     /* mask flag for (x,y,z) nodes in source */
    VIO_BOOL use_nearest_neighbour)   /* interpolation flag              */
{
    double
    sample, r,
            s1,s2,s3,s4,s5,tmp;                   /* accumulators for inner loop */
    int
    sizes[3],
          ind0, ind1, ind2,
          offset0, offset1, offset2,
          c,number_of_nonzero_samples;
    int xs,ys,zs;
    float
    f_trans, f_scale;

    static double v0, v1, v2;
    static double f0, f1, f2, r0, r1, r2, r1r2, r1f2, f1r2, f1f2;
    static double v000, v001, v010, v011, v100, v101, v110, v111;

    double ***double_ptr;

    double mean_s = 0.0;		/* init variables for stats */
    double mean_t = 0.0;
    double var_s = 0.0;
    double var_t = 0.0;
    double covariance = 0.0;

    number_of_nonzero_samples = 0;

    get_volume_sizes(data, sizes);
    xs = sizes[0];
    ys = sizes[1];
    zs = sizes[2];


    s1 = s2 = s3 = s4 = s5 = 0.0;
    ++a1;
    ++m1;                   /* inc pointer, so that we are pointing to
                                   the first feature value, corresponding
                                   to the first sub-lattice point x,y,z   */



    if (use_nearest_neighbour) {
        /* then do fast NN interpolation */

        dx += 0.;                        /* to achieve `rounding' for ind0, ind1 and */
        dy += 0.;                        /* ind2 below */
        dz += 0.;

        double_ptr = VOXEL_DATA (data);

        /* increment by one as we index from 1...n (but the array is ALLOC'd from 0..n) */
        x++;
        y++;
        z++;

        /* for each sub-lattice node */
        for(c=len; c--;) {

            /*
             *  this is code to test timing of David's evaluate_volume_in_world()
             *  interpolation code.  While it is _VERY_ general, the eval_vol_in_world()'s
             *  NN interpolation is approximately 8-9 times slower than the bit of
             *  fast NN code below.
             *
             *  VIO_Real sampleR, index[5], wx, wy, wz;
             *  index[0] = (VIO_Real) ( *x + dx );
             *  index[1] = (VIO_Real) ( *y + dy );
             *  index[2] = (VIO_Real) ( *z + dz );
             *  index[3] = index[4] = 0.0;
             *  convert_voxel_to_world(data, index, &wx, &wy, &wz );
             *  evaluate_volume_in_world(data, wx, wy, wz,
             *                            0, TRUE, 0.0, &sampleR,
             *                            NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
             *   sample = (double)sampleR;
             */

            if (!(*m1) && (voxel_point_not_masked(mask, (VIO_Real)*x, (VIO_Real)*y, (VIO_Real)*z)) && (!(obj_func==NONLIN_CHAMFER) ||  (*a1>0)) ) {

                ind0 = (int) ( *x + dx );
                ind1 = (int) ( *y + dy );
                ind2 = (int) ( *z + dz );

                if (ind0>=0 && ind0<xs &&
                        ind1>=0 && ind1<ys &&
                        ind2>=0 && ind2<zs) {
                    sample = (double)(double_ptr[ind0][ind1][ind2]);
                }
                else {
                    sample = 0.0;
                }

#include "switch_obj_func.c"	/* contains a case statement to do the sample-to-sample computations required for each possible non-lin objective function */
            }

            /* increment the coordinate, value and mask array pointers */
            x++;			/* x,y,z are the coords of the sublattice in the fixed (source) image */
            y++;
            z++;
            a1++;			/* a1 is from the fixed image */
            m1++;			/* m1 is rom the mask on the fixed image */

        }
    }
    else {                        /* then do fast trilinear interpolation */

        /* set up offsets */
        offset0 = (Gglobals->count[VIO_Z] > 1) ? 1 : 0;
        offset1 = (Gglobals->count[VIO_Y] > 1) ? 1 : 0;
        offset2 = (Gglobals->count[VIO_X] > 1) ? 1 : 0;

        double_ptr = VOXEL_DATA (data);

        /* increment by one as we index from 1...n */
        ++x;
        ++y;
        ++z;

        /* for each sub-lattice node */
        for(c=len; c--;) {

            /*  fast tri-linear interplation */

            if  (  !(*m1) && (voxel_point_not_masked(mask, (VIO_Real)*x, (VIO_Real)*y, (VIO_Real)*z)) && (!(obj_func==NONLIN_CHAMFER) ||  (*a1>0)) ) {
                v0 = (VIO_Real) ( *x + dx );
                v1 = (VIO_Real) ( *y + dy );
                v2 = (VIO_Real) ( *z + dz );

                ind0 = (int)v0;
                ind1 = (int)v1;
                ind2 = (int)v2;

                if (ind0>=0 && ind0<(xs-offset0) &&
                        ind1>=0 && ind1<(ys-offset1) &&
                        ind2>=0 && ind2<(zs-offset2)) {

                    /* get the data */
                    v000 = (VIO_Real)(double_ptr[ind0        ][ind1        ][ind2        ]);
                    v001 = (VIO_Real)(double_ptr[ind0        ][ind1        ][ind2+offset2]);
                    v010 = (VIO_Real)(double_ptr[ind0        ][ind1+offset1][ind2        ]);
                    v011 = (VIO_Real)(double_ptr[ind0        ][ind1+offset1][ind2+offset2]);
                    v100 = (VIO_Real)(double_ptr[ind0+offset0][ind1        ][ind2        ]);
                    v101 = (VIO_Real)(double_ptr[ind0+offset0][ind1        ][ind2+offset2]);
                    v110 = (VIO_Real)(double_ptr[ind0+offset0][ind1+offset1][ind2        ]);
                    v111 = (VIO_Real)(double_ptr[ind0+offset0][ind1+offset1][ind2+offset2]);

                    /* Get the fraction parts */
                    f0 = v0 - ind0;
                    f1 = v1 - ind1;
                    f2 = v2 - ind2;
                    r0 = 1.0 - f0;
                    r1 = 1.0 - f1;
                    r2 = 1.0 - f2;

                    /* Do the interpolation */
                    r1r2 = r1 * r2;
                    r1f2 = r1 * f2;
                    f1r2 = f1 * r2;
                    f1f2 = f1 * f2;

                    sample   =
                        r0 *  (r1r2 * v000 +
                               r1f2 * v001 +
                               f1r2 * v010 +
                               f1f2 * v011);
                    sample  +=
                        f0 *  (r1r2 * v100 +
                               r1f2 * v101 +
                               f1r2 * v110 +
                               f1f2 * v111);

                    sample = sample;


                }
                else {
                    sample = 0.0;
                }


#include "switch_obj_func.c"

            }

            /* increment the coordinate, value and mask array pointers */
            x++;			/* x,y,z are the coords of the sublattice in the fixed (source) image */
            y++;
            z++;
            a1++;			/* a1 is from the fixed image */
            m1++;			/* m1 is rom the mask on the fixed image */

        }



        /* do the last bits of the similarity function
           calculation here - normalizing each obj_func
           where-ever possible: */
        r = 0.0;

        switch (obj_func) {

        case NONLIN_XCORR:            /* use standard normalized cross-correlation
                                   where 0.0 < r < 1.0, where 1.0 is best*/
            if ( normalization < 0.001 && s3 < 0.00001) {
                r = 1.0;
            }
            else {
                if ( normalization < 0.001 || s3 < 0.00001) {
                    r = 0.0;
                }
                else {
                    r = s1 / ((sqrt((double)s2))*(sqrt((double)s3)));
                }
            }
            /* r = 1.0 - r;                 now, 0 is best                   */
            break;

        case NONLIN_DIFF:             /* normalization stores the number of samples in
                                   the sub-lattice
                                   s1 stores the sum of the magnitude of
                                   the differences*/

            r = -s1 /number_of_nonzero_samples;        /* r = average intensity difference ; with
                                   -max(intensity range) < r < 0,
                                   where 0 is best                  */
            break;
        case NONLIN_LABEL:
            r = s1 /number_of_nonzero_samples;           /* r = average label agreement,
                                    s1 stores the number of similar labels
                                   0 < r < 1.0
                                   where 1.0 is best                */
            break;
        case NONLIN_CHAMFER:
            if (number_of_nonzero_samples>0) {
                r = 1.0 - (s1 / (20.0*number_of_nonzero_samples));
                /* r = 1- average distance / 20mm
                       0 < r < ~1.0
                   where 1.0 is best
                       and where 2.0cm is an arbitrary value to
                       norm the dist, corresponding to a guess
                       at the maximum average cortical variability

                       so the max(r) could be greater than
                       1.0, but when it is, shouldn't
                       chamfer have larger weight to drive
                       the fit? */
            }
            else
                r = 2.0;                 /* this is simply a value > 1.5, used as a
                                   flag to indicate that there were no
                                   samples used for the chamfer */
            break;
        case NONLIN_CORRCOEFF:
        {
            /* Accumulators:
             * s1 = sum of source image values
             * s2 = sum of target image values
             * s3 = sum of squared source image values
             * s4 = sum of squared target image values
             * s5 = sum of source*target values
             *
             * normalization = #values considered
             */
            if (number_of_nonzero_samples>0) {
                mean_s = s1 / number_of_nonzero_samples;
                mean_t = s2 / number_of_nonzero_samples;
                var_s = s3 / number_of_nonzero_samples - mean_s*mean_s;
                var_t = s4 / number_of_nonzero_samples - mean_t*mean_t;
                covariance = s5 / number_of_nonzero_samples - mean_s*mean_t;
            }
            else {
                mean_s = 0.0;
                mean_t = 0.0;
                var_s = 0.0;
                var_t = 0.0;
                covariance = 0.0;
            }


            if ((var_s < 0.00001) || (var_t < 0.00001) ) {
                r = 0.0;
            }
            else {
                r = covariance / sqrt( var_s*var_t );
            }
        }
        break;

        case NONLIN_SQDIFF:           /* normalization stores the number of samples
                                   in the sub-lattice.
                                   s1 stores the sum of the squared intensity
                                   differences */
            r = -s1 /number_of_nonzero_samples;
            break;

        default:
            print_error_and_line_num("Objective function %d not supported in go_get_samples_with_offset",__FILE__, __LINE__,obj_func);
        }


        return(r);
    }

}
示例#18
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__);
  }

}
示例#19
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);
}
int main(int argc, char *argv[])
{
   VIO_General_transform 
     transform, 
     *grid_transform_ptr, 
     forward_transform;
   VIO_Volume 
     target_vol,
     volume;
   volume_input_struct 
     input_info;
   VIO_Real
     voxel[VIO_MAX_DIMENSIONS],
     steps[VIO_MAX_DIMENSIONS],
     start[VIO_N_DIMENSIONS],
     target_steps[VIO_MAX_DIMENSIONS],
     wx,wy,wz, inv_x, inv_y, inv_z,
     def_values[VIO_MAX_DIMENSIONS];

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

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


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


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

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

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

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


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

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

       copy_general_transform(grid_transform_ptr,
                              &forward_transform);

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

       forward_transform.inverse_flag = !(forward_transform.inverse_flag);

       volume = grid_transform_ptr->displacement_volume;

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

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

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

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

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

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

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

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

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

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

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

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

       delete_general_transform(&forward_transform);

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

   }
   

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

   exit(EXIT_SUCCESS);
}
示例#21
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);
  
}
示例#22
0
文件: kernel_ops.c 项目: BIC-MNI/minc
/* perform a median kernel operation on a volume */
Volume  *median_dilation_kernel(Kernel * K, Volume * vol)
{
   int      x, y, z, c, i;
   int      sizes[MAX_VAR_DIMS];
   progress_struct progress;
   Volume   tmp_vol;
   double   value;

   unsigned int kvalue;
   unsigned int neighbours[K->nelems];

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

   /* 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++){

            /* only modify background voxels */
            value = get_volume_voxel_value(tmp_vol, z, y, x, 0, 0);
            if(value == 0.0){

               i = 0;
               for(c = 0; c < K->nelems; c++){

                  kvalue = (unsigned int)get_volume_voxel_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]);
                  if(kvalue != 0){
                     neighbours[i] = kvalue;
                     i++;
                     }
                  }

               /* only run this for adjacent voxels */
               if(i > 0){

                  /* find the median of our little array */
                  qsort(&neighbours[0], (size_t) i, sizeof(unsigned int), &compare_ints);

                  /* store the median value */
                  set_volume_voxel_value(*vol, z, y, x, 0, 0,
                                         (double)neighbours[(int)floor((i - 1) / 2)]);
                  }
               }

            /* else just copy the original value over */
            else {
               set_volume_voxel_value(*vol, z, y, x, 0, 0, value);
               }
            }
         }

      update_progress_report(&progress, z + 1);
      }

   delete_volume(tmp_vol);
   terminate_progress_report(&progress);
   return (vol);
   }
示例#23
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 );
}
示例#24
0
/* return resulting totals and weights volumes */
void regrid_arb_path(char *coord_fn, char *data_fn, int buff_size,
                     VIO_Volume * totals, VIO_Volume * weights, int v_size,
                     double regrid_floor, double regrid_ceil)
{
   Coord_list coord_buf;
   double  *data_buf = NULL;
   size_t   data_buf_alloc_size = 0;
   int      sizes[MAX_VAR_DIMS];
   int      c, v;
   int      total_pts;
   double   value;
   int      valid;

   /* global max-min counters */
   double   v_min, v_max;
   double   x_min, y_min, z_min;
   double   x_max, y_max, z_max;

   /* loop max-min counters */
   double   l_v_min, l_v_max;
   double   l_x_min, l_y_min, l_z_min;
   double   l_x_max, l_y_max, l_z_max;

   /* get volume info */
   get_volume_sizes(*totals, sizes);

   /* check for the config file */
   if(!file_exists(coord_fn)){
      fprintf(stderr, "Couldn't find config file %s.\n\n", coord_fn);
      exit(EXIT_FAILURE);
      }

   /* initialise the parser with the config file */
   if(!init_arb_path(coord_fn, data_fn)){
      fprintf(stderr, "Failed to init arb_path, this isn't good\n");
      exit(EXIT_FAILURE);
      }

   /* get some co-ordinates */
   if(verbose){
      fprintf(stdout, " + Doing arbitrary path (vector: %d)\n", v_size);
      }
   total_pts = 0;
   v_min = DBL_MAX;
   v_max = -DBL_MAX;
   x_min = y_min = z_min = DBL_MAX;
   x_max = y_max = z_max = -DBL_MAX;
   coord_buf = get_some_arb_path_coords(buff_size);
   while(coord_buf->n_pts != 0){

      /* grow data_buf if we have to */
      if(coord_buf->n_pts * v_size > data_buf_alloc_size){
         data_buf_alloc_size = coord_buf->n_pts * v_size;
         data_buf = realloc(data_buf, data_buf_alloc_size * sizeof(*data_buf));
         }

      /* get the data */
      if(!get_some_arb_path_data
         (data_buf, in_dtype, in_is_signed, coord_buf->n_pts, v_size)){
         fprintf(stderr, "failed getting data\n");
         exit(EXIT_FAILURE);
         }

      total_pts += coord_buf->n_pts;
      if(verbose){
         fprintf(stdout, " | %d co-ords total: %d ", coord_buf->n_pts, total_pts);
         fflush(stdout);
         }

      /* regrid (do the nasty) */
      l_v_min = DBL_MAX;
      l_v_max = -DBL_MAX;
      l_x_min = l_y_min = l_z_min = DBL_MAX;
      l_x_max = l_y_max = l_z_max = -DBL_MAX;
      for(c = 0; c < coord_buf->n_pts; c++){

         /* check if this point is in range */
         valid = 1;
         for(v = 0; v < v_size; v++){
            value = data_buf[(c * v_size) + v];

            if(value < regrid_floor || value > regrid_ceil){
               valid = 0;
               }
            else {
               /* do range calculation */
               if(verbose){
                  if(value > l_v_max){
                     l_v_max = value;
                     }
                  else if(value < l_v_min){
                     l_v_min = value;
                     }
                  }
               }
            
         //   fprintf(stderr, "Value: %g   valid %d\n", value, valid);
            }
         // fprintf(stderr, "VV %d    [%g:%g:%g]\n", valid, 
         //        coord_buf->pts[c].coord[0], 
         //        coord_buf->pts[c].coord[1], 
         //        coord_buf->pts[c].coord[2] 
         //        );

         if(valid){
            regrid_point(totals, weights,
                         coord_buf->pts[c].coord[0],
                         coord_buf->pts[c].coord[1],
                         coord_buf->pts[c].coord[2], v_size, &data_buf[c * v_size]);

            /* coord max-min storage */
            if(verbose){
               if(coord_buf->pts[c].coord[0] > l_x_max){
                  l_x_max = coord_buf->pts[c].coord[0];
                  }
               else if(coord_buf->pts[c].coord[0] < l_x_min){
                  l_x_min = coord_buf->pts[c].coord[0];
                  }

               if(coord_buf->pts[c].coord[1] > l_y_max){
                  l_y_max = coord_buf->pts[c].coord[1];
                  }
               else if(coord_buf->pts[c].coord[1] < l_y_min){
                  l_y_min = coord_buf->pts[c].coord[1];
                  }

               if(coord_buf->pts[c].coord[2] > l_z_max){
                  l_z_max = coord_buf->pts[c].coord[2];
                  }
               else if(coord_buf->pts[c].coord[2] < l_z_min){
                  l_z_min = coord_buf->pts[c].coord[2];
                  }
               }

            }
         }

      if(verbose){
         fprintf(stdout, " xyz [%4.1g:%4.1g:%4.1g] : [%4.1g:%4.1g:%4.1g] v: [%g:%g]\n",
                 l_x_min, l_y_min, l_z_min, l_x_max, l_y_max, l_z_max, l_v_min, l_v_max);
         }

      /* update global counters */
      if(verbose){
         if(l_v_min < v_min){
            v_min = l_v_min;
            }
         if(l_v_max > v_max){
            v_max = l_v_max;
            }

         if(l_x_min < x_min){
            x_min = l_x_min;
            }
         if(l_y_min < y_min){
            y_min = l_y_min;
            }
         if(l_z_min < z_min){
            z_min = l_z_min;
            }

         if(l_x_max > x_max){
            x_max = l_x_max;
            }
         if(l_y_max > y_max){
            y_max = l_y_max;
            }
         if(l_z_max > z_max){
            z_max = l_z_max;
            }

         }

      /* get the next lot of co-ordinates */
      coord_buf = get_some_arb_path_coords(buff_size);
      }

   if(verbose){
      fprintf(stdout,
              " | == global xyz [%4.1g:%4.1g:%4.1g] : [%4.1g:%4.1g:%4.1g] v: [%g:%g]\n",
              x_min, y_min, z_min, x_max, y_max, z_max, v_min, v_max);
      }

   /* finish up */
   end_arb_path();
   }
示例#25
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);

}
示例#26
0
文件: kernel_ops.c 项目: BIC-MNI/minc
/* 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);
   }
示例#27
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);
   
}
示例#28
0
文件: kernel_ops.c 项目: BIC-MNI/minc
/* 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);
   }
示例#29
0
文件: kernel_ops.c 项目: BIC-MNI/minc
/* resulting groups are sorted WRT size          */
Volume  *group_kernel(Kernel * K, Volume * vol, double bg)
{
   int      x, y, z;
   int      sizes[MAX_VAR_DIMS];
   progress_struct progress;
   Volume   tmp_vol;
   Kernel  *k1, *k2;

   unsigned int *equiv;
   unsigned int *counts;
   unsigned int *trans;
   unsigned int neighbours[K->nelems];

   /* counters */
   unsigned int c;
   unsigned int value;
   unsigned int group_idx;             /* label for the next group     */
   unsigned int num_groups;

   unsigned int min_label;
   unsigned int curr_label;
   unsigned int prev_label;
   unsigned int num_matches;

   /* structure for group data */
   Group_info *group_data;

   /* split the Kernel into forward and backwards kernels */
   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, "Group 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], "Groups");

   /* copy and then zero out the original volume */
   tmp_vol = copy_volume(*vol);
   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);
            }
         }
      }

   /* pass 1 - forward direction (we assume a symmetric kernel) */

   /* our first group is given the label 1 */
   group_idx = 1;

   /* initialise the equiv and counts arrays */
   SET_ARRAY_SIZE(equiv, 0, group_idx, 500);
   equiv[0] = 0;

   SET_ARRAY_SIZE(counts, 0, group_idx, 500);
   counts[0] = 0;

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

            if(get_volume_voxel_value(tmp_vol, z, y, x, 0, 0) != bg){

               /* search this voxels neighbours */
               num_matches = 0;
               min_label = INT_MAX;

               for(c = 0; c < k1->nelems; c++){
                  value = (unsigned int)get_volume_voxel_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]);
                  if(value != 0){
                     if(value < min_label){
                        min_label = value;
                        }
                     neighbours[num_matches] = value;
                     num_matches++;
                     }
                  }

               switch (num_matches){
               case 0:
                  /* no neighbours, make a new label and increment */
                  set_volume_voxel_value(*vol, z, y, x, 0, 0, (Real) group_idx);

                  SET_ARRAY_SIZE(equiv, group_idx, group_idx + 1, 500);
                  equiv[group_idx] = group_idx;

                  SET_ARRAY_SIZE(counts, group_idx, group_idx + 1, 500);
                  counts[group_idx] = 1;

                  group_idx++;
                  break;

               case 1:
                  /* only one neighbour, no equivalences needed */
                  set_volume_voxel_value(*vol, z, y, x, 0, 0, (Real) min_label);
                  counts[min_label]++;
                  break;

               default:
                  /* more than one neighbour */

                  /* first sort the neighbours array */
                  qsort(&neighbours[0], (size_t) num_matches, sizeof(unsigned int),
                        &compare_ints);

                  /* find the minimum possible label for this voxel,    */
                  /* this is done by descending through each neighbours */
                  /* equivalences until an equivalence equal to itself  */
                  /* is found                                           */
                  prev_label = -1;
                  for(c = 0; c < num_matches; c++){
                     curr_label = neighbours[c];

                     /* recurse this label if we haven't yet */
                     if(curr_label != prev_label){
                        while(equiv[curr_label] != equiv[equiv[curr_label]]){
                           curr_label = equiv[curr_label];
                           }

                        /* check against the current minimum value */
                        if(equiv[curr_label] < min_label){
                           min_label = equiv[curr_label];
                           }
                        }

                     prev_label = neighbours[c];
                     }

                  /* repeat, setting equivalences to the min_label */
                  prev_label = -1;
                  for(c = 0; c < num_matches; c++){
                     curr_label = neighbours[c];

                     if(curr_label != prev_label){
                        while(equiv[curr_label] != equiv[equiv[curr_label]]){
                           curr_label = equiv[curr_label];

                           equiv[curr_label] = min_label;
                           }

                        /* set the label itself */
                        if(equiv[neighbours[c]] != min_label){
                           equiv[neighbours[c]] = min_label;
                           }
                        }

                     prev_label = neighbours[c];
                     }

                  /* finally set the voxel in question to the minimum value */
                  set_volume_voxel_value(*vol, z, y, x, 0, 0, (Real) min_label);
                  counts[min_label]++;
                  break;
                  }                       /* end case */

               }
            }
         }
      update_progress_report(&progress, z + 1);
      }
   terminate_progress_report(&progress);

   /* reduce the equiv and counts array */
   num_groups = 0;
   for(c = 0; c < group_idx; c++){

      /* if this equivalence is not resolved yet */
      if(c != equiv[c]){

         /* find the min label value */
         min_label = equiv[c];
         while(min_label != equiv[min_label]){
            min_label = equiv[min_label];
            }

         /* update the label and its counters */
         equiv[c] = min_label;
         counts[min_label] += counts[c];
         counts[c] = 0;
         }
      else {
         num_groups++;
         }
      }

   /* Allocate space for the array of groups */
   group_data = (Group_info *) malloc(num_groups * sizeof(Group_info));

   num_groups = 0;
   for(c = 0; c < group_idx; c++){
      if(counts[c] > 0){
         /* allocate space for this element */
         group_data[num_groups] = malloc(sizeof(group_info_struct));

         group_data[num_groups]->orig_label = equiv[c];
         group_data[num_groups]->count = counts[c];
         num_groups++;
         }
      }

   /* sort the groups by the count size */
   if(verbose){
      fprintf(stdout, "Found %d unique groups from %d, sorting...\n", num_groups,
              group_idx);
      }
   qsort(group_data, num_groups, sizeof(Group_info), &compare_groups);

   /* set up the transpose array */
   trans = (unsigned int *)malloc(sizeof(unsigned int) * group_idx);
   for(c = 0; c < num_groups; c++){
      trans[group_data[c]->orig_label] = c + 1; /* +1 to bump past 0 */
      }

   /* pass 2 - resolve equivalences in the output data */
   if(verbose){
      fprintf(stdout, "Resolving equivalences...\n");
      }
   for(z = sizes[0]; z--;){
      for(y = sizes[1]; y--;){
         for(x = sizes[2]; x--;){
            value = (unsigned int)get_volume_voxel_value(*vol, z, y, x, 0, 0);
            if(value != 0){
               value = trans[equiv[value]];
               set_volume_voxel_value(*vol, z, y, x, 0, 0, (Real) value);
               }
            }
         }
      }

   /* tidy up */
   delete_volume(tmp_vol);
   for(c = 0; c < num_groups; c++){
      free(group_data[c]);
      }
   free(group_data);
   free(trans);
   free(k1);
   free(k2);

   return (vol);
   }
示例#30
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;
}