contrib/mul/mfpf/mfpf_region_definer.h
Go to the documentation of this file.
00001 #ifndef mfpf_region_definer_h_
00002 #define mfpf_region_definer_h_
00003 //:
00004 // \file
00005 // \brief Base for objects which generate regions from sets of points
00006 // \author Tim Cootes
00007 
00008 #include <mfpf/mfpf_region_form.h>
00009 #include <vsl/vsl_binary_io.h>
00010 
00011 #include <vcl_string.h>
00012 #include <vcl_memory.h>
00013 #include <vcl_iosfwd.h>
00014 
00015 const unsigned mfpf_invalid_index=99999;
00016 
00017 //: Base for objects which generate regions from sets of points
00018 //  Given a set of points, derived classes can generate a region.
00019 //  Typically this is centred on one point or set of points, and
00020 //  is aligned with reference to some other points.
00021 //
00022 //  Two key functions are provided: set_up(pts1), which defines
00023 //  the region and its aspect ratio, and get_region(pts2), which
00024 //  returns a box of the same aspect ratio, with its pose defined
00025 //  by the points in pts2.  Two separate functions are required
00026 //  because all returned regions should have the same aspect ratio,
00027 //  since the boxes are to be used to initialise point_finders, which
00028 //  require a fixed aspect.
00029 class mfpf_region_definer
00030 {
00031  public:
00032 
00033   //: Dflt ctor
00034   mfpf_region_definer();
00035 
00036   //: Destructor
00037   virtual ~mfpf_region_definer();
00038 
00039   //: Returns true if the region is centred on an input point
00040   virtual bool is_centred_on_pt() const = 0;
00041 
00042   //: Returns index of reference point on which the region is centred
00043   virtual unsigned ref_point_index() const = 0;
00044 
00045   //: Returns original index of reference point on which the region is centred
00046   virtual unsigned orig_ref_point_index() const = 0;
00047 
00048   //: Returns reference point for region
00049   //  Returns the point that would be returned by
00050   //  set_up(pts).pose().p(), but without changing internal
00051   //  state.
00052   virtual vgl_point_2d<double> get_ref_point(
00053              const vcl_vector<vgl_point_2d<double> >& pts) const = 0;
00054 
00055   //: Uses some subset of pts to define a region
00056   //  The pose for the region will be a translation + rotation,
00057   //  ie region.pose().u() is a unit length
00058   virtual mfpf_region_form set_up(
00059              const vcl_vector<vgl_point_2d<double> >& pts) = 0;
00060 
00061   //: Uses some subset of pts to define a new region
00062   //  The aspect ratio of the region will be the same as that
00063   //  from the last call to set_up. Only region.pose() will be
00064   //  different.  Thus the returned region.pose() can be used
00065   //  to define the pose for training an mfpf_point_finder,
00066   //  for instance.
00067   virtual mfpf_region_form get_region(
00068               const vcl_vector<vgl_point_2d<double> >& pts) const = 0;
00069 
00070   //: Replace each point index i with new_index[i]
00071   //  Allows for re-numbering of the points used.
00072   //  new_index[i]==mfpf_invalid_index indicates an invalid index
00073   //  Returns true if successful.
00074   virtual bool replace_index(const vcl_vector<unsigned>& new_index)=0;
00075 
00076   //: Initialise from a stream
00077   virtual bool set_from_stream(vcl_istream &is);
00078 
00079   //: Version number for I/O
00080   short version_no() const;
00081 
00082   //: Name of the class
00083   virtual vcl_string is_a() const;
00084 
00085   //: Create a copy on the heap and return base class pointer
00086   virtual mfpf_region_definer* clone() const = 0;
00087 
00088   //: Print class to os
00089   virtual void print_summary(vcl_ostream& os) const =0;
00090 
00091   //: Save class to binary file stream
00092   virtual void b_write(vsl_b_ostream& bfs) const =0;
00093 
00094   //: Load class from binary file stream
00095   virtual void b_read(vsl_b_istream& bfs) =0;
00096 
00097   //: Create a concrete object, from a text specification.
00098   static vcl_auto_ptr<mfpf_region_definer> create_from_stream(vcl_istream &is);
00099 };
00100 
00101 //: Allows derived class to be loaded by base-class pointer
00102 void vsl_add_to_binary_loader(const mfpf_region_definer& b);
00103 
00104 //: Binary file stream output operator for class reference
00105 void vsl_b_write(vsl_b_ostream& bfs, const mfpf_region_definer& b);
00106 
00107 //: Binary file stream input operator for class reference
00108 void vsl_b_read(vsl_b_istream& bfs, mfpf_region_definer& b);
00109 
00110 //: Stream output operator for class reference
00111 vcl_ostream& operator<<(vcl_ostream& os,const mfpf_region_definer& b);
00112 
00113 //: Stream output operator for class pointer
00114 vcl_ostream& operator<<(vcl_ostream& os,const mfpf_region_definer* b);
00115 
00116 //: Generate a new set of points from \p pts0 using set of definers
00117 // \code
00118 //  new_pts[i] = definer[i]->get_ref_point(pts0)
00119 // \endcode
00120 void mfpf_points_from_definers(
00121               const vcl_vector<mfpf_region_definer*>& definer,
00122               const vcl_vector<vgl_point_2d<double> >& pts0,
00123               vcl_vector<vgl_point_2d<double> >& new_pts);
00124 
00125 //: Change indices in definers to refer to points generated
00126 //  Suppose definer is used to generate a set of n=definer.size()
00127 //  regions/pts (say pts1), by referring to some other set of m points.
00128 //  This sets up self_definer to generate an identical set of
00129 //  regions/pts by using the originally generated points (pts1).
00130 //  This can only be done if there is a region centred on each
00131 //  of the original points used in the definer.
00132 //  The function tests for this case, and returns false if it fails.
00133 //  In particular consider the following
00134 //  \code
00135 //  vcl_vector<vgl_point_2d<double> > pts0,pts1,pts2;
00136 //  // Set up pts0
00137 //  ...
00138 //  // Generate pts1 from pts0
00139 //  mfpf_points_from_definers(definer,pts0,pts1);
00140 //  mfpf_renumber_to_self(definer,pts0.size())
00141 //  // Now generate pts2 from pts1
00142 //  mfpf_points_from_definers(self_definer,pts1,pts2);
00143 //  // pts2 should be the same as pts1
00144 //  \endcode
00145 //  Note that objects pointed to by definer are changed.
00146 //  They may be left in an invalid state if this returns false,
00147 //  so caller should ensure a backup retained.
00148 bool mfpf_renumber_to_self(vcl_vector<mfpf_region_definer*>& definer,
00149                            unsigned n_pts0);
00150 
00151 #endif // mfpf_region_definer_h_