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_