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_