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
00018
#ifndef lint
00019
static char rcsid[] =
"$Header: /software/source//libraries/bicpl/Volumes/fill_volume.c,v 1.10 2000/02/06 15:30:54 stever Exp $";
00020
#endif
00021
00022 typedef struct
00023
{
00024 int x,
y, z;
00025 }
xyz_struct;
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 public BOOLEAN
fill_connected_voxels(
00049 Volume volume,
00050 Volume label_volume,
00051 Neighbour_types connectivity,
00052
int voxel[],
00053
int min_label_threshold,
00054
int max_label_threshold,
00055
int desired_label,
00056 Real min_threshold,
00057 Real max_threshold,
00058
int range_changed[2][N_DIMENSIONS] )
00059 {
00060
int dir,
n_dirs, *dx, *dy, *dz, dim;
00061
int x,
y, z, tx, ty, tz;
00062
int sizes[N_DIMENSIONS];
00063
int voxel_index[MAX_DIMENSIONS];
00064
xyz_struct entry;
00065
QUEUE_STRUCT(
xyz_struct ) queue;
00066
bitlist_3d_struct checked_flags, change_flags;
00067 BOOLEAN first;
00068
00069
if( !
should_change_this_one( volume, label_volume, voxel,
00070 min_threshold, max_threshold,
00071 min_label_threshold, max_label_threshold,
00072 desired_label ) )
00073
return(
FALSE );
00074
00075
n_dirs =
get_3D_neighbour_directions( connectivity, &dx, &dy, &dz );
00076
00077 get_volume_sizes( volume, sizes );
00078
00079
create_bitlist_3d( sizes[X], sizes[Y], sizes[Z], &checked_flags );
00080
create_bitlist_3d( sizes[X], sizes[Y], sizes[Z], &change_flags );
00081
00082
INITIALIZE_QUEUE( queue );
00083
00084
set_bitlist_bit_3d( &checked_flags, voxel[X], voxel[Y], voxel[Z],
TRUE );
00085
set_bitlist_bit_3d( &change_flags, voxel[X], voxel[Y], voxel[Z],
TRUE );
00086
00087 entry.
x = voxel[X];
00088 entry.
y = voxel[Y];
00089 entry.
z = voxel[Z];
00090
INSERT_IN_QUEUE( queue, entry );
00091
00092
while( !
IS_QUEUE_EMPTY( queue ) )
00093 {
00094
REMOVE_FROM_QUEUE( queue, entry );
00095
00096 x = entry.
x;
00097
y = entry.
y;
00098 z = entry.
z;
00099
00100 for_less( dir, 0,
n_dirs )
00101 {
00102 tx = x + dx[dir];
00103 ty =
y + dy[dir];
00104 tz = z + dz[dir];
00105
00106
if( tx >= 0 && tx < sizes[X] &&
00107 ty >= 0 && ty < sizes[Y] &&
00108 tz >= 0 && tz < sizes[Z] &&
00109 !
get_bitlist_bit_3d( &checked_flags, tx, ty, tz ) )
00110 {
00111
set_bitlist_bit_3d( &checked_flags, tx, ty, tz,
TRUE );
00112
00113 voxel_index[X] = tx;
00114 voxel_index[Y] = ty;
00115 voxel_index[Z] = tz;
00116
if(
should_change_this_one( volume, label_volume, voxel_index,
00117 min_threshold, max_threshold,
00118 min_label_threshold, max_label_threshold,
00119 desired_label ) )
00120 {
00121
set_bitlist_bit_3d( &change_flags, tx, ty, tz,
TRUE );
00122 entry.
x = tx;
00123 entry.
y = ty;
00124 entry.
z = tz;
00125
INSERT_IN_QUEUE( queue, entry );
00126 }
00127 }
00128 }
00129 }
00130
00131 first =
TRUE;
00132
00133 for_less( voxel_index[X], 0, sizes[X] )
00134 for_less( voxel_index[Y], 0, sizes[Y] )
00135 for_less( voxel_index[Z], 0, sizes[Z] )
00136 {
00137
if(
get_bitlist_bit_3d( &change_flags, voxel_index[X], voxel_index[Y],
00138 voxel_index[Z] ) )
00139 {
00140
set_volume_label_data( label_volume, voxel_index, desired_label );
00141
00142 for_less( dim, 0, N_DIMENSIONS )
00143 {
00144
if( first || voxel_index[dim] < range_changed[0][dim] )
00145 range_changed[0][dim] = voxel_index[dim];
00146
if( first || voxel_index[dim] > range_changed[1][dim] )
00147 range_changed[1][dim] = voxel_index[dim];
00148 }
00149
00150 first =
FALSE;
00151 }
00152 }
00153
00154
delete_bitlist_3d( &checked_flags );
00155
delete_bitlist_3d( &change_flags );
00156
00157
DELETE_QUEUE( queue );
00158
00159
return(
TRUE );
00160 }
00161
00162 private int Dx4[4] = { 1, 0, -1, 0 };
00163 private int Dy4[4] = { 0, 1, 0, -1 };
00164
00165 private int Dx8[8] = { 1, 1, 0, -1, -1, -1, 0, 1 };
00166 private int Dy8[8] = { 0, 1, 1, 1, 0, -1, -1, -1 };
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 public int get_neighbour_directions(
00183 Neighbour_types connectivity,
00184
int *dx[],
00185
int *dy[] )
00186 {
00187
int n_dirs;
00188
00189
switch( connectivity )
00190 {
00191
case FOUR_NEIGHBOURS:
00192 *dx =
Dx4;
00193 *dy =
Dy4;
00194
n_dirs = 4;
00195
break;
00196
00197
case EIGHT_NEIGHBOURS:
00198 *dx =
Dx8;
00199 *dy =
Dy8;
00200
n_dirs = 8;
00201
break;
00202 }
00203
00204
return(
n_dirs );
00205 }
00206
00207 private int Dx6[6] = { 1, 0, 0, -1, 0, 0 };
00208 private int Dy6[6] = { 0, 1, 0, 0, -1, 0 };
00209 private int Dz6[6] = { 0, 0, 1, 0, 0, -1 };
00210
00211 private int Dx26[26];
00212 private int Dy26[26];
00213 private int Dz26[26];
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 private void create_3D_neighbours(
void )
00229 {
00230
int x,
y, z, n;
00231
00232 n = 0;
00233 for_inclusive( x, -1, 1 )
00234 for_inclusive(
y, -1, 1 )
00235 for_inclusive( z, -1, 1 )
00236 {
00237
if( x != 0 ||
y != 0 || z != 0 )
00238 {
00239
Dx26[n] = x;
00240
Dy26[n] =
y;
00241
Dz26[n] = z;
00242 ++n;
00243 }
00244 }
00245
00246
if( n != 26 )
00247 {
00248 HANDLE_INTERNAL_ERROR(
"create_3D_neighbours" );
00249 }
00250 }
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267 public int get_3D_neighbour_directions(
00268 Neighbour_types connectivity,
00269
int *dx[],
00270
int *dy[],
00271
int *dz[] )
00272 {
00273
static BOOLEAN first =
TRUE;
00274
int n_dirs;
00275
00276
if( first )
00277 {
00278 first =
FALSE;
00279
create_3D_neighbours();
00280 }
00281
00282
switch( connectivity )
00283 {
00284
case FOUR_NEIGHBOURS:
00285 *dx =
Dx6;
00286 *dy =
Dy6;
00287 *dz =
Dz6;
00288
n_dirs = 6;
00289
break;
00290
00291
case EIGHT_NEIGHBOURS:
00292 *dx =
Dx26;
00293 *dy =
Dy26;
00294 *dz =
Dz26;
00295
n_dirs = 26;
00296
break;
00297 }
00298
00299
return(
n_dirs );
00300 }
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 public BOOLEAN
should_change_this_one(
00323 Volume volume,
00324 Volume label_volume,
00325
int voxel[],
00326 Real min_threshold,
00327 Real max_threshold,
00328
int label_min_threshold,
00329
int label_max_threshold,
00330
int desired_label )
00331 {
00332
int label;
00333 Real value;
00334
00335 label =
get_volume_label_data( label_volume, voxel );
00336
00337
if( label == desired_label )
00338
return(
FALSE );
00339
00340
if( label_min_threshold <= label_max_threshold &&
00341 (label < label_min_threshold || label > label_max_threshold) )
00342
return(
FALSE );
00343
00344
if( min_threshold > max_threshold )
00345
return(
TRUE );
00346
00347 value = get_volume_real_value( volume, voxel[X], voxel[Y], voxel[Z], 0, 0 );
00348
00349
return( min_threshold <= value && value <= max_threshold );
00350 }