core/vpgl/algo/vpgl_bundle_adjust.h
Go to the documentation of this file.
00001 // This is vpgl/algo/vpgl_bundle_adjust.h
00002 #ifndef vpgl_bundle_adjust_h_
00003 #define vpgl_bundle_adjust_h_
00004 //:
00005 // \file
00006 // \brief Bundle adjustment sparse least squares functions
00007 // \author Matt Leotta
00008 // \date April 18, 2005
00009 // \verbatim
00010 //  Modifications
00011 //   Mar 23, 2010  MJL - Separate file for least square function class
00012 // \endverbatim
00013 
00014 
00015 #include <vnl/vnl_vector.h>
00016 #include <vgl/vgl_point_2d.h>
00017 #include <vgl/vgl_point_3d.h>
00018 #include <vpgl/vpgl_perspective_camera.h>
00019 #include <vpgl/algo/vpgl_bundle_adjust_lsqr.h>
00020 #include <vcl_vector.h>
00021 
00022 
00023 //: Static functions for bundle adjustment
00024 class vpgl_bundle_adjust
00025 {
00026  public:
00027   //: Constructor
00028   vpgl_bundle_adjust();
00029   //: Destructor
00030   ~vpgl_bundle_adjust();
00031 
00032   void set_use_m_estimator(bool use_m) { use_m_estimator_ = use_m; }
00033   void set_m_estimator_scale(double scale) { m_estimator_scale_ = scale; }
00034   void set_use_gradient(bool use_gradient) { use_gradient_ = use_gradient; }
00035   void set_self_calibrate(bool self_calibrate) { self_calibrate_ = self_calibrate; }
00036   void set_normalize_data(bool normalize) { normalize_data_ = normalize; }
00037   void set_verbose(bool verbose) { verbose_ = verbose; }
00038   void set_max_iterations(unsigned maxitr) { max_iterations_ = maxitr; }
00039   void set_x_tolerence(double xtol) { x_tol_ = xtol; }
00040   void set_g_tolerence(double gtol) { g_tol_ = gtol; }
00041   //: step size for finite differencing operations
00042   void set_epsilon(double eps) { epsilon_ = eps; }
00043 
00044   //: Return the ending error
00045   double end_error() const { return end_error_; }
00046   //: Return the starting error
00047   double start_error() const { return start_error_; }
00048   //: Return the number of iterations
00049   int num_iterations() const { return num_iterations_; }
00050   //: Return the weights a the end of the optimization
00051   const vcl_vector<double>& final_weights() const { return weights_; }
00052 
00053   //: Return the raw camera parameters
00054   const vnl_vector<double>& cam_params() const { return a_; }
00055   //: Return the raw world point parameters
00056   const vnl_vector<double>& point_params() const { return b_; }
00057 
00058   //: Approximately depth invert the scene.
00059   //  Apply this and re-optimize to get out of a common local minimum.
00060   //  Find the mean axis between cameras and points, mirror the points about
00061   //  a plane perpendicular to this axis, and rotate the cameras 180 degrees
00062   //  around this axis
00063   void depth_reverse(vcl_vector<vpgl_perspective_camera<double> >& cameras,
00064                      vcl_vector<vgl_point_3d<double> >& world_points);
00065 
00066   //: Bundle Adjust
00067   //
00068   // \param mask should have the same number of entries as \param cameras, 
00069   // and each entry of \param mask should be the same size as 
00070   // \param world_points. mask[i][j] is true if point j is visible from 
00071   // camera i
00072   //
00073   // \param image_points and is a linear list of the 2D locations of the 
00074   // 3D points as seen by the cameras. There is one image point for every 
00075   // true in \param mask. The following piece of code shows the structure 
00076   // of \param image_points
00077   // 
00078   // for( int c = 0; c < num_cameras; c++ ){
00079   //   for( int dp = 0; dp < num_world_points; dp++ ){
00080   //     if( mask[c][dp] )
00081   //       img_points.push_back( all_image_points[c*num_world_points+dp] );
00082   //   }
00083   // }
00084   bool optimize(vcl_vector<vpgl_perspective_camera<double> >& cameras,
00085                 vcl_vector<vgl_point_3d<double> >& world_points,
00086                 const vcl_vector<vgl_point_2d<double> >& image_points,
00087                 const vcl_vector<vcl_vector<bool> >& mask);
00088 
00089   //: Write cameras and points to a file in VRML 2.0 for debugging
00090   static void write_vrml(const vcl_string& filename,
00091                          const vcl_vector<vpgl_perspective_camera<double> >& cameras,
00092                          const vcl_vector<vgl_point_3d<double> >& world_points);
00093 
00094  private:
00095   //: normalize image points to be mean centered with scale sqrt(2)
00096   // \return parameters such that original point are recovered as (ns*x+nx, ns*y+ny)
00097   void normalize_points(vcl_vector<vgl_point_2d<double> >& image_points,
00098                         double& nx, double& ny, double& ns);
00099 
00100   // reflect the points about a plane
00101   void reflect_points(const vgl_plane_3d<double>& plane,
00102                       vcl_vector<vgl_point_3d<double> >& points);
00103 
00104   // rotation the cameras 180 degrees around an axis
00105   void rotate_cameras(const vgl_vector_3d<double>& axis,
00106                       vcl_vector<vpgl_perspective_camera<double> >& cameras);
00107 
00108   //: The bundle adjustment error function
00109   vpgl_bundle_adjust_lsqr* ba_func_;
00110   //: The last camera parameters
00111   vnl_vector<double> a_;
00112   //: The last point parameters
00113   vnl_vector<double> b_;
00114   //: The last global parameters
00115   vnl_vector<double> c_;
00116   //: The last estimated weights
00117   vcl_vector<double> weights_;
00118 
00119   bool use_m_estimator_;
00120   double m_estimator_scale_;
00121   bool use_gradient_;
00122   bool self_calibrate_;
00123   bool normalize_data_;
00124   bool verbose_;
00125   unsigned int max_iterations_;
00126   double x_tol_;
00127   double g_tol_;
00128   double epsilon_;
00129 
00130   double start_error_;
00131   double end_error_;
00132   int num_iterations_;
00133 };
00134 
00135 
00136 #endif // vpgl_bundle_adjust_h_