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 } else {
00258 ++itr;
00259 }
00260 }
00261 this->children.push_back( new_node );
00262 }
00263
00264
00265
00266
00267 vtol_intensity_face_sptr
00268 make_face( finder_type* find, data_image_type const* img ) const
00269 {
00270 vcl_vector< vtol_one_chain_sptr > face_chains;
00271 face_chains.push_back( region->make_one_chain() );
00272 for ( unsigned i = 0; i < children.size(); ++i ) {
00273 face_chains.push_back( children[i]->region->make_one_chain() );
00274 }
00275 if ( find ) {
00276 assert( img );
00277
00278 vcl_vector<unsigned> ri, rj;
00279 find->same_int_region( region->i, region->j, ri, rj );
00280 assert( ri.size() == rj.size() && !ri.empty() );
00281
00282 vcl_vector<float> x, y;
00283 vcl_vector<unsigned short> intensity;
00284 for ( unsigned c = 0; c < ri.size(); ++c ) {
00285 x.push_back( static_cast<float>(ri[c]) );
00286 y.push_back( static_cast<float>(rj[c]) );
00287 intensity.push_back( (*img)( ri[c], rj[c] ) );
00288 }
00289 vdgl_digital_region r( x.size(), &x[0], &y[0], &intensity[0] );
00290 return new vtol_intensity_face( &face_chains, r );
00291 } else {
00292
00293 vcl_clog << "Creating region with NO pixels" << vcl_endl;
00294 return new vtol_intensity_face( face_chains );
00295 }
00296 }
00297
00298
00299 void
00300 print( vcl_ostream& ostr, unsigned indent ) const
00301 {
00302 for ( unsigned i = 0; i < indent; ++i ) {
00303 ostr << ' ';
00304 }
00305 ostr << '['<<children.size()<<']';
00306 if ( ! children.empty() ) {
00307 ostr << "___\n";
00308 for ( unsigned i = 0; i < indent; ++i ) {
00309 ostr << ' ';
00310 }
00311 ostr << " \\\n";
00312 for ( unsigned i = 0; i < children.size(); ++i ) {
00313 children[i]->print( ostr, indent+7 );
00314 }
00315 } else {
00316 ostr << '\n';
00317 }
00318 }
00319 };
00320
00321
00322 public:
00323
00324
00325 vtol_extract_topology( label_image_type const& image,
00326 vtol_extract_topology_params const& params = vtol_extract_topology_params() );
00327
00328
00329
00330 vcl_vector< vtol_vertex_2d_sptr >
00331 vertices() const;
00332
00333
00334
00335
00336
00337
00338
00339 vcl_vector< vtol_intensity_face_sptr >
00340 faces() const;
00341
00342
00343
00344
00345
00346
00347 vcl_vector< vtol_intensity_face_sptr >
00348 faces( data_image_type const& data_img ) const;
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 void
00359 add_faces( vcl_vector<vtol_intensity_face_sptr>& faces,
00360 finder_type* find,
00361 data_image_type const* img,
00362 chain_tree_node* node,
00363 bool even_level = false ) const ;
00364
00365
00366
00367
00368
00369
00370
00371
00372 static
00373 bool
00374 contains( region_type_sptr a, region_type_sptr b );
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 static
00385 unsigned
00386 num_crosses_x_pos_ray( double x, double y, vdgl_edgel_chain const& chain );
00387
00388
00389
00390
00391 vdgl_edgel_chain_sptr
00392 smooth_chain( vdgl_edgel_chain_sptr chain,
00393 unsigned int num_pts ) const;
00394
00395 private:
00396
00397
00398
00399
00400 struct LabelPoint
00401 {
00402 LABEL_TYPE label;
00403 bool valid;
00404 LabelPoint(): label(0), valid(false) {}
00405 LabelPoint(LABEL_TYPE const& lt, bool v): label(lt), valid(v) {}
00406 bool operator==( LabelPoint const& lp ) {
00407 return (lp.valid == this->valid) && ( (lp.valid) ? lp.label == this->label : true );
00408 }
00409 bool operator!=( LabelPoint const& lp ) {
00410 return !(*this == lp);
00411 }
00412 };
00413
00414 typedef vtol_extract_topology_edgel_chain edgel_chain;
00415 typedef vbl_smart_ptr< edgel_chain > edgel_chain_sptr;
00416
00417
00418 typedef vil_image_view< unsigned > index_image_type;
00419
00420
00421 friend struct vtol_extract_topology_vertex_node;
00422
00423
00424
00425
00426 friend class test_vtol_extract_topology;
00427
00428
00429 void
00430 compute_label_range();
00431
00432
00433
00434
00435
00436
00437 LabelPoint
00438 label( unsigned i, unsigned j ) const;
00439
00440
00441 bool
00442 is_junction_vertex( unsigned i, unsigned j ) const;
00443
00444
00445 bool
00446 is_boundary_vertex( unsigned i, unsigned j ) const;
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468 bool
00469 is_edge( unsigned i, unsigned j, unsigned dir ) const;
00470
00471
00472
00473
00474
00475
00476 void
00477 edge_labels( unsigned i, unsigned j, unsigned dir,
00478 LabelPoint& left, LabelPoint& right ) const;
00479
00480
00481 unsigned
00482 vertex_index( unsigned i, unsigned j ) const;
00483
00484
00485 void
00486 set_vertex_index( unsigned i, unsigned j, unsigned index );
00487
00488
00489 vtol_extract_topology_vertex_node&
00490 node( unsigned index );
00491
00492
00493 vtol_extract_topology_vertex_node const&
00494 node( unsigned index ) const;
00495
00496
00497 void
00498 move( unsigned dir, unsigned& i, unsigned& j );
00499
00500
00501
00502
00503
00504 void
00505 set_mark( unsigned& marker, unsigned dir ) const;
00506
00507
00508
00509
00510
00511 bool
00512 is_marked( unsigned marker, unsigned dir ) const;
00513
00514
00515
00516
00517
00518
00519
00520 void
00521 trace_edge_chain( unsigned i, unsigned j, unsigned dir );
00522
00523
00524
00525
00526
00527
00528
00529 void
00530 construct_topology();
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545 bool
00546 trace_face_boundary( vcl_vector<unsigned>& markers,
00547 unsigned index,
00548 unsigned dir,
00549 region_type& chain,
00550 LabelPoint& region_label ) const;
00551
00552 typedef vcl_vector< vcl_vector< region_type_sptr > > region_collection;
00553
00554
00555
00556
00557
00558
00559
00560 void
00561 collect_regions( region_collection& out_region_list ) const;
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575 void
00576 compute_faces( vcl_vector< region_type_sptr > const& chains,
00577 vcl_vector< vtol_intensity_face_sptr >& faces,
00578 data_image_type const* data_img ) const;
00579
00580 private:
00581
00582
00583 label_image_type const& label_img_;
00584
00585
00586 vtol_extract_topology_params params_;
00587
00588
00589 LABEL_TYPE min_label_, max_label_;
00590
00591
00592 vcl_vector< vtol_extract_topology_vertex_node > node_list_;
00593
00594
00595 index_image_type index_img_;
00596 };
00597
00598 #endif // vtol_extract_topology_h_