contrib/gel/gevd/gevd_contour.h
Go to the documentation of this file.
00001 #ifndef gevd_contour_h_
00002 #define gevd_contour_h_
00003 //:
00004 // \file
00005 // \brief tracing connected contours and junctions
00006 //
00007 // Operator to implement the tracing of connected contours and junctions.
00008 // All contours are assumed chains or cycles with zero width,
00009 // and so can be traced using 4/8-connected pixels.
00010 // Junctions will be detected from end points touching multiple
00011 // other end points, or touching a stronger contour with a significant
00012 // jump in filter response.
00013 // Extensively use the image grid to insure planarity of the network
00014 // of edges and vertices, when projected onto the image plane.
00015 // The recipe is:
00016 //
00017 //    1. Trace 4/8-connected pixels to enumerate disjoint chains
00018 //       and cycles. Prune contours that are either short or have
00019 //       no pixel stronger than a high hysteresis threshold.
00020 //
00021 //    2. Find junctions from end points touching internal
00022 //       pixels of some stronger chain/cycle. Break a stronger
00023 //       contour at a junction, only if there is a detectable
00024 //       jump in filter response.
00025 //       Next, merge end points touching other end points or junctions.
00026 //       Finally, create dummy end point for isolated cycles.
00027 //
00028 //    3. Insert subpixel accuracy into edges/vertices.
00029 //       Because of truncation errors, the mapping from edgel
00030 //       locations to integral grid locations may no longer be
00031 //       preserved, after this step.
00032 //
00033 //    4. Optionally reduce noisy zig-zags along the contours, and
00034 //       evenly space the contour points. The zig-zags are never
00035 //       more than 0.5 pixel, and happen when sub-pixel locations
00036 //       are noisy and so out-of-sync with the 4/8-connected tracing.
00037 //
00038 //    5. Optionally insert virtual border at the image boundary,
00039 //       to form closed region beyond the image boundary.
00040 //
00041 //    6. Insert depth/z values into edges/vertices, through
00042 //       interpolation of the range image, for example.
00043 //       For an intensity image, set this depth to a constant
00044 //       value, since the 3D edges/vertices all lie in the
00045 //       image plane.
00046 //
00047 // Input: connected edge elements, with response strength,
00048 //        and subpixel location, describing isolated contours
00049 //        disjoint only at junction pixels.
00050 //        min_strength and min_length are used to prune weak or
00051 //        short edges. min_jump is used to prune weak junctions.
00052 //
00053 // Output: planar network of linked edges and vertices.
00054 //
00055 // Complexity: O(|edgels|) time and space.
00056 //             O(nlogn) time for quicksort if n=|chains| < 1000,
00057 //             to make sure that junctions are found from
00058 //             longer/stronger chains first.
00059 //
00060 // \author
00061 //  John Canny      (1986) SM Thesis            \and
00062 //  Chris Connolly  (1987) Use Fu-Tsao thinning \and
00063 //  Van-Duc Nguyen  (1989) Eliminate short & weak contours \and
00064 //  Arron Heller    (1992) Translate from CLOS to C++ \and
00065 //  Van-Duc Nguyen  (1995) Trace/search breadth-first instead of thinning \and
00066 //  Joe Mundy       (1997) Added continuous edgel orientation output \and
00067 //  Van-Duc Nguyen  (1998) Merge from end points of dangling chains only \and
00068 //  Joe Mundy       (1999) Modified ::InsertBorder to use ROI bounds
00069 //  Peter Vanroose  (2003) removed z coord arg of Translate()
00070 //-----------------------------------------------------------------------------
00071 
00072 #include <vcl_vector.h>
00073 #include <vbl/vbl_array_2d.h>
00074 #include <vtol/vtol_vertex_2d_sptr.h>
00075 #include <vtol/vtol_edge_2d_sptr.h>
00076 #include <gevd/gevd_bufferxy.h>
00077 
00078 class gevd_contour
00079 {
00080  public:
00081   gevd_contour(float min_strength, int min_length, // hysteresis
00082                float min_jump,         // jump in strength at junctions
00083                float max_gap=2.236068f); // bridge small gaps (sqrt(5))
00084   ~gevd_contour();
00085 
00086   bool FindNetwork(gevd_bufferxy& edgels, // link pixels into network
00087                    const int njunction, // junctions detected previously
00088                    const int* junctionx, const int* junctiony,
00089                    vcl_vector<vtol_edge_2d_sptr>*& edges,
00090                    vcl_vector<vtol_vertex_2d_sptr >*& vertices);
00091   void SubPixelAccuracy(vcl_vector<vtol_edge_2d_sptr>& edges, // insert subpixel
00092                         vcl_vector<vtol_vertex_2d_sptr >& vertices, // accuracy
00093                         const gevd_bufferxy& locationx, // along normal to
00094                         const gevd_bufferxy& locationy); // contour only
00095   void InsertBorder(vcl_vector<vtol_edge_2d_sptr>& edges, // border location = 3
00096                     vcl_vector<vtol_vertex_2d_sptr >& vertices); // virtual chain/junction
00097 
00098   static void EqualizeSpacing(vcl_vector<vtol_edge_2d_sptr>& chains); // uniform spacing
00099   static void Translate(vcl_vector<vtol_edge_2d_sptr>& edges, // translate loc to center
00100                         vcl_vector<vtol_vertex_2d_sptr >& vertices, // instead of upper-left
00101                         const float tx=0.5, const float ty = 0.5);
00102   static void ClearNetwork(vcl_vector<vtol_edge_2d_sptr>*& edges, // remove network of edges
00103                            vcl_vector<vtol_vertex_2d_sptr >*& vertices); // and vertices
00104   int CheckInvariants(vcl_vector<vtol_edge_2d_sptr>& edges, // return number of errors
00105                       vcl_vector<vtol_vertex_2d_sptr >& vertices);
00106 
00107   static void MaskEdgels(const gevd_bufferxy& mask, // byte mask image
00108                          gevd_bufferxy& edgels, // edge elements AND with mask
00109                          int& njunction, // vertices AND with mask
00110                          int* junctionx, int* junctiony);
00111   static void SetEdgelData(gevd_bufferxy& grad_mag, gevd_bufferxy& angle,
00112                            vcl_vector<vtol_edge_2d_sptr>& edges);
00113 
00114 #if 0 // commented out
00115   static int ClosedRegions(vcl_vector<vtol_edge_2d*>& edges, // remove dangling/bridge
00116                            vcl_vector<vtol_vertex_2d*>& vertices); //  edges/vertices
00117   static void SetRayOrigin(const float x, const float y);
00118   static int ClockWiseOrder(vtol_edge_2d* const& dc1, vtol_edge_2d* const& dc2);
00119 #endif
00120 
00121   static int LengthCmp(vtol_edge_2d_sptr const& dc1, vtol_edge_2d_sptr const& dc2); // pixel length
00122   static vcl_vector<vtol_edge_2d_sptr>* CreateLookupTable(vcl_vector<vtol_edge_2d_sptr>&);
00123   static void LookupTableInsert(vcl_vector<vtol_edge_2d_sptr>& set, vtol_edge_2d_sptr elmt);
00124   static void LookupTableReplace(vcl_vector<vtol_edge_2d_sptr>& set,
00125                                  vtol_edge_2d_sptr deleted, vtol_edge_2d_sptr inserted);
00126   static void LookupTableRemove(vcl_vector<vtol_edge_2d_sptr>& set, vtol_edge_2d_sptr elmt);
00127   static void LookupTableCompress(vcl_vector<vtol_edge_2d_sptr>& set);
00128 
00129   static vcl_vector<vtol_vertex_2d_sptr >* CreateLookupTable(vcl_vector<vtol_vertex_2d_sptr >&);
00130   static void LookupTableInsert(vcl_vector<vtol_vertex_2d_sptr >& set, vtol_vertex_2d_sptr  elmt);
00131   static void LookupTableReplace(vcl_vector<vtol_vertex_2d_sptr >& set,
00132                                  vtol_vertex_2d_sptr  deleted, vtol_vertex_2d_sptr  inserted);
00133   static void LookupTableRemove(vcl_vector<vtol_vertex_2d_sptr >& set, vtol_vertex_2d_sptr  elmt);
00134   static void LookupTableCompress(vcl_vector<vtol_vertex_2d_sptr >& set);
00135 
00136   static void BeSilent() {talkative = false;}
00137   static void BeTalkative() {talkative = true;}
00138  protected:
00139   float minStrength;  // hysteresis or noise threshold
00140   int minLength;      // number of pixels in shortest chain
00141   float minJump;      // change in strength at junction
00142   int maxSpiral;      // number of spiral search for max_gap
00143   vbl_array_2d<vtol_edge_2d_sptr> *edgeMap;
00144   vbl_array_2d<vtol_vertex_2d_sptr> *vertexMap; // map pixel to junction/chain
00145 
00146  protected:
00147   int FindChains(gevd_bufferxy& edgels, // link pixels into chains
00148                  const int njunction, // junctions detected
00149                  const int* junctionx, const int* junctiony,
00150                  vcl_vector<vtol_edge_2d_sptr>& edges);
00151   int FindJunctions(gevd_bufferxy& edgels, // merge end/end and end/contour
00152                     vcl_vector<vtol_edge_2d_sptr>& edges, // replace these global lists
00153                     vcl_vector<vtol_vertex_2d_sptr >& vertices);
00154 
00155   static bool talkative; // output comentaries or not
00156 };
00157 
00158 #endif // gevd_contour_h_