00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
#include <volume_io/internal_volume_io.h>
00016
#include <bicpl/vols.h>
00017
#include <bicpl/geom.h>
00018
#include <bicpl/trans.h>
00019
00020
#ifndef lint
00021
static char rcsid[] =
"$Header: /software/source//libraries/bicpl/Volumes/smooth.c,v 1.21 2000/02/06 15:30:57 stever Exp $";
00022
#endif
00023
00024
private Real
calculate_weight(
00025
int x,
00026 Real dx,
00027 Real x_min,
00028 Real x_max );
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 public Volume
smooth_resample_volume(
00048 Volume volume,
00049
int new_nx,
00050
int new_ny,
00051
int new_nz )
00052 {
00053 Volume resampled_volume;
00054
int sizes[MAX_DIMENSIONS], new_sizes[MAX_DIMENSIONS];
00055
int dest_voxel[N_DIMENSIONS], src_voxel[N_DIMENSIONS], c;
00056 Real x_min, x_max, y_min, y_max, z_min, z_max;
00057 Real separations[N_DIMENSIONS];
00058 Real dx, dy, dz;
00059 Real voxel;
00060 Real x_weight, xy_weight, weight;
00061 Real *y_weights, *z_weights;
00062 Real val;
00063 Transform scale_transform, translation_transform, transform;
00064 General_transform general_transform, tmp;
00065 progress_struct progress;
00066
00067
if( get_volume_n_dimensions(volume) != 3 )
00068 {
00069 handle_internal_error(
"smooth_resample_volume: volume must be 3D.\n" );
00070 }
00071
00072 get_volume_sizes( volume, sizes );
00073
00074 new_sizes[X] = new_nx;
00075 new_sizes[Y] = new_ny;
00076 new_sizes[Z] = new_nz;
00077
00078 for_less( c, 0, N_DIMENSIONS )
00079
if( new_sizes[c] <= 0 )
00080 new_sizes[c] = sizes[c];
00081
00082 resampled_volume = create_volume( 3, volume->dimension_names,
00083 volume->nc_data_type,
00084 volume->signed_flag,
00085 get_volume_voxel_min(volume),
00086 get_volume_voxel_max(volume) );
00087
00088 set_volume_sizes( resampled_volume, new_sizes );
00089
00090 set_volume_real_range( resampled_volume, get_volume_real_min(volume),
00091 get_volume_real_max(volume) );
00092
00093 dx = (Real) sizes[X] / (Real) new_sizes[X];
00094 dy = (Real) sizes[Y] / (Real) new_sizes[Y];
00095 dz = (Real) sizes[Z] / (Real) new_sizes[Z];
00096
00097 get_volume_separations( volume, separations );
00098
00099 separations[X] *= dx;
00100 separations[Y] *= dy;
00101 separations[Z] *= dz;
00102
00103 set_volume_separations( resampled_volume, separations );
00104
00105
make_translation_transform( dx / 2.0 - 0.5, dy / 2.0 - 0.5, dz / 2.0 - 0.5,
00106 &translation_transform );
00107
make_scale_transform( dx, dy, dz, &scale_transform );
00108
00109 concat_transforms( &transform, &scale_transform, &translation_transform );
00110
00111 create_linear_transform( &tmp, &transform );
00112
00113 concat_general_transforms( &tmp, get_voxel_to_world_transform(volume),
00114 &general_transform );
00115 delete_general_transform( &tmp );
00116
00117 set_voxel_to_world_transform( resampled_volume, &general_transform );
00118
00119 alloc_volume_data( resampled_volume );
00120
00121 ALLOC( y_weights, (
int) dy + 2 );
00122 ALLOC( z_weights, (
int) dz + 2 );
00123
00124 initialize_progress_report( &progress,
FALSE, new_nx * new_ny,
00125
"Resampling" );
00126
00127 for_less( dest_voxel[X], 0, new_nx )
00128 {
00129 x_min = (Real) dest_voxel[X] * dx;
00130 x_max = (Real) (dest_voxel[X]+1) * dx;
00131
00132 for_less( dest_voxel[Y], 0, new_ny )
00133 {
00134 y_min = (Real) dest_voxel[Y] * dy;
00135 y_max = (Real) (dest_voxel[Y]+1) * dy;
00136
00137 for_less( dest_voxel[Z], 0, new_nz )
00138 {
00139 z_min = (Real) dest_voxel[Z] * dz;
00140 z_max = (Real) (dest_voxel[Z]+1) * dz;
00141
00142 for_inclusive( src_voxel[Y], (
int) y_min, (
int) y_max )
00143 {
00144 y_weights[src_voxel[Y]-(
int)y_min] =
00145
calculate_weight( src_voxel[Y], dy, y_min, y_max );
00146 }
00147
00148 for_inclusive( src_voxel[Z], (
int) z_min, (
int) z_max )
00149 {
00150 z_weights[src_voxel[Z]-(
int)z_min] =
00151
calculate_weight( src_voxel[Z], dz, z_min, z_max );
00152 }
00153
00154 val = 0.0;
00155
00156 for_inclusive( src_voxel[X], (
int) x_min, (
int) x_max )
00157 {
00158 x_weight =
calculate_weight( src_voxel[X], dx,
00159 x_min, x_max );
00160
00161 for_inclusive( src_voxel[Y], (
int) y_min, (
int) y_max )
00162 {
00163 xy_weight = x_weight *
00164 y_weights[src_voxel[Y]-(
int)y_min];
00165
00166 for_inclusive( src_voxel[Z], (
int) z_min, (
int) z_max )
00167 {
00168 weight = xy_weight *
00169 z_weights[src_voxel[Z]-(
int)z_min];
00170
00171
if( weight > 0.0 )
00172 {
00173 voxel = get_volume_voxel_value( volume,
00174 src_voxel[X], src_voxel[Y],
00175 src_voxel[Z], 0, 0 );
00176 val += weight * voxel;
00177 }
00178 }
00179 }
00180 }
00181
00182 set_volume_voxel_value( resampled_volume,
00183 dest_voxel[X], dest_voxel[Y], dest_voxel[Z], 0, 0,
00184 val + 0.5 );
00185 }
00186
00187 update_progress_report( &progress,
00188 dest_voxel[X] * new_ny + dest_voxel[Y] + 1 );
00189 }
00190 }
00191
00192 terminate_progress_report( &progress );
00193
00194 FREE( y_weights );
00195 FREE( z_weights );
00196
00197
return( resampled_volume );
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 private Real
calculate_weight(
00217
int x,
00218 Real dx,
00219 Real x_min,
00220 Real x_max )
00221 {
00222 Real start, end, weight;
00223
00224 start = MAX( x_min, (Real) x );
00225 end = MIN( x_max, (Real) (x+1) );
00226
00227
if( end < start || end - start > 1.0 )
00228 {
00229 handle_internal_error(
"calculate_weight" );
00230 }
00231
00232 weight = (end - start) / dx;
00233
00234
return( weight );
00235 }