00001 #ifndef vtol_extract_topology_h_
00002 #define vtol_extract_topology_h_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <vxl_config.h>
00016 #include <vcl_vector.h>
00017 #include <vcl_cassert.h>
00018 #include <vcl_iostream.h>
00019
00020 #include <vbl/vbl_ref_count.h>
00021
00022 #include <vil/vil_image_view.h>
00023 #include <vil/algo/vil_region_finder.h>
00024
00025 #include <vdgl/vdgl_edgel_chain_sptr.h>
00026 #include <vdgl/vdgl_digital_region.h>
00027
00028 #include <vtol/vtol_vertex_2d_sptr.h>
00029 #include <vtol/vtol_intensity_face.h>
00030 #include <vtol/vtol_intensity_face_sptr.h>
00031 #include <vtol/vtol_edge_2d_sptr.h>
00032 #include <vtol/vtol_one_chain_sptr.h>
00033
00034
00035
00036 class test_vtol_extract_topology;
00037
00038
00039
00040 typedef vxl_byte vtol_extract_topology_data_pixel_type;
00041 typedef vil_image_view< vtol_extract_topology_data_pixel_type >
00042 vtol_extract_topology_data_image_type;
00043
00044
00045 struct vtol_extract_topology_params
00046 {
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 unsigned num_for_smooth;
00057
00058 vtol_extract_topology_params&
00059 set_smooth( unsigned s ) { num_for_smooth = s; return *this; }
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 vtol_extract_topology_params() : num_for_smooth( 0 ) {}
00071 };
00072
00073
00074
00075
00076
00077
00078
00079 struct vtol_extract_topology_edgel_chain
00080 : public vbl_ref_count
00081 {
00082 vdgl_edgel_chain_sptr chain;
00083 vtol_edge_2d_sptr edge;
00084 };
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 class vtol_extract_topology_region_type
00096 : public vbl_ref_count
00097 {
00098 public:
00099 typedef vbl_smart_ptr< vtol_extract_topology_edgel_chain > edgel_chain_sptr;
00100
00101
00102 void
00103 push_back( edgel_chain_sptr chain );
00104
00105
00106 unsigned
00107 size() const;
00108
00109
00110 vdgl_edgel_chain_sptr const&
00111 operator[]( unsigned i ) const;
00112
00113
00114 vtol_one_chain_sptr
00115 make_one_chain() const;
00116
00117
00118 unsigned i, j;
00119
00120 private:
00121
00122
00123 vcl_vector< edgel_chain_sptr > list_;
00124 };
00125
00126
00127
00128
00129
00130
00131 struct vtol_extract_topology_vertex_node
00132 {
00133
00134 vtol_extract_topology_vertex_node( unsigned i, unsigned j );
00135
00136
00137 unsigned i, j;
00138
00139
00140 vtol_vertex_2d_sptr vertex;
00141
00142
00143 unsigned link[4];
00144
00145
00146
00147
00148
00149 unsigned back_dir[4];
00150
00151
00152 vbl_smart_ptr< vtol_extract_topology_edgel_chain > edgel_chain[4];
00153
00154
00155
00156
00157
00158
00159 static const unsigned null_index VCL_STATIC_CONST_INIT_INT_DECL( unsigned(-2) );
00160
00161
00162
00163
00164
00165
00166 static const unsigned done_index VCL_STATIC_CONST_INIT_INT_DECL( unsigned(-1) );
00167 };
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 template< typename LABEL_TYPE >
00188 class vtol_extract_topology
00189 {
00190 public:
00191
00192
00193 typedef vtol_extract_topology_region_type region_type;
00194 typedef vbl_smart_ptr< region_type > region_type_sptr;
00195
00196
00197 typedef vil_image_view< LABEL_TYPE > label_image_type;
00198 typedef vil_region_finder< LABEL_TYPE > finder_type;
00199
00200
00201 typedef vtol_extract_topology_data_image_type data_image_type;
00202
00203
00204
00205
00206
00207 struct chain_tree_node
00208 {
00209
00210
00211
00212
00213 region_type_sptr region;
00214
00215
00216
00217
00218 vcl_vector<chain_tree_node*> children;
00219
00220 chain_tree_node( region_type_sptr in_region ) : region( in_region ) {}
00221
00222 ~chain_tree_node() {
00223 typename vcl_vector<chain_tree_node*>::const_iterator itr;
00224 for (itr = children.begin(); itr != children.end(); ++itr ) {
00225 delete *itr;
00226 }
00227 }
00228
00229
00230
00231
00232 void
00233 add( region_type_sptr new_region )
00234 {
00235 typename vcl_vector<chain_tree_node*>::iterator itr;
00236
00237
00238
00239
00240 for ( itr = children.begin(); itr != children.end(); ++itr ) {
00241 if ( vtol_extract_topology<LABEL_TYPE>::contains( (*itr)->region, new_region ) ) {
00242 (*itr)->add( new_region );
00243 return;
00244 }
00245 }
00246
00247
00248
00249
00250
00251 chain_tree_node* new_node = new chain_tree_node( new_region );
00252 itr = children.begin();
00253 while ( itr != children.end() ) {
00254 if ( contains( new_region, (*itr)->region ) ) {
00255 new_node->children.push_back( *itr );
00256 itr = this->children.erase( itr );
00257 }
00258 else {
00259 ++itr;
00260 }
00261 }
00262 this->children.push_back( new_node );
00263 }
00264
00265
00266
00267
00268 vtol_intensity_face_sptr
00269 make_face( finder_type* find, data_image_type const* img ) const
00270 {
00271 vcl_vector< vtol_one_chain_sptr > face_chains;
00272 face_chains.push_back( region->make_one_chain() );
00273 for ( unsigned i = 0; i < children.size(); ++i ) {
00274 face_chains.push_back( children[i]->region->make_one_chain() );
00275 }
00276 if ( find ) {
00277 assert( img );
00278
00279 vcl_vector<unsigned> ri, rj;
00280 find->same_int_region( region->i, region->j, ri, rj );
00281 assert( ri.size() == rj.size() && !ri.empty() );
00282
00283 vcl_vector<float> x, y;
00284 vcl_vector<unsigned short> intensity;
00285 for ( unsigned c = 0; c < ri.size(); ++c ) {
00286 x.push_back( static_cast<float>(ri[c]) );
00287 y.push_back( static_cast<float>(rj[c]) );
00288 intensity.push_back( (*img)( ri[c], rj[c] ) );
00289 }
00290 vdgl_digital_region r( x.size(), &x[0], &y[0], &intensity[0] );
00291 return new vtol_intensity_face( &face_chains, r );
00292 }
00293 else {
00294
00295 vcl_clog << "Creating region with NO pixels" << vcl_endl;
00296 return new vtol_intensity_face( face_chains );
00297 }
00298 }
00299
00300
00301 void
00302 print( vcl_ostream& ostr, unsigned indent ) const
00303 {
00304 for ( unsigned i = 0; i < indent; ++i ) {
00305 ostr << ' ';
00306 }
00307 ostr << '['<<children.size()<<']';
00308 if ( ! children.empty() ) {
00309 ostr << "___\n";
00310 for ( unsigned i = 0; i < indent; ++i ) {
00311 ostr << ' ';
00312 }
00313 ostr << " \\\n";
00314 for ( unsigned i = 0; i < children.size(); ++i ) {
00315 children[i]->print( ostr, indent+7 );
00316 }
00317 }
00318 else {
00319 ostr << '\n';
00320 }
00321 }
00322 };
00323
00324
00325 public:
00326
00327
00328 vtol_extract_topology( label_image_type const& image,
00329 vtol_extract_topology_params const& params = vtol_extract_topology_params() );
00330
00331
00332
00333 vcl_vector< vtol_vertex_2d_sptr >
00334 vertices() const;
00335
00336
00337
00338
00339
00340
00341
00342 vcl_vector< vtol_intensity_face_sptr >
00343 faces() const;
00344
00345
00346
00347
00348
00349
00350 vcl_vector< vtol_intensity_face_sptr >
00351 faces( data_image_type const& data_img ) const;
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 void
00362 add_faces( vcl_vector<vtol_intensity_face_sptr>& faces,
00363 finder_type* find,
00364 data_image_type const* img,
00365 chain_tree_node* node,
00366 bool even_level = false ) const ;
00367
00368
00369
00370
00371
00372
00373
00374
00375 static
00376 bool
00377 contains( region_type_sptr a, region_type_sptr b );
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 static
00388 unsigned
00389 num_crosses_x_pos_ray( double x, double y, vdgl_edgel_chain const& chain );
00390
00391
00392
00393
00394 vdgl_edgel_chain_sptr
00395 smooth_chain( vdgl_edgel_chain_sptr chain,
00396 unsigned int num_pts ) const;
00397
00398 private:
00399
00400
00401
00402
00403 struct LabelPoint
00404 {
00405 LABEL_TYPE label;
00406 bool valid;
00407 LabelPoint(): label(0), valid(false) {}
00408 LabelPoint(LABEL_TYPE const& lt, bool v): label(lt), valid(v) {}
00409 bool operator==( LabelPoint const& lp ) {
00410 return (lp.valid == this->valid) && ( (lp.valid) ? lp.label == this->label : true );
00411 }
00412 bool operator!=( LabelPoint const& lp ) {
00413 return !(*this == lp);
00414 }
00415 };
00416
00417 typedef vtol_extract_topology_edgel_chain edgel_chain;
00418 typedef vbl_smart_ptr< edgel_chain > edgel_chain_sptr;
00419
00420
00421 typedef vil_image_view< unsigned > index_image_type;
00422
00423
00424 friend struct vtol_extract_topology_vertex_node;
00425
00426
00427
00428
00429 friend class test_vtol_extract_topology;
00430
00431
00432 void
00433 compute_label_range();
00434
00435
00436
00437
00438
00439
00440 LabelPoint
00441 label( unsigned i, unsigned j ) const;
00442
00443
00444 bool
00445 is_junction_vertex( unsigned i, unsigned j ) const;
00446
00447
00448 bool
00449 is_boundary_vertex( unsigned i, unsigned j ) const;
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471 bool
00472 is_edge( unsigned i, unsigned j, unsigned dir ) const;
00473
00474
00475
00476
00477
00478
00479 void
00480 edge_labels( unsigned i, unsigned j, unsigned dir,
00481 LabelPoint& left, LabelPoint& right ) const;
00482
00483
00484 unsigned
00485 vertex_index( unsigned i, unsigned j ) const;
00486
00487
00488 void
00489 set_vertex_index( unsigned i, unsigned j, unsigned index );
00490
00491
00492 vtol_extract_topology_vertex_node&
00493 node( unsigned index );
00494
00495
00496 vtol_extract_topology_vertex_node const&
00497 node( unsigned index ) const;
00498
00499
00500 void
00501 move( unsigned dir, unsigned& i, unsigned& j );
00502
00503
00504
00505
00506
00507 void
00508 set_mark( unsigned& marker, unsigned dir ) const;
00509
00510
00511
00512
00513
00514 bool
00515 is_marked( unsigned marker, unsigned dir ) const;
00516
00517
00518
00519
00520
00521
00522
00523 void
00524 trace_edge_chain( unsigned i, unsigned j, unsigned dir );
00525
00526
00527
00528
00529
00530
00531
00532 void
00533 construct_topology();
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548 bool
00549 trace_face_boundary( vcl_vector<unsigned>& markers,
00550 unsigned index,
00551 unsigned dir,
00552 region_type& chain,
00553 LabelPoint& region_label ) const;
00554
00555 typedef vcl_vector< vcl_vector< region_type_sptr > > region_collection;
00556
00557
00558
00559
00560
00561
00562
00563 void
00564 collect_regions( region_collection& out_region_list ) const;
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578 void
00579 compute_faces( vcl_vector< region_type_sptr > const& chains,
00580 vcl_vector< vtol_intensity_face_sptr >& faces,
00581 data_image_type const* data_img ) const;
00582
00583 private:
00584
00585
00586 label_image_type const& label_img_;
00587
00588
00589 vtol_extract_topology_params params_;
00590
00591
00592 LABEL_TYPE min_label_, max_label_;
00593
00594
00595 vcl_vector< vtol_extract_topology_vertex_node > node_list_;
00596
00597
00598 index_image_type index_img_;
00599 };
00600
00601 #endif // vtol_extract_topology_h_