1 // This is gel/gevd/gevd_edgel_regions.h
2 #ifndef gevd_edgel_regions_h_
3 #define gevd_edgel_regions_h_
4 //:
5 // \file
6 // \brief generation of regions bounded by gevd_edgel chains
7 // \verbatim
8 //     Inputs:  Image, EdgelGroup
9 //     Output: CoolListP<IntensityFace*>
10 // \endverbatim
11 //  The idea is to generate regions by inserting boundaries into an
12 //  array.  The boundaries are defined by a set of edgel chains and
13 //  a boundary location is inserted at each edgel.  The array is
14 //  assumed to have a boundary at the perimeter of the ROI.
15 //
16 //  The array is scanned with a 2x2 neighborhood to form connected
17 //  components in the usual way. Each of the connected component labels are
18 //  reduced to the lowest equivalent label id by a transitive closure
19 //  on the equivalence table.
20 //
21 // A second scan of the label array is made to determine adjacency to
22 //  a given edge.  This process is enabled by a companion class,
23 //  the gevd_region_edge which has storage for two labels, corresponding to
24 //  each side of the edge.
25 //
26 //  The region edges are then used to collect the input edges which are
27 //  adjacent to a given region.  The set of edges adjacent to a region
28 //  are used to construct a multiply-connected sub-class of Face, the
29 //  IntensityFace.  The IntensityFace maintains a scatter matrix of
30 //  a planar fit to the intensity distribution over the corresponding
31 //  region.
32 //
33 // \author Author J. L. Mundy - January 14, 1999
34 // \verbatim
35 // Modifications
36 //  25 April 2000 - collinsr@cs.rpi.edu - switched region_edges_
37 //                  to key on the Id() rather than the pointer value
38 //                  to avoid different hash tables (and different
39 //                  segmentations) for identical inputs (leaving the
40 //                  question of why the hash table order matters for
41 //                  another day)
42 // 24 April 2002 - Peter Vanroose - replaced GetLeftLabel and GetRightLabel
43 //                  by GetLabel, in accordance with gevd_region_edge change
44 // \endverbatim
45 //
46 //-----------------------------------------------------------------------------
47 #include <vector>
48 #include <iostream>
49 #include <map>
50 #ifdef _MSC_VER
51 #  include <vcl_msvc_warnings.h>
52 #endif
53 
54 #include <vtol/vtol_vertex_sptr.h>
55 #include <vtol/vtol_edge_2d_sptr.h>
56 #include <gevd/gevd_region_edge.h>
57 #include <gevd/gevd_bufferxy.h>
58 #include <vtol/vtol_intensity_face_sptr.h>
59 #include <vil1/vil1_image.h>
60 
61 
62 class gevd_edgel_regions
63 {
64  public:
65   enum RegionLabel {UNLABELED=0, EDGE, LABEL};
66   //Constructors/Destructors
67   gevd_edgel_regions(bool debug = false);
68   ~gevd_edgel_regions();
69   //Main process method
70   bool compute_edgel_regions(vil1_image* image,
71                              std::vector<vtol_edge_2d_sptr>& sgrp,
72                              std::vector<vtol_intensity_face_sptr>& faces);
73 
74   bool compute_edgel_regions(gevd_bufferxy* buf,
75                              std::vector<vtol_edge_2d_sptr>& sgrp,
76                              std::vector<vtol_intensity_face_sptr>& faces);
77   //Acessors
SetVerbose()78   void SetVerbose() {verbose_ = true;}
ClearVerbose()79   void ClearVerbose() {verbose_ = false;}
SetDebug()80   void SetDebug() {debug_ = true;}
ClearDebug()81   void ClearDebug() {debug_ = false;}
set_magnification(float magnification)82   void set_magnification(float magnification){magnification_=magnification;}
83   unsigned int BaseLabel(unsigned int label);
GetMaxRegionLabel()84   unsigned int GetMaxRegionLabel() const {return max_region_label_;}
SetMaxRegionLabel(unsigned int label)85   void SetMaxRegionLabel(unsigned int label){max_region_label_ = label;}
GetRegionArray()86   unsigned int** GetRegionArray(){return region_label_array_;}
GetXSize()87   int GetXSize() const {return xend_ - xo_ + 1;}
GetYSize()88   int GetYSize() const {return yend_ - yo_ + 1;}
89   vil1_image* GetEdgeImage(std::vector<vtol_edge_2d_sptr>& edgels);
90 #if 0
91   topo_debug_data_ref get_topo_debug_data() {return debug_data_;}
92 #endif
93   // Utilities (especially for testing)
94   bool InsertRegionEquivalence(unsigned int label_b, unsigned int label_a);
95   void GrowEquivalenceClasses();
96   void PropagateEquivalence();
97   unsigned int GetLabel(const vtol_edge_2d_sptr& e, unsigned int nr);
98   // Debug print methods
99   void print_region_array();
100   void print_region_equivalence();
101   void print_reverse_region_equivalence();
102   void print_base_equivalence();
103   void print_intensity_data();
104  protected:
105   // Utilities
106   bool GroupContainsEdges(std::vector<vtol_edge_2d_sptr>& sg);
107   bool InitRegionArray(std::vector<vtol_edge_2d_sptr>& sg);
108   unsigned char label_code(unsigned int label) const;
109   bool add_to_forward(unsigned int key, unsigned int value);
110   bool add_to_reverse(unsigned int key, unsigned int value);
111   unsigned char EncodeNeighborhood(unsigned int ul, unsigned int ur,
112                                    unsigned int ll, unsigned int lr);
113   void UpdateConnectedNeighborhood(unsigned int x, unsigned int y);
114   void AssignEdgeLabels(unsigned int x, unsigned int y);
115   void ApplyRegionEquivalence();
116   bool out_of_bounds(unsigned int x, unsigned int y) const;
117   void insert_adjacency(unsigned int region, const vtol_edge_2d_sptr& e);
118   void CollectEdges();
119   void CollectFaceEdges();
120   void ConstructFaces();
121   void AccumulateMeans();
122   void AccumulateRegionData();
123   void InsertFaceData();
124   unsigned int X(unsigned int x) const;
125   unsigned int Y(unsigned int y) const;
126   unsigned int Xf(float x);
127   unsigned int Yf(float y);
128   bool insert_edgel(float pre_x, float pre_y, float x, float y,
129                     gevd_region_edge* e);
130   void insert_equivalence(unsigned int ll, unsigned int ur, unsigned int& lr);
131   bool merge_equivalence(std::map<unsigned int, std::vector<unsigned int>* >& tab,
132                          unsigned int cur_label,
133                          unsigned int label);
134   bool get_next_label(std::vector<unsigned int>* labels,
135                       unsigned int& label) const;
136   void print_edge_colis(unsigned int x, unsigned int y,
137                         gevd_region_edge* r1, gevd_region_edge* r2) const;
138   bool corrupt_boundary(std::vector<vtol_edge_2d_sptr>& edges,
139                         std::vector<vtol_vertex_sptr>& bad_verts) const;
140   bool remove_hairs(std::vector<vtol_edge_2d_sptr>& edges);
141   bool connect_ends(std::vector<vtol_edge_2d_sptr>& edges,
142                     std::vector<vtol_vertex_sptr>& bad_verts);
143   void repair_failed_insertions(std::vector<vtol_edge_2d_sptr>& edges,
144                                 std::vector<vtol_vertex_sptr>& bad_verts);
145   void get_buffer_row(unsigned int row);
146   void get_image_row(unsigned int row);
147   unsigned short get_intensity(unsigned int x);
148   int bytes_per_pix();
149 
150   //to be used after image or buf are set
151   bool compute_edgel_regions(std::vector<vtol_edge_2d_sptr>& sgrp,
152                              std::vector<vtol_intensity_face_sptr>& faces);
153   //members
154   bool verbose_;
155   bool debug_;
156   bool image_source_;
157   bool buf_source_;
158   float magnification_;
159   vil1_image* image_;
160   gevd_bufferxy* buf_;
161   gevd_region_edge*** edge_boundary_array_;
162   unsigned int** region_label_array_;
163   unsigned int min_region_label_;
164   unsigned int max_region_label_;
165   float Xob_;//buffer X origin in original image
166   float Yob_;//buffer Y origin in original image
167   unsigned int xo_;                    //X coor of starting x pixel
168   unsigned int yo_;                    //Y coor of starting y pixel
169   unsigned int xend_;                  //X coor of ending x pixel
170   unsigned int yend_;                  //Y coor of ending y pixel
171   //Region label equivalency hash tables
172   std::map<unsigned int, std::vector<unsigned int>* > region_pairs_forward_;
173   std::map<unsigned int, std::vector<unsigned int>* > region_pairs_reverse_;
174   std::map<unsigned int, std::vector<unsigned int>* > equivalence_set_;
175   std::map<unsigned int, unsigned int > label_map_;
176   //hash table for Edge<->gevd_region_edge relationship
177   std::map<int, gevd_region_edge*> region_edges_;
178   std::map<unsigned int, std::vector<vtol_edge_2d_sptr>* > region_edge_adjacency_;
179   //Final output vtol_intensity_face(s) and relation to corresponding region label
180   std::vector<vtol_intensity_face_sptr>* faces_;
181   vtol_intensity_face_sptr* intensity_face_index_;
182   std::vector<vtol_edge_2d_sptr>** face_edge_index_;
183   std::vector<vtol_edge_2d_sptr>* failed_insertions_; //Short edges that fail
184 #if 0
185   topo_debug_data_ref debug_data_;
186 #endif
187   unsigned char* ubuf_;
188   unsigned short* sbuf_;
189 };
190 
191 #endif // gevd_edgel_regions_h_
192