contrib/rpl/rgrl/rgrl_invariant_single_landmark.h
Go to the documentation of this file.
00001 #ifndef rgrl_invariant_single_landmark_h_
00002 #define rgrl_invariant_single_landmark_h_
00003 //:
00004 // \file
00005 // \brief  Represent a 2D bifurcation landmark associated with a set of invariant properties.
00006 // \author Charlene Tsai
00007 // \date   March 2004
00008 
00009 #include <vcl_vector.h>
00010 #include <vnl/vnl_double_2.h>
00011 
00012 #include "rgrl_transformation_sptr.h"
00013 #include "rgrl_scale_sptr.h"
00014 #include "rgrl_invariant_sptr.h"
00015 #include "rgrl_mask.h"
00016 #include "rgrl_invariant.h"
00017 
00018 //: Represent a 2D bifurcation landmark associated with a set of invariant properties.
00019 //
00020 //  This is the simplified implementation of the single-landmark feature
00021 //  with invariant properties in "The Dual-Bootstrap Iterative
00022 //  Closest Point Algorithm with Application to Retinal Image
00023 //  Registration" by Stewart et al., TMI 2003, vol 22, no 11.
00024 //
00025 //  This invariant class is to serve as an example of feature with
00026 //  invariants for initialization using invariant indexing. The
00027 //  properties of a landmark includes the center location, 3 direction
00028 //  vectors of the vessels that come to meet, 3 associated widths. The
00029 //  radius of the circular region that the landmark occupies is taken
00030 //  as the maximum of the 3 widths.
00031 //
00032 //  The transformation model is similarity
00033 //  (translation+scaling+rotation), estimated using the landmark center
00034 //  location and 6 boundary points.
00035 //
00036 class rgrl_invariant_single_landmark
00037   : public rgrl_invariant
00038 {
00039  public:
00040   //: Constructor, both angular_variance and width_ratio_variance are in radius
00041   rgrl_invariant_single_landmark(vnl_vector<double> location,
00042                                  vnl_vector<double> vessel_dir1,
00043                                  vnl_vector<double> vessel_dir2,
00044                                  vnl_vector<double> vessel_dir3,
00045                                  double width1, double width2, double width3,
00046                                  double angular_std = 1,
00047                                  double width_ratio_std = 1);
00048 
00049   //: Construct the constellation from another by shifting indices counterclockwise
00050   //
00051   //  \note Used if there is ambiguity in the ordering of the vessel
00052   //  directions. Both angular_variance and width_ratio_variance are
00053   //  in radius
00054   rgrl_invariant_single_landmark(const rgrl_invariant_single_landmark& copy,
00055                                  double angular_std = 1,
00056                                  double width_ratio_std = 1);
00057 
00058   //: Return the location
00059   const vnl_double_2& location() const;
00060 
00061   //: Returns the i-th boundary point location
00062   const vnl_double_2& boundary_point_location(int i) const;
00063 
00064   //: Returns the i-th boundary point normal direction
00065   const vnl_double_2& boundary_point_normal(int i) const;
00066 
00067   //: Estimate the xform mapping \a from to the current feature
00068   bool estimate(rgrl_invariant_sptr         from,
00069                 rgrl_transformation_sptr&   xform,
00070                 rgrl_scale_sptr&            scale );
00071 
00072   //: Returns the vector of invariants normalized by scale
00073   const vnl_vector<double>& cartesian_invariants() const;
00074 
00075   //: Returns the vector of invariants normalized by scale
00076   const vnl_vector<double>& angular_invariants() const;
00077 
00078   //: Computes the valid match region for the constellation
00079   rgrl_mask_box region() const;
00080 
00081   //: Return true if the feature has an initial ROI
00082   bool has_region() const {return true;}
00083 
00084   //: Returns the center of the points in the computation of the parameters
00085   //
00086   // The center is the average location of all landmarks and boundary
00087   // points. This is not necessarily the center of the bounding_box
00088   const vnl_double_2& center();
00089 
00090   //: Constellation ambiguity check
00091   //
00092   // \note constellations are ambiguous if one or more landmarks has a
00093   // signature angle near 0 degrees, since angles near 0 could
00094   // actually be near 360. The reverse is not flagged or corrected
00095   // since this would lead to redundancy.
00096   bool is_ambiguous() const {return is_ambiguous_;}
00097 
00098   // Defines type-related functions
00099   rgrl_type_macro( rgrl_invariant_single_landmark, rgrl_invariant );
00100 
00101  private:
00102   //: A helper function to compute the counterclockwise angles between two orientation vectors
00103   // \return angles in the range of [0,2*PI)
00104   double ccw_angle_between(vnl_double_2 from, vnl_double_2 to);
00105 
00106   //: A helper function to reorder selected indices of a landmark
00107   //
00108   //  \note The indices are passed in by reference.  The indices
00109   //  specified are reordered counterclockwise from the basis
00110   //  direction specified. The counterclockwise angles from the basis
00111   //  are also returned by reference.
00112   void reorder_vessel( vcl_vector<vnl_vector<double> >& directions,
00113                        vcl_vector<double>& local_widths,
00114                        vcl_vector<double>& angles);
00115 
00116  private:
00117   vnl_double_2 location_;
00118   vcl_vector<double> local_widths_;
00119   vcl_vector<vnl_double_2> boundary_points_;
00120   vcl_vector<vnl_double_2> trace_normals_;
00121   vnl_vector<double> cartesian_invariants_;
00122   vnl_vector<double> angular_invariants_;
00123   vnl_double_2 center_;
00124 
00125   double radius_;
00126   bool is_ambiguous_;
00127   bool center_set_;
00128   bool is_estimate_set_;
00129 };
00130 
00131 #endif // rgrl_invariant_single_landmark_h_