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

search_utils.c

Go to the documentation of this file.
00001 #include <volume_io/internal_volume_io.h> 00002 #include <bicpl/deform.h> 00003 00004 public BOOLEAN is_point_inside_surface( 00005 Volume volume, 00006 Volume label_volume, 00007 int continuity, 00008 Real voxel[], 00009 Vector *direction, 00010 boundary_definition_struct *boundary_def ) 00011 { 00012 BOOLEAN active; 00013 Real value, mag, dx, dy, dz, dot_product; 00014 Real derivs[MAX_DIMENSIONS], *deriv_ptr[1]; 00015 Real min_dot, max_dot; 00016 00017 active = get_volume_voxel_activity( label_volume, voxel, FALSE ); 00018 00019 if( !active ) 00020 return( FALSE ); 00021 00022 deriv_ptr[0] = derivs; 00023 00024 evaluate_volume( volume, voxel, NULL, continuity, FALSE, 00025 get_volume_real_min(volume), 00026 &value, deriv_ptr, NULL ); 00027 00028 if( value < boundary_def->min_isovalue ) 00029 return( FALSE ); 00030 else if( value >= boundary_def->max_isovalue ) 00031 return( TRUE ); 00032 00033 convert_voxel_normal_vector_to_world( volume, derivs, 00034 &dx, &dy, &dz ); 00035 00036 mag = dx * dx + dy * dy + dz * dz; 00037 00038 if( mag < 00039 boundary_def->gradient_threshold * boundary_def->gradient_threshold ) 00040 return( FALSE ); 00041 00042 if( mag == 0.0 ) 00043 mag = 1.0; 00044 00045 dot_product = dx * (Real) Vector_x(*direction) + 00046 dy * (Real) Vector_y(*direction) + 00047 dz * (Real) Vector_z(*direction); 00048 00049 min_dot = boundary_def->min_dot_product; 00050 max_dot = boundary_def->max_dot_product; 00051 00052 if( min_dot <= -1.0 && max_dot == 0.0 ) 00053 return( dot_product <= 0.0 ); 00054 else if( min_dot == 0.0 && max_dot >= 1.0 ) 00055 return( dot_product >= 0.0 ); 00056 else if( min_dot <= -1.0 && max_dot >= 1.0 ) 00057 return( TRUE ); 00058 else 00059 { 00060 dot_product /= sqrt(mag); 00061 00062 return( dot_product >= min_dot && dot_product <= max_dot ); 00063 } 00064 } 00065 00066 public void get_centre_of_cube( 00067 Point *cube, 00068 int sizes[3], 00069 Point *centre ) 00070 { 00071 int c; 00072 00073 for_less( c, 0, 3 ) 00074 { 00075 if( sizes[c] > 1 ) 00076 Point_coord(*centre,c) = (Point_coord_type) ( 00077 ((Real) Point_coord(cube[0],c) + 00078 (Real) Point_coord(cube[1],c)) / 2.0); 00079 else 00080 Point_coord(*centre,c) = Point_coord(cube[0],c); 00081 } 00082 } 00083 00084 public BOOLEAN contains_value( 00085 Real values[2][2][2], 00086 int sizes[3] ) 00087 { 00088 BOOLEAN under_found, over_found; 00089 int x, y, z; 00090 00091 for_less( x, 0, sizes[X] ) 00092 { 00093 for_less( y, 0, sizes[Y] ) 00094 { 00095 for_less( z, 0, sizes[Z] ) 00096 { 00097 if( values[x][y][z] == 0.0 ) 00098 { 00099 return( TRUE ); 00100 } 00101 else if( x == 0 && y == 0 && z == 0 ) 00102 { 00103 under_found = (values[x][y][z] < 0.0); 00104 over_found = (values[x][y][z] > 0.0); 00105 } 00106 else if( values[x][y][z] < 0.0 ) 00107 { 00108 if( over_found ) 00109 return( TRUE ); 00110 under_found = TRUE; 00111 } 00112 else if( values[x][y][z] > 0.0 ) 00113 { 00114 if( under_found ) 00115 return( TRUE ); 00116 over_found = TRUE; 00117 } 00118 } 00119 } 00120 } 00121 00122 return( FALSE ); 00123 } 00124 00125 public BOOLEAN cube_is_small_enough( 00126 Point cube[2], 00127 int sizes[3], 00128 Real min_cube_size ) 00129 { 00130 BOOLEAN small_enough; 00131 Real size_in_dimension; 00132 int c; 00133 00134 small_enough = TRUE; 00135 00136 for_less( c, 0, 3 ) 00137 { 00138 size_in_dimension = (Real) Point_coord(cube[sizes[c]-1],c ) - 00139 (Real) Point_coord(cube[0],c ); 00140 if( size_in_dimension > min_cube_size ) 00141 { 00142 small_enough = FALSE; 00143 break; 00144 } 00145 } 00146 00147 return( small_enough ); 00148 } 00149 00150 public void initialize_deform_stats( 00151 deform_stats *stats ) 00152 { 00153 int i; 00154 00155 stats->average = 0.0; 00156 stats->maximum = 0.0; 00157 00158 for_less( i, 0, N_DEFORM_HISTOGRAM ) 00159 stats->n_below[i] = 0; 00160 } 00161 00162 public void record_error_in_deform_stats( 00163 deform_stats *stats, 00164 Real error ) 00165 { 00166 int i; 00167 00168 stats->average += error; 00169 if( error > stats->maximum ) 00170 stats->maximum = error; 00171 00172 i = N_DEFORM_HISTOGRAM-1; 00173 while( i >= 0 && error <= (Real) (i+1) ) 00174 { 00175 ++stats->n_below[i]; 00176 --i; 00177 } 00178 } 00179 00180 public void print_deform_stats( 00181 deform_stats *stats, 00182 int n_points ) 00183 { 00184 int i, n_above; 00185 00186 print( "avg %5.2f max %6.2f hist:", 00187 stats->average / (Real) n_points, stats->maximum ); 00188 00189 for_less( i, 0, N_DEFORM_HISTOGRAM ) 00190 { 00191 if( i < N_DEFORM_HISTOGRAM-1 ) 00192 n_above = stats->n_below[i+1] - stats->n_below[i]; 00193 else 00194 n_above = n_points - stats->n_below[i]; 00195 00196 if( stats->n_below[i] == n_points ) 00197 break; 00198 00199 if( n_above == 0 ) 00200 print( " " ); 00201 else if( n_above < 100 ) 00202 print( " %4d", n_above ); 00203 else 00204 print( " %3.0f%%", 100.0 * (Real) n_above / (Real) n_points ); 00205 } 00206 print( "\n" ); 00207 } 00208 00209 public BOOLEAN get_max_point_cube_distance( 00210 Point cube[2], 00211 int sizes[3], 00212 Point *point, 00213 Real *distance ) 00214 { 00215 int c; 00216 Real dist_to_low, dist_to_high, dist, max_dist; 00217 00218 max_dist = 0.0; 00219 00220 for_less( c, 0, 3 ) 00221 { 00222 if( sizes[c] > 1 ) 00223 { 00224 dist_to_low = (Real) Point_coord(*point,c) - 00225 (Real) Point_coord(cube[0],c); 00226 dist_to_high = (Real) Point_coord(cube[1],c) - 00227 (Real) Point_coord(*point,c); 00228 00229 dist = MAX( dist_to_low, dist_to_high ); 00230 max_dist += dist * dist; 00231 } 00232 } 00233 00234 max_dist = sqrt( (double) max_dist ); 00235 00236 if( max_dist < *distance ) 00237 { 00238 *distance = max_dist; 00239 return( TRUE ); 00240 } 00241 else 00242 return( FALSE ); 00243 } 00244 00245 public void initialize_deformation_parameters( 00246 deform_struct *deform ) 00247 { 00248 deform->deform_data.type = VOLUME_DATA; 00249 00250 initialize_deformation_model( &deform->deformation_model ); 00251 deform->deformation_model.position_constrained = FALSE; 00252 deform->fractional_step = 0.3; 00253 deform->max_step = 0.3; 00254 deform->stop_threshold = 0.0; 00255 deform->degrees_continuity = 0; 00256 deform->boundary_definition.min_isovalue = 90.0; 00257 deform->boundary_definition.max_isovalue = 90.0; 00258 deform->boundary_definition.gradient_threshold = 0.0; 00259 deform->boundary_definition.min_dot_product = -2.0; 00260 deform->boundary_definition.max_dot_product = 0.0; 00261 deform->boundary_definition.normal_direction = TOWARDS_LOWER; 00262 deform->max_iterations = 1000000; 00263 deform->stop_threshold = 0.0; 00264 00265 deform->n_movements_alloced = 0; 00266 deform->movement_threshold = 0.0; 00267 } 00268 00269 public void delete_deformation_parameters( 00270 deform_struct *deform ) 00271 { 00272 delete_deformation_model( &deform->deformation_model ); 00273 00274 if( deform->n_movements_alloced > 0 ) 00275 FREE( deform->prev_movements ); 00276 } 00277 00278 public void set_boundary_definition( 00279 boundary_definition_struct *boundary_def, 00280 Real min_value, 00281 Real max_value, 00282 Real grad_threshold, 00283 Real angle, 00284 char direction, 00285 Real tolerance ) 00286 { 00287 Real cosine; 00288 00289 boundary_def->min_isovalue = MIN( min_value, max_value ); 00290 boundary_def->max_isovalue = MAX( min_value, max_value ); 00291 boundary_def->gradient_threshold = grad_threshold; 00292 boundary_def->tolerance = tolerance; 00293 00294 if( angle == 90.0 ) 00295 cosine = 0.0; 00296 else 00297 cosine = cos( angle * DEG_TO_RAD ); 00298 00299 if( direction == '-' ) 00300 { 00301 boundary_def->normal_direction = TOWARDS_LOWER; 00302 boundary_def->min_dot_product = -2.0; 00303 boundary_def->max_dot_product = -cosine; 00304 } 00305 else if( direction == '+' ) 00306 { 00307 boundary_def->normal_direction = TOWARDS_HIGHER; 00308 boundary_def->min_dot_product = cosine; 00309 boundary_def->max_dot_product = 2.0; 00310 } 00311 else 00312 { 00313 boundary_def->normal_direction = ANY_DIRECTION; 00314 boundary_def->min_dot_product = -2.0; 00315 boundary_def->max_dot_product = 2.0; 00316 } 00317 } 00318 00319 public void initialize_lookup_volume_coeficients( 00320 voxel_coef_struct *lookup ) 00321 { 00322 lookup->n_in_hash = 0; 00323 } 00324 00325 public void lookup_volume_coeficients( 00326 voxel_coef_struct *lookup, 00327 Volume volume, 00328 int degrees_continuity, 00329 int x, 00330 int y, 00331 int z, 00332 Real c[] ) 00333 { 00334 int key, i, offset, n, sizes[N_DIMENSIONS]; 00335 voxel_lin_coef_struct *data; 00336 00337 offset = -(degrees_continuity + 1) / 2; 00338 n = degrees_continuity + 2; 00339 get_volume_sizes( volume, sizes ); 00340 00341 if( x + offset < 0 || x + offset + n >= sizes[X] || 00342 y + offset < 0 || y + offset + n >= sizes[Y] || 00343 z + offset < 0 || z + offset + n >= sizes[Z] ) 00344 { 00345 for_less( i, 0, n * n * n ) 00346 c[i] = 0.0; 00347 return; 00348 } 00349 00350 if( lookup == NULL || degrees_continuity != 0 ) 00351 { 00352 get_volume_value_hyperslab_3d( volume, x+offset, y+offset, z+offset, 00353 n, n, n, c ); 00354 return; 00355 } 00356 00357 if( lookup->n_in_hash == 0 ) 00358 { 00359 initialize_hash_table( &lookup->hash, MAX_IN_VOXEL_COEF_LOOKUP * 10, 00360 sizeof(voxel_lin_coef_struct *), 00361 0.5, 0.25 ); 00362 lookup->head = NULL; 00363 lookup->tail = NULL; 00364 } 00365 00366 key = IJK( x, y, z, sizes[Y], sizes[Z] ); 00367 00368 data = NULL; 00369 00370 if( !lookup_in_hash_table( &lookup->hash, key, (void *) &data ) ) 00371 { 00372 if( lookup->n_in_hash >= MAX_IN_VOXEL_COEF_LOOKUP ) 00373 { 00374 if( !remove_from_hash_table( &lookup->hash, lookup->tail->hash_key, 00375 (void *) &data)) 00376 handle_internal_error( "lookup_volume_coeficients" ); 00377 00378 lookup->tail = data->prev; 00379 if( lookup->tail == NULL ) 00380 lookup->head = NULL; 00381 else 00382 lookup->tail->next = NULL; 00383 } 00384 else 00385 { 00386 ALLOC( data, 1 ); 00387 ++lookup->n_in_hash; 00388 } 00389 00390 data->hash_key = key; 00391 get_volume_value_hyperslab_3d( volume, x, y, z, 2, 2, 2, data->coefs ); 00392 00393 data->next = lookup->head; 00394 data->prev = NULL; 00395 if( lookup->head != NULL ) 00396 lookup->head->prev = data; 00397 else 00398 lookup->tail = data; 00399 lookup->head = data; 00400 00401 insert_in_hash_table( &lookup->hash, key, (void *) &data ); 00402 } 00403 00404 for_less( i, 0, 8 ) 00405 c[i] = data->coefs[i]; 00406 } 00407 00408 public void delete_lookup_volume_coeficients( 00409 voxel_coef_struct *lookup ) 00410 { 00411 voxel_lin_coef_struct *ptr, *next; 00412 00413 ptr = lookup->head; 00414 while( ptr != NULL ) 00415 { 00416 next = ptr->next; 00417 FREE( ptr ); 00418 ptr = next; 00419 } 00420 00421 if( lookup->n_in_hash > 0 ) 00422 delete_hash_table( &lookup->hash ); 00423 }

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