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.h>
00017
00018
#ifndef lint
00019
static char rcsid[] =
"$Header: /software/source//libraries/bicpl/Volumes/crop_volume.c,v 1.9 2000/02/05 21:27:24 stever Exp $";
00020
#endif
00021
00022 #define MAX_BUFFER_SIZE 100000
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 public BOOLEAN
find_volume_crop_bounds(
00041 Volume volume,
00042 Real min_crop_threshold,
00043 Real max_crop_threshold,
00044
int limits[2][MAX_DIMENSIONS] )
00045 {
00046
int dim, n_dims, lim, voxel[MAX_DIMENSIONS], sizes[MAX_DIMENSIONS];
00047
int start, end, step, voxel_pos, new_limits[2];
00048
int start0, start1, start2, start3, start4;
00049
int end0, end1, end2, end3, end4;
00050 Real value;
00051 BOOLEAN found;
00052
00053 n_dims = get_volume_n_dimensions( volume );
00054 get_volume_sizes( volume, sizes );
00055
00056 for_less( dim, 0, MAX_DIMENSIONS )
00057 {
00058 limits[0][dim] = 0;
00059
00060
if( dim < n_dims )
00061 limits[1][dim] = sizes[dim]-1;
00062
else
00063 limits[1][dim] = 0;
00064 }
00065
00066 for_less( dim, 0, n_dims )
00067 {
00068 limits[0][dim] = 0;
00069 limits[1][dim] = 0;
00070
00071 start0 = limits[0][0];
00072 start1 = limits[0][1];
00073 start2 = limits[0][2];
00074 start3 = limits[0][3];
00075 start4 = limits[0][4];
00076 end0 = limits[1][0];
00077 end1 = limits[1][1];
00078 end2 = limits[1][2];
00079 end3 = limits[1][3];
00080 end4 = limits[1][4];
00081
00082 for_less( lim, 0, 2 )
00083 {
00084
if( lim == 0 )
00085 {
00086 start = 0;
00087 end = sizes[dim];
00088 step = 1;
00089 }
00090
else
00091 {
00092 start = sizes[dim]-1;
00093 end = -1;
00094 step = -1;
00095 }
00096
00097 found =
FALSE;
00098
00099
for( voxel_pos = start; voxel_pos != end; voxel_pos += step )
00100 {
00101 for_inclusive( voxel[0], start0, end0 )
00102 {
00103 for_inclusive( voxel[1], start1, end1 )
00104 {
00105 for_inclusive( voxel[2], start2, end2 )
00106 {
00107 for_inclusive( voxel[3], start3, end3 )
00108 {
00109 for_inclusive( voxel[4], start4, end4 )
00110 {
00111 voxel[dim] = voxel_pos;
00112
00113 value = get_volume_real_value( volume,
00114 voxel[0], voxel[1],
00115 voxel[2], voxel[3], voxel[4] );
00116
00117
if( value < min_crop_threshold ||
00118 value > max_crop_threshold )
00119 {
00120 found =
TRUE;
00121
break;
00122 }
00123 }
00124
if( found )
00125
break;
00126 }
00127
if( found )
00128
break;
00129 }
00130
if( found )
00131
break;
00132 }
00133
if( found )
00134
break;
00135 }
00136
00137
if( found )
00138
break;
00139 }
00140
00141 new_limits[lim] = voxel_pos;
00142 }
00143
00144 limits[0][dim] = new_limits[0];
00145 limits[1][dim] = new_limits[1];
00146 }
00147
00148
return( limits[0][X] <= limits[1][X] );
00149 }
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 public Volume
create_cropped_volume(
00166 Volume volume,
00167
int limits[2][MAX_DIMENSIONS] )
00168 {
00169
int dim, n_dims;
00170
int sizes[MAX_DIMENSIONS], new_sizes[MAX_DIMENSIONS];
00171
int v0, v1, v2, v3, v4, offset[MAX_DIMENSIONS];
00172
int start[MAX_DIMENSIONS], end[MAX_DIMENSIONS];
00173 nc_type nc_data_type;
00174 Real separations[MAX_DIMENSIONS];
00175 Real start_voxel[MAX_DIMENSIONS];
00176 Real xyz[N_DIMENSIONS], voxel_value;
00177 Real min_voxel, max_voxel;
00178 BOOLEAN signed_flag, is_fully_inside;
00179 STRING *dim_names;
00180 Volume cropped_volume;
00181 General_transform cropped_transform, offset_transform;
00182 Transform translation;
00183
00184 n_dims = get_volume_n_dimensions( volume );
00185 get_volume_sizes( volume, sizes );
00186
00187 dim_names = get_volume_dimension_names( volume );
00188
00189 nc_data_type = get_volume_nc_data_type( volume, &signed_flag );
00190 get_volume_voxel_range( volume, &min_voxel, &max_voxel );
00191
00192 cropped_volume = create_volume( n_dims, dim_names,
00193 nc_data_type, signed_flag,
00194 min_voxel, max_voxel );
00195
00196 delete_dimension_names( volume, dim_names );
00197
00198 is_fully_inside =
TRUE;
00199
00200 for_less( dim, 0, n_dims )
00201 {
00202 new_sizes[dim] = limits[1][dim] - limits[0][dim] + 1;
00203
00204
if( limits[0][dim] < 0 || limits[1][dim] >= sizes[dim] )
00205 is_fully_inside =
FALSE;
00206 }
00207
00208 set_volume_sizes( cropped_volume, new_sizes );
00209 alloc_volume_data( cropped_volume );
00210
00211 set_volume_real_range( cropped_volume,
00212 get_volume_real_min(volume),
00213 get_volume_real_max(volume) );
00214
00215 get_volume_separations( volume, separations );
00216 set_volume_separations( cropped_volume, separations );
00217
00218 for_less( dim, 0, n_dims )
00219 start_voxel[dim] = (Real) limits[0][dim];
00220
00221 reorder_voxel_to_xyz( volume, start_voxel, xyz );
00222
00223
make_translation_transform( xyz[X], xyz[Y], xyz[Z], &translation );
00224 create_linear_transform( &offset_transform, &translation );
00225 concat_general_transforms( &offset_transform,
00226 get_voxel_to_world_transform(volume),
00227 &cropped_transform );
00228
00229 set_voxel_to_world_transform( cropped_volume, &cropped_transform );
00230
00231 delete_general_transform( &offset_transform );
00232
00233 for_less( dim, 0, n_dims )
00234 {
00235 offset[dim] = limits[0][dim];
00236 start[dim] = MAX( 0, -limits[0][dim] );
00237 end[dim] = MIN( new_sizes[dim]-1, sizes[dim] - 1 - limits[0][dim] );
00238 }
00239
00240 for_less( dim, n_dims, MAX_DIMENSIONS )
00241 {
00242 start[dim] = 0;
00243 end[dim] = 0;
00244 offset[dim] = 0;
00245 }
00246
00247
if( !is_fully_inside )
00248 {
00249 BEGIN_ALL_VOXELS( cropped_volume, v0, v1, v2, v3, v4 )
00250 set_volume_real_value( cropped_volume, v0, v1, v2, v3, v4, 0.0 );
00251 END_ALL_VOXELS
00252 }
00253
00254 for_inclusive( v0, start[0], end[0] )
00255 for_inclusive( v1, start[1], end[1] )
00256 for_inclusive( v2, start[2], end[2] )
00257 for_inclusive( v3, start[3], end[3] )
00258 for_inclusive( v4, start[4], end[4] )
00259 {
00260 voxel_value = get_volume_voxel_value( volume,
00261 v0 + offset[0], v1 + offset[1],
00262 v2 + offset[2], v3 + offset[3],
00263 v4 + offset[4] );
00264 set_volume_voxel_value( cropped_volume, v0, v1, v2, v3, v4,
00265 voxel_value );
00266 }
00267
00268
return( cropped_volume );
00269 }
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 public Volume
autocrop_volume(
00286 Volume volume )
00287 {
00288 Volume cropped;
00289
int dim, limits[2][MAX_DIMENSIONS];
00290
00291
if( !
find_volume_crop_bounds( volume, 0.0, 0.0, limits ) )
00292 {
00293 for_less( dim, 0, N_DIMENSIONS )
00294 {
00295 limits[0][dim] = 0;
00296 limits[1][dim] = 0;
00297 }
00298 }
00299
00300 cropped =
create_cropped_volume( volume, limits );
00301
00302
return( cropped );
00303 }