Exemple #1
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);
  }
}
Exemple #2
0
int main(int argc, char *argv[])
{
   Volume volume;
   volume_input_struct input_info;
   char *filename;
   double v0, v1, v2, wx, wy, wz;
   static char *dim_names[] =
      {ANY_SPATIAL_DIMENSION, ANY_SPATIAL_DIMENSION, ANY_SPATIAL_DIMENSION};

   milog_init(argv[0]);

   /* Check arguments */
   if (ParseArgv(&argc, argv, argTable, 0) || argc != 5) {
      (void) fprintf(stderr, 
      "Usage: %s <image file> <voxel index 1 (slowest)> <index 2> <index 3>\n",
                     argv[0]);
      exit(EXIT_FAILURE);
   }
   filename = argv[1];
   v0 = atof(argv[2]);
   v1 = atof(argv[3]);
   v2 = atof(argv[4]);

   /* Open the image file */
   set_print_function(print_to_stderr);
   if (start_volume_input(filename, 3, dim_names, MI_ORIGINAL_TYPE, TRUE,
                          0.0, 0.0, TRUE, &volume, NULL, &input_info) != OK) {
      (void) fprintf(stderr, "Error opening file %s for input.\n",
                     filename);
      exit(EXIT_FAILURE);
   }

   /* Convert the voxel to world coordinates */
   convert_3D_voxel_to_world(volume, v0, v1, v2, &wx, &wy, &wz);

   /* Write out the result */
   (void) printf("%.20g %.20g %.20g\n", wx, wy, wz);

   exit(EXIT_SUCCESS);
}
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);

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