00001 #ifndef mfpf_point_finder_h_ 00002 #define mfpf_point_finder_h_ 00003 //: 00004 // \file 00005 // \brief Base for classes which locate feature points 00006 // \author Tim Cootes 00007 00008 #include <vimt/vimt_image_2d_of.h> 00009 #include <vgl/vgl_point_2d.h> 00010 #include <vgl/vgl_vector_2d.h> 00011 00012 #include <mfpf/mfpf_pose.h> 00013 #include <vxl_config.h> // For vxl_byte 00014 00015 #include <vsl/vsl_binary_io.h> 00016 #include <vcl_string.h> 00017 #include <vcl_iosfwd.h> 00018 00019 class vimt_image_pyramid; 00020 00021 //: Base for classes which locate feature points 00022 // The object will be set up by an 00023 // associated mfpf_point_finder_builder object 00024 class mfpf_point_finder 00025 { 00026 protected: 00027 //: Size of step between sample points 00028 double step_size_; 00029 00030 //: Number of points either side of centre to search 00031 int search_ni_; 00032 00033 //: Number of points either side of centre to search 00034 int search_nj_; 00035 00036 //: Define N. angles (ie try at A+idA, i in [-nA,+nA]) 00037 unsigned nA_; 00038 00039 //: Angle step size (ie try at A+idA, i in [-nA,+nA]) 00040 double dA_; 00041 00042 //: Number of scales to try at 00043 unsigned ns_; 00044 00045 //: Scaling factor (ie try at ((ds)^i), i in [-ns,+ns] 00046 double ds_; 00047 00048 //: Return true if base class parameters are the same in pf 00049 bool base_equality(const mfpf_point_finder& pf) const; 00050 public: 00051 00052 //: Dflt ctor 00053 mfpf_point_finder(); 00054 00055 //: Destructor 00056 virtual ~mfpf_point_finder(); 00057 00058 //: Size of step between sample points 00059 virtual void set_step_size(double); 00060 00061 //: Size of step between sample points 00062 double step_size() const { return step_size_; } 00063 00064 //: Define search region size 00065 // During search, samples at points on grid [-ni,ni]x[-nj,nj], 00066 // with axes defined by u. 00067 virtual void set_search_area(unsigned ni, unsigned nj); 00068 00069 //: Define angle search parameters 00070 void set_angle_range(unsigned nA, double dA); 00071 00072 //: Define scale search parameters 00073 void set_scale_range(unsigned ns, double ds); 00074 00075 //: Number of points either side of centre to search along i 00076 int search_ni() const { return search_ni_; } 00077 00078 //: Number of points either side of centre to search along j 00079 int search_nj() const { return search_nj_; } 00080 00081 //: Set model to a new value when provided with a vector 00082 virtual bool set_model(const vcl_vector<double>& v); 00083 00084 //: Number of dimensions in the model 00085 virtual unsigned model_dim(); 00086 00087 //: Radius of circle containing modelled region (in model frame units) 00088 // Radius in world units given by step_size()*radius() 00089 virtual double radius() const = 0; 00090 00091 //: Get sample of region around specified point in image 00092 virtual void get_sample_vector(const vimt_image_2d_of<float>& image, 00093 const vgl_point_2d<double>& p, 00094 const vgl_vector_2d<double>& u, 00095 vcl_vector<double>& v); 00096 00097 //: Evaluate match at p, using u to define scale and orientation 00098 // Returns a quality of fit measure at the point (the smaller the better). 00099 virtual double evaluate(const vimt_image_2d_of<float>& image, 00100 const vgl_point_2d<double>& p, 00101 const vgl_vector_2d<double>& u)=0; 00102 00103 //: Evaluate match at in a region around p 00104 // Returns a quality of fit at a set of positions. 00105 // response image (whose size and transform is set inside the 00106 // function), indicates the points at which the function was 00107 // evaluated. response(i,j) is the fit at the point 00108 // response.world2im().inverse()(i,j). The world2im() transformation 00109 // may be affine. 00110 virtual void evaluate_region(const vimt_image_2d_of<float>& image, 00111 const vgl_point_2d<double>& p, 00112 const vgl_vector_2d<double>& u, 00113 vimt_image_2d_of<double>& response)=0; 00114 00115 //: Search given image around p, using u to define scale and angle 00116 // On exit, new_p defines position of the best nearby match. 00117 // Returns a quality of fit measure at that 00118 // point (the smaller the better). 00119 virtual double search_one_pose(const vimt_image_2d_of<float>& image, 00120 const vgl_point_2d<double>& p, 00121 const vgl_vector_2d<double>& u, 00122 vgl_point_2d<double>& new_p)=0; 00123 00124 //: Search given image around p, using u to define scale and angle 00125 // Evaluates responses on a grid, finds the best point on the 00126 // grid, then optimises its position by fitting a parabola. 00127 // 00128 // On exit, new_p defines position of the best nearby match. 00129 // Returns a quality of fit measure at that 00130 // point (the smaller the better). 00131 virtual double search_one_pose_with_opt( 00132 const vimt_image_2d_of<float>& image, 00133 const vgl_point_2d<double>& p, 00134 const vgl_vector_2d<double>& u, 00135 vgl_point_2d<double>& new_p); 00136 00137 //: Search given image around p, using u to define scale and orientation 00138 // On exit, new_p and new_u define position, scale and orientation of 00139 // the best nearby match. Returns a quality of fit measure at that 00140 // point (the smaller the better). 00141 // 00142 // Default implementation calls search_one_pose(...) at multiple 00143 // angles and scales. Result will be at a grid position 00144 // and one of the given angle/scales. True optima can then 00145 // be found by further optimisation of the point. 00146 virtual double search(const vimt_image_2d_of<float>& image, 00147 const vgl_point_2d<double>& p, 00148 const vgl_vector_2d<double>& u, 00149 vgl_point_2d<double>& new_p, 00150 vgl_vector_2d<double>& new_u); 00151 00152 //: Search given image around p, using u to define scale and orientation 00153 // On exit, new_p and new_u define position, scale and orientation of 00154 // the best nearby match. Returns a quality of fit measure at that 00155 // point (the smaller the better). 00156 // Parabolic fit used to estimate optimal position. 00157 // 00158 // Default implementation calls search_one_pose(...) at multiple 00159 // angles and scales. Result will be at a grid position 00160 // and one of the given angle/scales. True optima can then 00161 // be found by further optimisation of the point. 00162 virtual double search_with_opt( 00163 const vimt_image_2d_of<float>& image, 00164 const vgl_point_2d<double>& p, 00165 const vgl_vector_2d<double>& u, 00166 vgl_point_2d<double>& new_p, 00167 vgl_vector_2d<double>& new_u); 00168 00169 //: Search for local optima around given point/scale/angle 00170 // Search in a grid around p (defined by search_ni and search_nj). 00171 // Find local minima on this grid and return append each to 00172 // pts. Note: pts is not resized, so empty beforehand if necessary. 00173 virtual void grid_search_one_pose(const vimt_image_2d_of<float>& image, 00174 const vgl_point_2d<double>& p, 00175 const vgl_vector_2d<double>& u, 00176 vcl_vector<mfpf_pose>& pts, 00177 vcl_vector<double>& fit); 00178 00179 //: Search for local optima around given point/scale/angle 00180 // Search in a grid around p (defined by search_ni and search_nj). 00181 // Find local minima on this grid. 00182 // Perform single sub-grid optimisation by fitting a parabola 00183 // in x and y and testing resulting point. 00184 // Append each to pts. 00185 // Note: pts is not resized, so empty beforehand if necessary. 00186 virtual void multi_search_one_pose( 00187 const vimt_image_2d_of<float>& image, 00188 const vgl_point_2d<double>& p, 00189 const vgl_vector_2d<double>& u, 00190 vcl_vector<mfpf_pose>& pts, 00191 vcl_vector<double>& fit); 00192 00193 //: Search for local optima around given point/scale/angle 00194 // For each angle and scale (defined by internal nA,dA,ns,ds) 00195 // search in a grid around p (defined by search_ni and search_nj). 00196 // Find local minima on this grid and return them in poses. 00197 // Responses lie on grid in (x,y,ds,dA) 00198 // 00199 // Note that an object in an image may lead to multiple responses, 00200 // one at each scale and angle near to the optima. Thus the 00201 // poses defined in pts should be further refined to eliminate 00202 // such multiple responses. 00203 virtual void grid_search(const vimt_image_2d_of<float>& image, 00204 const vgl_point_2d<double>& p, 00205 const vgl_vector_2d<double>& u, 00206 vcl_vector<mfpf_pose>& poses, 00207 vcl_vector<double>& fit); 00208 00209 //: Search for local optima around given point/scale/angle 00210 // For each angle and scale (defined by internal nA,dA,ns,ds) 00211 // search in a grid around p (defined by search_ni and search_nj). 00212 // Find local minima on this grid. 00213 // Sub-grid estimation using parabolic fitting included. 00214 // poses[i] defines result i, with corresponding fit fits[i] 00215 // 00216 // Note that an object in an image may lead to multiple responses, 00217 // one at each scale and angle near to the optima. Thus the 00218 // poses defined in pts should be further refined to eliminate 00219 // such multiple responses. 00220 virtual void multi_search(const vimt_image_2d_of<float>& image, 00221 const vgl_point_2d<double>& p, 00222 const vgl_vector_2d<double>& u, 00223 vcl_vector<mfpf_pose>& poses, 00224 vcl_vector<double>& fits); 00225 00226 //: Perform local optimisation to refine position,scale and angle 00227 // On input fit is match at p,u. On exit p,u and fit are updated. 00228 // Baseclass implementation uses simplex optimisation. 00229 virtual void refine_match(const vimt_image_2d_of<float>& image, 00230 vgl_point_2d<double>& p, 00231 vgl_vector_2d<double>& u, 00232 double& fit); 00233 00234 //: Return true if modelled regions at pose1 and pose2 overlap 00235 virtual bool overlap(const mfpf_pose& pose1, 00236 const mfpf_pose& pose2) const; 00237 00238 //: Generate points in ref frame that represent boundary 00239 // Points of a contour around the shape. 00240 // Used for display purposes. Join the points with an open 00241 // contour to get a representation. 00242 virtual void get_outline(vcl_vector<vgl_point_2d<double> >& pts) const=0; 00243 00244 //: Computes the aligned bounding box for feature with given pose 00245 // On exit box_pose.p() gives the centre, corners are given by 00246 // box_pose(+/-0.5*wi, +/-0.5*wj). 00247 virtual void aligned_bounding_box(const mfpf_pose& pose, 00248 mfpf_pose& box_pose, 00249 double& wi, double& wj) const; 00250 00251 //: Create an image summarising the average model (where possible) 00252 // For instance, creates an image of the mean template used for 00253 // search. image.world2im() gives mapping from reference frame 00254 // into raw image co-ords (including the step size). 00255 // Default implementation does nothing - returns an empty image. 00256 virtual void get_image_of_model(vimt_image_2d_of<vxl_byte>& image) const; 00257 00258 //: Select best level for searching around pose 00259 // Selects pyramid level with pixel sizes best matching 00260 // the model pixel size at given pose. 00261 unsigned image_level(const mfpf_pose& pose, 00262 const vimt_image_pyramid& im_pyr) const; 00263 00264 //: Version number for I/O 00265 short version_no() const; 00266 00267 //: Name of the class 00268 virtual vcl_string is_a() const; 00269 00270 //: Create a copy on the heap and return base class pointer 00271 virtual mfpf_point_finder* clone() const = 0; 00272 00273 //: Print class to os 00274 virtual void print_summary(vcl_ostream& os) const; 00275 00276 //: Save class to binary file stream 00277 virtual void b_write(vsl_b_ostream& bfs) const; 00278 00279 //: Load class from binary file stream 00280 virtual void b_read(vsl_b_istream& bfs); 00281 }; 00282 00283 //: Allows derived class to be loaded by base-class pointer 00284 void vsl_add_to_binary_loader(const mfpf_point_finder& b); 00285 00286 //: Binary file stream output operator for class reference 00287 void vsl_b_write(vsl_b_ostream& bfs, const mfpf_point_finder& b); 00288 00289 //: Binary file stream input operator for class reference 00290 void vsl_b_read(vsl_b_istream& bfs, mfpf_point_finder& b); 00291 00292 //: Stream output operator for class reference 00293 vcl_ostream& operator<<(vcl_ostream& os,const mfpf_point_finder& b); 00294 00295 //: Stream output operator for class pointer 00296 vcl_ostream& operator<<(vcl_ostream& os,const mfpf_point_finder* b); 00297 00298 #endif // mfpf_point_finder_h_