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); }
void get_volume(float *data, VIO_Volume vol, int *sizes){ int i,j,k; for (i=0;i<sizes[0];i++) for (j=0;j<sizes[1];j++) for (k=0;k<sizes[2];k++) set_volume_real_value(vol,i,j,k,0,0,data[i*sizes[1]*sizes[2]+j*sizes[2]+k]); }
/* 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); }
/* 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); }
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); }
/* 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); }
/* 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); }
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 ); }
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); }
/* 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]]; } }
int main(int argc, char *argv[]) { char **infiles; int n_infiles; char *out_fn; char *history; VIO_progress_struct progress; VIO_Volume totals, weights; int i, j, k, v; double min, max; double w_min, w_max; long num_missed; double weight, value; double initial_weight; VIO_Real dummy[3]; int sizes[MAX_VAR_DIMS]; double starts[MAX_VAR_DIMS]; double steps[MAX_VAR_DIMS]; long t = 0; /* start the time counter */ current_realtime_seconds(); /* get the history string */ history = time_stamp(argc, argv); /* get args */ if(ParseArgv(&argc, argv, argTable, 0) || (argc < 3)){ fprintf(stderr, "\nUsage: %s [options] <in1.mnc> [<in2.mnc> [...]] <out.mnc>\n", argv[0]); fprintf(stderr, " %s [options] -arb_path pth.conf <infile.raw> <out.mnc>\n", argv[0]); fprintf(stderr, " %s -help\n\n", argv[0]); exit(EXIT_FAILURE); } /* get file names */ n_infiles = argc - 2; infiles = (char **)malloc(sizeof(char *) * n_infiles); for(i = 0; i < n_infiles; i++){ infiles[i] = argv[i + 1]; } out_fn = argv[argc - 1]; /* check for infiles and outfile */ for(i = 0; i < n_infiles; i++){ if(!file_exists(infiles[i])){ fprintf(stderr, "%s: Couldn't find input file %s.\n\n", argv[0], infiles[i]); exit(EXIT_FAILURE); } } if(!clobber && file_exists(out_fn)){ fprintf(stderr, "%s: %s exists, -clobber to overwrite.\n\n", argv[0], out_fn); exit(EXIT_FAILURE); } /* check for weights_fn if required */ if(weights_fn != NULL){ if(!clobber && file_exists(weights_fn)){ fprintf(stderr, "%s: %s exists, -clobber to overwrite.\n\n", argv[0], weights_fn); exit(EXIT_FAILURE); } } /* set up parameters for reconstruction */ if(out_dtype == NC_UNSPECIFIED){ out_dtype = in_dtype; } if(out_is_signed == DEF_BOOL){ out_is_signed = in_is_signed; } /* check vector dimension size */ if(vect_size < 1){ fprintf(stderr, "%s: -vector (%d) must be 1 or greater.\n\n", argv[0], vect_size); exit(EXIT_FAILURE); } /* check sigma */ if(regrid_sigma[0] <= 0 || regrid_sigma[1] <= 0 || regrid_sigma[2] <= 0 ){ fprintf(stderr, "%s: -sigma must be greater than 0\n\n", argv[0]); exit(EXIT_FAILURE); } /* read in the output file config from a file is specified */ if(out_config_fn != NULL){ int ext_args_c; char *ext_args[32]; /* max possible is 32 arguments */ ext_args_c = read_config_file(out_config_fn, ext_args); if(ParseArgv(&ext_args_c, ext_args, argTable, ARGV_DONT_SKIP_FIRST_ARG | ARGV_NO_LEFTOVERS | ARGV_NO_DEFAULTS)){ fprintf(stderr, "\nError in parameters in %s\n", out_config_fn); exit(EXIT_FAILURE); } } if(verbose){ fprintf_vol_def(stdout, &out_inf); } /* transpose the geometry arrays */ /* out_inf.*[] are in world xyz order, perm[] is the permutation array to map world xyz to the right voxel order in the volume */ for(i = 0; i < WORLD_NDIMS; i++){ sizes[i] = out_inf.nelem[perm[i]]; /* sizes, starts, steps are in voxel volume order. */ starts[i] = out_inf.start[perm[i]]; steps[i] = out_inf.step[perm[i]]; } sizes[WORLD_NDIMS] = vect_size; /* create the totals volume */ totals = create_volume((vect_size > 1) ? 4 : 3, (vect_size > 1) ? std_dimorder_v : std_dimorder, out_dtype, out_is_signed, 0.0, 0.0); set_volume_sizes(totals, sizes); set_volume_starts(totals, starts); set_volume_separations(totals, steps); for(i = 0; i < WORLD_NDIMS; i++){ /* out_inf.dircos is in world x,y,z order, we have to use the perm array to map each direction to the right voxel axis. */ set_volume_direction_cosine(totals, i, out_inf.dircos[perm[i]]); } alloc_volume_data(totals); /* create the "weights" volume */ weights = create_volume(3, std_dimorder, out_dtype, out_is_signed, 0.0, 0.0); set_volume_sizes(weights, sizes); set_volume_starts(weights, starts); set_volume_separations(weights, steps); for(i = 0; i < WORLD_NDIMS; i++){ set_volume_direction_cosine(weights, i, out_inf.dircos[perm[i]]); } alloc_volume_data(weights); /* down below in regrid_loop, Andrew makes a nasty direct reference to the voxel_to_world transformation in the volume. This transformation is not necessarily up to date, particularly when non-default direction cosines are used. In volume_io, the direction cosines are set and a FLAG is also set to indicate that the voxel-to-world xform is not up to date. If the stanrd volume_io general transform code is used, it checks internally to see if the matrix is up to date, and if not it is recomputed. So here, we'll (LC + MK) force an update by calling a general transform. */ // convert_world_to_voxel(weights, (Real) 0, (Real) 0, (Real) 0, dummy); // convert_world_to_voxel(totals, (Real) 0, (Real) 0, (Real) 0, dummy); fprintf(stderr, "2Sizes: [%d:%d:%d] \n", sizes[perm[0]], sizes[perm[1]], sizes[perm[2]]); /* initialize weights to be arbitray large value if using NEAREST */ /* volume interpolation else initialize all to zero */ if(regrid_type == NEAREST_FUNC && ap_coord_fn == NULL){ initial_weight = LARGE_INITIAL_WEIGHT; } else{ initial_weight = 0.0; } /* initialize weights and totals */ for(k = sizes[Z_IDX]; k--;){ for(j = sizes[Y_IDX]; j--;){ for(i = sizes[X_IDX]; i--;){ set_volume_real_value(weights, k, j, i, 0, 0, initial_weight); for(v = vect_size; v--;){ set_volume_real_value(totals, k, j, i, v, 0, 0.0); } } } } /* if regridding via an arbitrary path */ if(ap_coord_fn != NULL){ if(n_infiles > 1){ fprintf(stderr, "%s: arb_path only works for one input file (so far).\n\n", argv[0]); exit(EXIT_FAILURE); } /* print some pretty output */ if(verbose){ fprintf(stdout, " | Input data: %s\n", infiles[0]); fprintf(stdout, " | Arb path: %s\n", ap_coord_fn); fprintf(stdout, " | Output range: [%g:%g]\n", out_range[0], out_range[1]); fprintf(stdout, " | Output file: %s\n", out_fn); } regrid_arb_path(ap_coord_fn, infiles[0], max_buffer_size_in_kb, &totals, &weights, vect_size, regrid_range[0], regrid_range[1]); } /* else if regridding via a series of input minc file(s) */ else { for(i = 0; i < n_infiles; i++){ if(verbose){ fprintf(stdout, " | Input file: %s\n", infiles[i]); } regrid_minc(infiles[i], max_buffer_size_in_kb, &totals, &weights, vect_size, regrid_range[0], regrid_range[1]); } } /* initialise min and max counters and divide totals/weights */ num_missed = 0; min = get_volume_real_value(totals, 0, 0, 0, 0, 0); max = get_volume_real_value(totals, 0, 0, 0, 0, 0); w_min = get_volume_real_value(weights, 0, 0, 0, 0, 0); w_max = get_volume_real_value(weights, 0, 0, 0, 0, 0); initialize_progress_report(&progress, FALSE, out_inf.nelem[Z_IDX], "Dividing through"); for(i = sizes[perm[0]]; i--;){ for(j = sizes[perm[1]]; j--;){ for(k = sizes[perm[2]]; k--;){ weight = get_volume_real_value(weights, k, j, i, 0, 0); if(weight < w_min){ w_min = weight; } else if(weight > w_max){ w_max = weight; } if(weight != 0){ for(v = vect_size; v--;){ value = get_volume_real_value(totals, k, j, i, v, 0) / weight; if(value < min){ min = value; } else if(value > max){ max = value; } set_volume_real_value(totals, k, j, i, v, 0, value); } } else { num_missed++; } } } update_progress_report(&progress, k + 1); } terminate_progress_report(&progress); /* set the volumes range */ if(verbose){ fprintf(stdout, " + data range: [%g:%g]\n", min, max); fprintf(stdout, " + weight range: [%g:%g]\n", w_min, w_max); } set_volume_real_range(totals, min, max); set_volume_real_range(weights, w_min, w_max); if(num_missed > 0 && verbose){ int nvox; nvox = out_inf.nelem[X_IDX] * out_inf.nelem[Y_IDX] * out_inf.nelem[Z_IDX]; fprintf(stdout, "\n-regrid_radius possibly too small, no data in %ld/%d[%2.2f%%] voxels\n\n", num_missed, nvox, ((float)num_missed / nvox * 100)); } /* rescale data if required */ if(out_range[0] != -DBL_MAX && out_range[1] != DBL_MAX){ double o_min, o_max; /* get the existing range */ get_volume_real_range(totals, &o_min, &o_max); /* rescale it */ scale_volume(&totals, o_min, o_max, out_range[0], out_range[1]); } /* output the result */ if(verbose){ fprintf(stdout, " | Outputting %s...\n", out_fn); } if(output_volume(out_fn, out_dtype, out_is_signed, 0.0, 0.0, totals, history, NULL) != VIO_OK){ fprintf(stderr, "Problems outputing: %s\n\n", out_fn); } /* output weights volume if required */ if(weights_fn != NULL){ if(verbose){ fprintf(stdout, " | Outputting %s...\n", weights_fn); } if(output_volume(weights_fn, out_dtype, out_is_signed, 0.0, 0.0, weights, history, NULL) != VIO_OK){ fprintf(stderr, "Problems outputting: %s\n\n", weights_fn); } } delete_volume(totals); delete_volume(weights); t = current_realtime_seconds(); printf("Total reconstruction time: %ld hours %ld minutes %ld seconds\n", t/3600, (t/60)%60, t%60); return (EXIT_SUCCESS); }
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); }
/* ----------------------------- 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; }