Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages

crop_volume.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------- 00002 @COPYRIGHT : 00003 Copyright 1993,1994,1995 David MacDonald, 00004 McConnell Brain Imaging Centre, 00005 Montreal Neurological Institute, McGill University. 00006 Permission to use, copy, modify, and distribute this 00007 software and its documentation for any purpose and without 00008 fee is hereby granted, provided that the above copyright 00009 notice appear in all copies. The author and McGill University 00010 make no representations about the suitability of this 00011 software for any purpose. It is provided "as is" without 00012 express or implied warranty. 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 /* ----------------------------- MNI Header ----------------------------------- 00025 @NAME : find_volume_crop_bounds 00026 @INPUT : volume 00027 min_crop_threshold 00028 max_crop_threshold 00029 @OUTPUT : limits 00030 @RETURNS : TRUE if volume can be cropped 00031 @DESCRIPTION: Checks if the volume can be cropped, where values between 00032 min_crop_threshold and max_crop_threshold can be cropped. 00033 @METHOD : 00034 @GLOBALS : 00035 @CALLS : 00036 @CREATED : 1995 David MacDonald 00037 @MODIFIED : Aug. 1, 1995 D. MacDonald - made it faster 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 /* ----------------------------- MNI Header ----------------------------------- 00152 @NAME : create_cropped_volume 00153 @INPUT : volume 00154 limits 00155 @OUTPUT : 00156 @RETURNS : cropped volume 00157 @DESCRIPTION: Crops a volume to the specified limits. 00158 @METHOD : 00159 @GLOBALS : 00160 @CALLS : 00161 @CREATED : 1993 David MacDonald 00162 @MODIFIED : 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 /* ----------------------------- MNI Header ----------------------------------- 00272 @NAME : autocrop_volume 00273 @INPUT : volume 00274 @OUTPUT : 00275 @RETURNS : a volume 00276 @DESCRIPTION: Creates a new volume which is the input volume cropped down 00277 to exclude regions containing only zero values. 00278 @METHOD : 00279 @GLOBALS : 00280 @CALLS : 00281 @CREATED : Dec. 8, 1995 David MacDonald 00282 @MODIFIED : 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 }

Generated on Wed Jul 28 09:10:57 2004 for BICPL by doxygen 1.3.7