00001 // This is mul/fhs/fhs_searcher.h 00002 #ifndef fhs_searcher_h_ 00003 #define fhs_searcher_h_ 00004 //: 00005 // \file 00006 // \author Tim Cootes 00007 // \brief Use F&H's DP style algorithm to search for global solutions 00008 00009 #include <fhs/fhs_arc.h> 00010 #include <vgl/vgl_fwd.h> // for point_2d<T> 00011 #include <vimt/vimt_image_2d_of.h> 00012 00013 //: Use F&H's DP style algorithm to search for global solutions to model match 00014 // Model consists of a set of features, together with a tree of neighbour 00015 // relationships of the form pos(j) = pos(i) + (N(mx,var_x),N(my,var_y)) 00016 // where N(m,var) is a gaussian with mean m and variance var. 00017 // 00018 // The aim is to find a set of points {p(i)} which minimise 00019 // sum_i F_i(p(i)) + sum_k shape_cost(arc(k)) 00020 // where k indexes the set of arcs defining neighbour relationships, 00021 // and shape_cost(arc) = dx*dx/arc.var_x + dy*dy.var_y (dx=p(arc_j).x()-p(arc_i).x()-arc.mx) 00022 // This is achieved using a combination of a quadratic distance function 00023 // applied to each feature response image F(i), and a dynamic programming 00024 // approach to combining the data. 00025 // 00026 // Algorithm based on papers by Felzenszwalb and Huttenlocher on 00027 // Pictoral Structure Matching. 00028 class fhs_searcher 00029 { 00030 private: 00031 //: Arcs defining neighbour relationships between features 00032 // Ordered so that parents precede children 00033 vcl_vector<fhs_arc> arc_; 00034 00035 //: Scaling applied to shape cost (default 1.0) 00036 double geom_wt_; 00037 00038 //: arc_to_j_[j] gives index of arc ending at given j 00039 vcl_vector<unsigned> arc_to_j_; 00040 00041 //: children_[i] gives list of child nodes of node i in tree 00042 vcl_vector<vcl_vector<unsigned> > children_; 00043 00044 //: Workspace for accumulated sum of responses 00045 vcl_vector<vimt_image_2d_of<float> > sum_im_; 00046 00047 //: Workspace for sum of responses, transformed by distance function 00048 vcl_vector<vimt_image_2d_of<float> > dist_im_; 00049 00050 //: pos_[i](x,y,0),pos_[i](x,y,1) is position of best response for (x,y) 00051 // Result is in image co-ordinates. 00052 vcl_vector<vimt_image_2d_of<int> > pos_im_; 00053 00054 //: Combine responses for image im_index, given supplied feature_response for that node 00055 void combine_responses(unsigned im_index, 00056 const vimt_image_2d_of<float>& feature_response); 00057 00058 public: 00059 //: Default constructor 00060 fhs_searcher(); 00061 00062 //: Set tree defining relationships between features 00063 // Input arcs define neighbour relationships in any order. 00064 // root_node defines which feature to be used as the root 00065 void set_tree(const vcl_vector<fhs_arc>& arcs, unsigned root_node); 00066 00067 //: Set scaling applied to shape cost (default 1.0) 00068 void set_geom_wt(double geom_wt); 00069 00070 00071 //: Index of root node (set by last call to set_tree() 00072 unsigned root_node() const; 00073 00074 //: Number of points represented 00075 unsigned n_points() const { return arc_.size()+1; } 00076 00077 //: Perform global search 00078 // Images of feature response supplied. The transformation 00079 // (world2im()) for each image can be used to indicate regions 00080 // which don't necessarily overlap. However, effective displacements 00081 // are assumed to be in pixel sized steps. 00082 // 00083 // After calling search(), results can be obtained using 00084 // points() and best_points() etc 00085 // \param geom_wt is the weighting applied to the geometric component of the cost. 00086 void search(const vcl_vector<vimt_image_2d_of<float> >& feature_response); 00087 00088 //: Compute optimal position of all points given position of root 00089 // Assumes search() has been called first 00090 void points_from_root(const vgl_point_2d<double>& root_pt, 00091 vcl_vector<vgl_point_2d<double> >& pts) const; 00092 00093 //: Compute optimal position of all points 00094 // Assumes search() has been called first 00095 // Returns cost at optimal position 00096 double best_points(vcl_vector<vgl_point_2d<double> >& pts) const; 00097 00098 //: Return final total cost image for root 00099 const vimt_image_2d_of<float>& root_cost_image() const; 00100 }; 00101 00102 #endif // fhs_searcher_h_