vpgl_bundle_adjust_lsqr.h
Go to the documentation of this file.
1 // This is vpgl/algo/vpgl_bundle_adjust_lsqr.h
2 #ifndef vpgl_bundle_adjust_lsqr_h_
3 #define vpgl_bundle_adjust_lsqr_h_
4 //:
5 // \file
6 // \brief Bundle adjustment sparse least squares base class
7 // \author Matt Leotta
8 // \date April 18, 2005
9 //
10 // \verbatim
11 // Modifications
12 // Mar 23, 2010 MJL - Split off base class and moved to its own file
13 // \endverbatim
14 
15 
16 #include <vector>
17 #include <vnl/vnl_vector.h>
18 #include <vnl/vnl_double_3x3.h>
19 #include <vnl/vnl_double_3x4.h>
21 #include <vgl/vgl_point_2d.h>
22 #include <vgl/vgl_homg_point_3d.h>
24 #ifdef _MSC_VER
25 # include <vcl_msvc_warnings.h>
26 #endif
27 
28 
29 //: base class bundle adjustment sparse least squares function
31 {
32  public:
33  //: Constructor
34  // \note image points are not homogeneous because they require finite points
35  // to measure projection error
36  vpgl_bundle_adjust_lsqr(unsigned int num_params_per_a,
37  unsigned int num_params_per_b,
38  unsigned int num_params_c,
39  std::vector<vgl_point_2d<double> > image_points,
40  const std::vector<std::vector<bool> >& mask);
41 
42  //: Constructor
43  // Each image point is assigned an inverse covariance (error projector) matrix
44  // \note image points are not homogeneous because they require finite points
45  // to measure projection error
46  vpgl_bundle_adjust_lsqr(unsigned int num_params_per_a,
47  unsigned int num_params_per_b,
48  unsigned int num_params_c,
49  const std::vector<vgl_point_2d<double> >& image_points,
50  const std::vector<vnl_matrix<double> >& inv_covars,
51  const std::vector<std::vector<bool> >& mask);
52 
53  // Destructor
54  ~vpgl_bundle_adjust_lsqr() override = default;
55 
56  //: Compute all the reprojection errors
57  // Given the parameter vectors a, b, and c, compute the vector of residuals e.
58  // e has been sized appropriately before the call.
59  // The parameters in for each camera are in a.
60  // The 3D point parameters are in b.
61  // Global parameters are in c.
62  void f(vnl_vector<double> const& a,
63  vnl_vector<double> const& b,
64  vnl_vector<double> const& c,
65  vnl_vector<double>& e) override;
66 
67  //: Compute the residuals from the ith component of a, the jth component of b, and all of c.
68  // This function is not normally used because f() has a
69  // self-contained efficient implementation.
70  // It is used for finite-differencing if the gradient is marked as unavailable
71  void fij(int i, int j,
72  vnl_vector<double> const& ai,
73  vnl_vector<double> const& bj,
74  vnl_vector<double> const& c,
75  vnl_vector<double>& fij) override;
76 
77  //: Compute the sparse Jacobian in block form.
78  void jac_blocks(vnl_vector<double> const& a,
79  vnl_vector<double> const& b,
80  vnl_vector<double> const& c,
81  std::vector<vnl_matrix<double> >& A,
82  std::vector<vnl_matrix<double> >& B,
83  std::vector<vnl_matrix<double> >& C) override;
84 
85 
86  /* parent class has different signatures for these functions */
90 
91  //: compute the Jacobian Aij
92  virtual void jac_Aij(unsigned int i,
93  unsigned int j,
94  vnl_double_3x4 const& Pi,
95  vnl_vector<double> const& ai,
96  vnl_vector<double> const& bj,
97  vnl_vector<double> const& c,
98  vnl_matrix<double>& Aij) = 0;
99 
100  //: compute the Jacobian Bij
101  virtual void jac_Bij(unsigned int i,
102  unsigned int j,
103  vnl_double_3x4 const& Pi,
104  vnl_vector<double> const& ai,
105  vnl_vector<double> const& bj,
106  vnl_vector<double> const& c,
107  vnl_matrix<double>& Bij) = 0;
108 
109  //: compute the Jacobian Cij
110  virtual void jac_Cij(unsigned int i,
111  unsigned int j,
112  vnl_double_3x4 const& Pi,
113  vnl_vector<double> const& ai,
114  vnl_vector<double> const& bj,
115  vnl_vector<double> const& c,
116  vnl_matrix<double>& Cij) = 0;
117 
118  //: Use an M-estimator to compute weights
119  void compute_weight_ij(int i, int j,
120  vnl_vector<double> const& ai,
121  vnl_vector<double> const& bj,
122  vnl_vector<double> const& c,
123  vnl_vector<double> const& fij,
124  double& weight) override;
125 
126  //: set the residual scale for the robust estimation
127  void set_residual_scale(double scale) { scale2_ = scale*scale; }
128 
129 
130  //: construct the \param j-th 3D point from parameter vector \param b and \param c
133  const vnl_vector<double>& b,
134  const vnl_vector<double>& c) const
135  {
136  return param_to_point(j, b.data_block() + index_b(j), c);
137  }
138 
139  //: construct the \param j-th perspective camera from a pointer to the j-th parameter of \param bj and parameters \param c
141  param_to_point(int j,
142  const double* bj,
143  const vnl_vector<double>& c) const = 0;
144 
145  //: construct the \param j-th 3D point from parameter vector \param b and \param c
148  const vnl_vector<double>& b,
149  const vnl_vector<double>& c) const
150  {
151  return param_to_pt_vector(j, b.data_block() + index_b(j), c);
152  }
153 
154  //: construct the \param j-th perspective camera from a pointer to the j-th parameter of \param bj and parameters \param c
156  param_to_pt_vector(int j,
157  const double* bj,
158  const vnl_vector<double>& c) const = 0;
159 
160  //: construct the \param i-th perspective camera from parameter vector \param a
163  const vnl_vector<double>& a,
164  const vnl_vector<double>& c) const
165  {
166  return param_to_cam(i, a.data_block()+index_a(i), c);
167  }
168 
169  //: construct the \param i-th perspective camera from a pointer to the i-th parameter of \param ai and parameters \param c
171  param_to_cam(int i,
172  const double* ai,
173  const vnl_vector<double>& c) const = 0;
174 
175  //: construct the \param i-th perspective camera matrix from parameter vectors \param a and \param c
177  const vnl_vector<double>& a,
178  const vnl_vector<double>& c) const
179  {
180  return param_to_cam_matrix(i, a.data_block()+index_a(i), c);
181  }
182 
183  //: compute the 3x4 matrix of camera \param i from a pointer to the i-th parameter of \param ai and parameters \param c
184  virtual vnl_double_3x4 param_to_cam_matrix(int i,
185  const double* ai,
186  const vnl_vector<double>& c) const = 0;
187 
188  //: reset the weights
189  void reset()
190  {
191  iteration_count_ = 0;
192  }
193 
194 
195  //---------------------------------------------------------------------------
196  // Static helper functions
197 
198  //: Fast conversion of rotation from Rodrigues vector to matrix
200 
201  //: compute the 2x3 Jacobian of camera projection with respect to point location df/dpt where $f(pt) = P*pt$
202  static void jac_inhomg_3d_point(vnl_double_3x4 const& P,
203  vnl_vector<double> const& pt,
204  vnl_matrix<double>& J);
205 
206  //: compute the 2x3 Jacobian of camera projection with respect to camera center df/dC where $f(C) = [M | -M*C]*pt$
207  static void jac_camera_center(vnl_double_3x3 const& M,
208  vnl_vector<double> const& C,
209  vnl_vector<double> const& pt,
210  vnl_matrix<double>& J);
211 
212  //: 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$
213  // Here r is a Rodrigues vector, K is an upper triangular calibration matrix
214  static void jac_camera_rotation(vnl_double_3x3 const& K,
215  vnl_vector<double> const& C,
216  vnl_vector<double> const& r,
217  vnl_vector<double> const& pt,
218  vnl_matrix<double>& J);
219 
220 
221  protected:
222  //: The corresponding points in the image
223  std::vector<vgl_point_2d<double> > image_points_;
224  //: The Cholesky factored inverse covariances for each image point
225  std::vector<vnl_matrix<double> > factored_inv_covars_;
226  //: Flag to enable covariance weighted errors
228  //: The square of the scale of the robust estimator
229  double scale2_;
230 
232 };
233 
234 
235 #endif // vpgl_bundle_adjust_lsqr_h_
void jac_blocks(vnl_vector< double > const &a, vnl_vector< double > const &b, vnl_vector< double > const &c, std::vector< vnl_matrix< double > > &A, std::vector< vnl_matrix< double > > &B, std::vector< vnl_matrix< double > > &C) override
Compute the sparse Jacobian in block form.
unsigned int index_a(int i) const
A class for the perspective camera model.
virtual void jac_Aij(unsigned int i, unsigned int j, vnl_vector< double > const &ai, vnl_vector< double > const &bj, vnl_vector< double > const &c, vnl_matrix< double > &Aij)
void fij(int i, int j, vnl_vector< double > const &ai, vnl_vector< double > const &bj, vnl_vector< double > const &c, vnl_vector< double > &fij) override
Compute the residuals from the ith component of a, the jth component of b, and all of c.
static void jac_camera_rotation(vnl_double_3x3 const &K, vnl_vector< double > const &C, vnl_vector< double > const &r, vnl_vector< double > const &pt, vnl_matrix< double > &J)
compute the 2x3 Jacobian of camera projection with respect to camera rotation df/dr where $f(r) = K*r...
vnl_vector_fixed< double, 4 > param_to_pt_vector(int j, const vnl_vector< double > &b, const vnl_vector< double > &c) const
construct the
unsigned int index_b(int j) const
static vnl_double_3x3 rod_to_matrix(vnl_vector< double > const &r)
Fast conversion of rotation from Rodrigues vector to matrix.
double scale2_
The square of the scale of the robust estimator.
static void jac_camera_center(vnl_double_3x3 const &M, vnl_vector< double > const &C, vnl_vector< double > const &pt, vnl_matrix< double > &J)
compute the 2x3 Jacobian of camera projection with respect to camera center df/dC where $f(C) = [M | ...
void compute_weight_ij(int i, int j, vnl_vector< double > const &ai, vnl_vector< double > const &bj, vnl_vector< double > const &c, vnl_vector< double > const &fij, double &weight) override
Use an M-estimator to compute weights.
~vpgl_bundle_adjust_lsqr() override=default
virtual void jac_Cij(unsigned int i, unsigned int j, vnl_double_3x4 const &Pi, vnl_vector< double > const &ai, vnl_vector< double > const &bj, vnl_vector< double > const &c, vnl_matrix< double > &Cij)=0
compute the Jacobian Cij.
double const * data_block() const
vnl_double_3x4 param_to_cam_matrix(int i, const vnl_vector< double > &a, const vnl_vector< double > &c) const
construct the
virtual void jac_Aij(unsigned int i, unsigned int j, vnl_double_3x4 const &Pi, vnl_vector< double > const &ai, vnl_vector< double > const &bj, vnl_vector< double > const &c, vnl_matrix< double > &Aij)=0
compute the Jacobian Aij.
std::vector< vgl_point_2d< double > > image_points_
The corresponding points in the image.
virtual void jac_Bij(unsigned int i, unsigned int j, vnl_vector< double > const &ai, vnl_vector< double > const &bj, vnl_vector< double > const &c, vnl_matrix< double > &Bij)
void f(vnl_vector< double > const &a, vnl_vector< double > const &b, vnl_vector< double > const &c, vnl_vector< double > &e) override
Compute all the reprojection errors.
base class bundle adjustment sparse least squares function.
vgl_homg_point_3d< double > param_to_point(int j, const vnl_vector< double > &b, const vnl_vector< double > &c) const
construct the
static void jac_inhomg_3d_point(vnl_double_3x4 const &P, vnl_vector< double > const &pt, vnl_matrix< double > &J)
compute the 2x3 Jacobian of camera projection with respect to point location df/dpt where $f(pt) = P*...
This class implements the perspective camera class as described in Hartley & Zisserman as a finite ca...
bool use_covars_
Flag to enable covariance weighted errors.
std::vector< vnl_matrix< double > > factored_inv_covars_
The Cholesky factored inverse covariances for each image point.
vpgl_bundle_adjust_lsqr(unsigned int num_params_per_a, unsigned int num_params_per_b, unsigned int num_params_c, std::vector< vgl_point_2d< double > > image_points, const std::vector< std::vector< bool > > &mask)
Constructor.
virtual void jac_Cij(unsigned int i, unsigned int j, vnl_vector< double > const &ai, vnl_vector< double > const &bj, vnl_vector< double > const &c, vnl_matrix< double > &Cij)
virtual void jac_Bij(unsigned int i, unsigned int j, vnl_double_3x4 const &Pi, vnl_vector< double > const &ai, vnl_vector< double > const &bj, vnl_vector< double > const &c, vnl_matrix< double > &Bij)=0
compute the Jacobian Bij.
void set_residual_scale(double scale)
set the residual scale for the robust estimation.
vpgl_perspective_camera< double > param_to_cam(int i, const vnl_vector< double > &a, const vnl_vector< double > &c) const
construct the
void reset()
reset the weights.