core/vpgl/algo/vpgl_bundle_adjust_lsqr.h
Go to the documentation of this file.
00001 // This is vpgl/algo/vpgl_bundle_adjust_lsqr.h
00002 #ifndef vpgl_bundle_adjust_lsqr_h_
00003 #define vpgl_bundle_adjust_lsqr_h_
00004 //:
00005 // \file
00006 // \brief Bundle adjustment sparse least squares base class
00007 // \author Matt Leotta
00008 // \date April 18, 2005
00009 //
00010 // \verbatim
00011 //  Modifications
00012 //   Mar 23, 2010  MJL - Split off base class and moved to its own file
00013 // \endverbatim
00014 
00015 
00016 #include <vnl/vnl_vector.h>
00017 #include <vnl/vnl_double_3x3.h>
00018 #include <vnl/vnl_double_3x4.h>
00019 #include <vnl/vnl_sparse_lst_sqr_function.h>
00020 #include <vgl/vgl_point_2d.h>
00021 #include <vgl/vgl_homg_point_3d.h>
00022 #include <vpgl/vpgl_perspective_camera.h>
00023 #include <vcl_vector.h>
00024 
00025 
00026 //: base class bundle adjustment sparse least squares function
00027 class vpgl_bundle_adjust_lsqr : public vnl_sparse_lst_sqr_function
00028 {
00029  public:
00030   //: Constructor
00031   // \note image points are not homogeneous because they require finite points
00032   //       to measure projection error
00033   vpgl_bundle_adjust_lsqr(unsigned int num_params_per_a,
00034                           unsigned int num_params_per_b,
00035                           unsigned int num_params_c,
00036                           const vcl_vector<vgl_point_2d<double> >& image_points,
00037                           const vcl_vector<vcl_vector<bool> >& mask);
00038 
00039   //: Constructor
00040   //  Each image point is assigned an inverse covariance (error projector) matrix
00041   // \note image points are not homogeneous because they require finite points
00042   //       to measure projection error
00043   vpgl_bundle_adjust_lsqr(unsigned int num_params_per_a,
00044                           unsigned int num_params_per_b,
00045                           unsigned int num_params_c,
00046                           const vcl_vector<vgl_point_2d<double> >& image_points,
00047                           const vcl_vector<vnl_matrix<double> >& inv_covars,
00048                           const vcl_vector<vcl_vector<bool> >& mask);
00049 
00050   // Destructor
00051   virtual ~vpgl_bundle_adjust_lsqr() {}
00052 
00053   //: Compute all the reprojection errors
00054   //  Given the parameter vectors a, b, and c, compute the vector of residuals e.
00055   //  e has been sized appropriately before the call.
00056   //  The parameters in for each camera are in a.
00057   //  The 3D point parameters are in b.
00058   //  Global parameters are in c.
00059   virtual void f(vnl_vector<double> const& a,
00060                  vnl_vector<double> const& b,
00061                  vnl_vector<double> const& c,
00062                  vnl_vector<double>& e);
00063 
00064   //: Compute the residuals from the ith component of a, the jth component of b, and all of c.
00065   //  This function is not normally used because f() has a
00066   //  self-contained efficient implementation.
00067   //  It is used for finite-differencing if the gradient is marked as unavailable
00068   virtual void fij(int i, int j,
00069                    vnl_vector<double> const& ai,
00070                    vnl_vector<double> const& bj,
00071                    vnl_vector<double> const& c,
00072                    vnl_vector<double>& fij);
00073 
00074   //: Compute the sparse Jacobian in block form.
00075   virtual void jac_blocks(vnl_vector<double> const& a,
00076                           vnl_vector<double> const& b,
00077                           vnl_vector<double> const& c,
00078                           vcl_vector<vnl_matrix<double> >& A,
00079                           vcl_vector<vnl_matrix<double> >& B,
00080                           vcl_vector<vnl_matrix<double> >& C);
00081 
00082   //: compute the Jacobian Aij
00083   virtual void jac_Aij(unsigned int i,
00084                        unsigned int j,
00085                        vnl_double_3x4 const& Pi,
00086                        vnl_vector<double> const& ai,
00087                        vnl_vector<double> const& bj,
00088                        vnl_vector<double> const& c,
00089                        vnl_matrix<double>& Aij) = 0;
00090 
00091   //: compute the Jacobian Bij
00092   virtual void jac_Bij(unsigned int i,
00093                        unsigned int j,
00094                        vnl_double_3x4 const& Pi,
00095                        vnl_vector<double> const& ai,
00096                        vnl_vector<double> const& bj,
00097                        vnl_vector<double> const& c,
00098                        vnl_matrix<double>& Bij) = 0;
00099 
00100   //: compute the Jacobian Cij
00101   virtual void jac_Cij(unsigned int i,
00102                        unsigned int j,
00103                        vnl_double_3x4 const& Pi,
00104                        vnl_vector<double> const& ai,
00105                        vnl_vector<double> const& bj,
00106                        vnl_vector<double> const& c,
00107                        vnl_matrix<double>& Cij) = 0;
00108 
00109   //: Use an M-estimator to compute weights
00110   void compute_weight_ij(int i, int j,
00111                          vnl_vector<double> const& ai,
00112                          vnl_vector<double> const& bj,
00113                          vnl_vector<double> const& c,
00114                          vnl_vector<double> const& fij,
00115                          double& weight);
00116 
00117   //: set the residual scale for the robust estimation
00118   void set_residual_scale(double scale) { scale2_ = scale*scale; }
00119 
00120 
00121   //: construct the \param j-th 3D point from parameter vector \param b and \param c
00122   vgl_homg_point_3d<double>
00123   param_to_point(int j,
00124                  const vnl_vector<double>& b,
00125                  const vnl_vector<double>& c) const
00126   {
00127     return param_to_point(j, b.data_block() + index_b(j), c);
00128   }
00129 
00130   //: construct the \param j-th perspective camera from a pointer to the j-th parameter of \param bj and parameters \param c
00131   virtual vgl_homg_point_3d<double>
00132   param_to_point(int j,
00133                  const double* bj,
00134                  const vnl_vector<double>& c) const = 0;
00135 
00136   //: construct the \param j-th 3D point from parameter vector \param b and \param c
00137   vnl_vector_fixed<double,4>
00138   param_to_pt_vector(int j,
00139                      const vnl_vector<double>& b,
00140                      const vnl_vector<double>& c) const
00141   {
00142     return param_to_pt_vector(j, b.data_block() + index_b(j), c);
00143   }
00144 
00145   //: construct the \param j-th perspective camera from a pointer to the j-th parameter of \param bj and parameters \param c
00146   virtual vnl_vector_fixed<double,4>
00147   param_to_pt_vector(int j,
00148                      const double* bj,
00149                      const vnl_vector<double>& c) const = 0;
00150 
00151   //: construct the \param i-th perspective camera from parameter vector \param a
00152   vpgl_perspective_camera<double>
00153   param_to_cam(int i,
00154                const vnl_vector<double>& a,
00155                const vnl_vector<double>& c) const
00156   {
00157     return param_to_cam(i, a.data_block()+index_a(i), c);
00158   }
00159 
00160   //: construct the \param i-th perspective camera from a pointer to the i-th parameter of \param ai and parameters \param c
00161   virtual vpgl_perspective_camera<double>
00162   param_to_cam(int i,
00163                const double* ai,
00164                const vnl_vector<double>& c) const = 0;
00165 
00166   //: construct the \param i-th perspective camera matrix from parameter vectors \param a and \param c
00167   vnl_double_3x4 param_to_cam_matrix(int i,
00168                                      const vnl_vector<double>& a,
00169                                      const vnl_vector<double>& c) const
00170   {
00171     return param_to_cam_matrix(i, a.data_block()+index_a(i), c);
00172   }
00173 
00174   //: compute the 3x4 matrix of camera \param i from a pointer to the i-th parameter of \param ai and parameters \param c
00175   virtual vnl_double_3x4 param_to_cam_matrix(int i,
00176                                              const double* ai,
00177                                              const vnl_vector<double>& c) const = 0;
00178 
00179   //: reset the weights
00180   void reset()
00181   {
00182     iteration_count_ = 0;
00183   }
00184 
00185 
00186   //---------------------------------------------------------------------------
00187   // Static helper functions
00188 
00189   //: Fast conversion of rotation from Rodrigues vector to matrix
00190   static vnl_double_3x3 rod_to_matrix(vnl_vector<double> const& r);
00191 
00192   //: compute the 2x3 Jacobian of camera projection with respect to point location df/dpt where $f(pt) = P*pt$
00193   static void jac_inhomg_3d_point(vnl_double_3x4 const& P,
00194                                   vnl_vector<double> const& pt,
00195                                   vnl_matrix<double>& J);
00196 
00197   //: compute the 2x3 Jacobian of camera projection with respect to camera center df/dC where $f(C) = [M | -M*C]*pt$
00198   static void jac_camera_center(vnl_double_3x3 const& M,
00199                                 vnl_vector<double> const& C,
00200                                 vnl_vector<double> const& pt,
00201                                 vnl_matrix<double>& J);
00202 
00203   //: compute the 2x3 Jacobian of camera projection with respect to camera rotation df/dr where $f(r) = K*rod_to_matrix(r)*[I | -C]*pt$
00204   //  Here r is a Rodrigues vector, K is an upper triangular calibration matrix
00205   static void jac_camera_rotation(vnl_double_3x3 const& K,
00206                                   vnl_vector<double> const& C,
00207                                   vnl_vector<double> const& r,
00208                                   vnl_vector<double> const& pt,
00209                                   vnl_matrix<double>& J);
00210 
00211 
00212  protected:
00213   //: The corresponding points in the image
00214   vcl_vector<vgl_point_2d<double> > image_points_;
00215   //: The Cholesky factored inverse covariances for each image point
00216   vcl_vector<vnl_matrix<double> > factored_inv_covars_;
00217   //: Flag to enable covariance weighted errors
00218   bool use_covars_;
00219   //: The square of the scale of the robust estimator
00220   double scale2_;
00221 
00222   int iteration_count_;
00223 };
00224 
00225 
00226 #endif // vpgl_bundle_adjust_lsqr_h_