contrib/mul/fhs/fhs_searcher.h
Go to the documentation of this file.
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_