contrib/mul/mfpf/mfpf_max_finder.cxx
Go to the documentation of this file.
00001 #include "mfpf_max_finder.h"
00002 //:
00003 // \file
00004 // \brief Locates largest value along a profile
00005 // \author Tim Cootes
00006 
00007 #include <vsl/vsl_binary_loader.h>
00008 #include <vnl/vnl_vector.h>
00009 #include <vgl/vgl_point_2d.h>
00010 #include <vgl/vgl_vector_2d.h>
00011 
00012 #include <vimt/vimt_bilin_interp.h>
00013 #include <vimt/vimt_sample_profile_bilin.h>
00014 
00015 //=======================================================================
00016 // Dflt ctor
00017 //=======================================================================
00018 
00019 mfpf_max_finder::mfpf_max_finder()
00020 {
00021 }
00022 
00023 //=======================================================================
00024 // Destructor
00025 //=======================================================================
00026 
00027 mfpf_max_finder::~mfpf_max_finder()
00028 {
00029 }
00030 
00031 //: Radius of circle containing modelled region
00032 double mfpf_max_finder::radius() const
00033 {
00034   return 1.0;
00035 }
00036 
00037 //: Generate points in ref frame that represent boundary
00038 //  Points of a closed contour around the shape.
00039 //  Used for display purposes.
00040 void mfpf_max_finder::get_outline(vcl_vector<vgl_point_2d<double> >& pts) const
00041 {
00042   pts.resize(2);
00043   pts[0]=vgl_point_2d<double>(-0.5,0);
00044   pts[1]=vgl_point_2d<double>( 0.5,0);
00045 }
00046 
00047 
00048 //: Evaluate match at p, using u to define scale and orientation
00049 // Returns -1*edge strength at p along direction u
00050 double mfpf_max_finder::evaluate(const vimt_image_2d_of<float>& image,
00051                                  const vgl_point_2d<double>& p,
00052                                  const vgl_vector_2d<double>& u)
00053 {
00054   double v2 = vimt_bilin_interp_safe(image,p);
00055   return -1.0*v2;
00056 }
00057 
00058 //: Evaluate match at in a region around p
00059 // Returns a quality of fit at a set of positions.
00060 // response image (whose size and transform is set inside the
00061 // function), indicates the points at which the function was
00062 // evaluated.  response(i,j) is the fit at the point
00063 // response.world2im().inverse()(i,j).  The world2im() transformation
00064 // may be affine.
00065 void mfpf_max_finder::evaluate_region(
00066                         const vimt_image_2d_of<float>& image,
00067                         const vgl_point_2d<double>& p,
00068                         const vgl_vector_2d<double>& u,
00069                         vimt_image_2d_of<double>& response)
00070 {
00071   int n=1+2*search_ni_;
00072   vnl_vector<double> v(n);
00073   vgl_vector_2d<double> u1=step_size_*u;
00074   const vgl_point_2d<double> p0 = p-search_ni_*u1;
00075   vimt_sample_profile_bilin(v,image,p0,u1,n);
00076   response.image().set_size(n,1);
00077   double* r = response.image().top_left_ptr();
00078   for (int i=0;i<n;++i,++r)
00079   {
00080     *r = -1*v[i];
00081   }
00082 
00083   // Set up transformation parameters
00084 
00085   // Point (i,j) in dest corresponds to p1+i.u+j.v,
00086   // an affine transformation for image to world
00087   const vgl_point_2d<double> p1 = p-search_ni_*u1;
00088 
00089   vimt_transform_2d i2w;
00090   i2w.set_similarity(vgl_point_2d<double>(u1.x(),u1.y()),p1);
00091   response.set_world2im(i2w.inverse());
00092 }
00093 
00094 //: Search given image around p, using u to define scale and orientation
00095 //  On exit, new_p and new_u define position, scale and orientation of
00096 //  the best nearby match.  Returns a quality of fit measure at that
00097 //  point (the smaller the better).
00098 double mfpf_max_finder::search_one_pose(
00099                                 const vimt_image_2d_of<float>& image,
00100                                 const vgl_point_2d<double>& p,
00101                                 const vgl_vector_2d<double>& u,
00102                                 vgl_point_2d<double>& new_p)
00103 {
00104   int n=1+2*search_ni_;
00105   vnl_vector<double> v(n);
00106   vgl_vector_2d<double> u1=step_size_*u;
00107   const vgl_point_2d<double> p0 = p-search_ni_*u1;
00108   vimt_sample_profile_bilin(v,image,p0,u1,n);
00109   int best_i=0;
00110   double best_e = v[0];
00111   for (int i=1;i<n;++i)
00112   {
00113     double e = v[i];
00114     if (e>best_e) { best_e=e; best_i=i; }
00115   }
00116   new_p = p+(best_i-search_ni_)*u1;
00117   return -1.0 * best_e;
00118 }
00119 
00120 //=======================================================================
00121 // Method: is_a
00122 //=======================================================================
00123 
00124 vcl_string mfpf_max_finder::is_a() const
00125 {
00126   return vcl_string("mfpf_max_finder");
00127 }
00128 
00129 //: Create a copy on the heap and return base class pointer
00130 mfpf_point_finder* mfpf_max_finder::clone() const
00131 {
00132   return new mfpf_max_finder(*this);
00133 }
00134 
00135 //=======================================================================
00136 // Method: print
00137 //=======================================================================
00138 
00139 void mfpf_max_finder::print_summary(vcl_ostream& os) const
00140 {
00141   os<<"{ ";
00142   mfpf_point_finder::print_summary(os);
00143   os<<" }";
00144 }
00145 
00146 short mfpf_max_finder::version_no() const
00147 {
00148   return 1;
00149 }
00150 
00151 
00152 void mfpf_max_finder::b_write(vsl_b_ostream& bfs) const
00153 {
00154   vsl_b_write(bfs,version_no());
00155   mfpf_point_finder::b_write(bfs);  // Save baseclass
00156 }
00157 
00158 //=======================================================================
00159 // Method: load
00160 //=======================================================================
00161 
00162 void mfpf_max_finder::b_read(vsl_b_istream& bfs)
00163 {
00164   if (!bfs) return;
00165   short version;
00166   vsl_b_read(bfs,version);
00167   switch (version)
00168   {
00169     case 1:
00170       mfpf_point_finder::b_read(bfs);  // Load in baseclass
00171       break;
00172     default:
00173       vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream&)\n"
00174                << "           Unknown version number "<< version << vcl_endl;
00175       bfs.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00176       return;
00177   }
00178 }