core/vpgl/algo/vpgl_ba_fixed_k_lsqr.cxx
Go to the documentation of this file.
00001 // This is vpgl/algo/vpgl_ba_fixed_k_lsqr.cxx
00002 #include "vpgl_ba_fixed_k_lsqr.h"
00003 //:
00004 // \file
00005 
00006 #include <vnl/vnl_vector_ref.h>
00007 #include <vgl/algo/vgl_rotation_3d.h>
00008 
00009 
00010 //: Constructor
00011 vpgl_ba_fixed_k_lsqr::
00012 vpgl_ba_fixed_k_lsqr(const vcl_vector<vpgl_calibration_matrix<double> >& K,
00013                      const vcl_vector<vgl_point_2d<double> >& image_points,
00014                      const vcl_vector<vcl_vector<bool> >& mask)
00015  : vpgl_bundle_adjust_lsqr(6,3,0,image_points,mask),
00016    K_(K)
00017 {
00018   for (unsigned int i=0; i<K_.size(); ++i)
00019     Km_.push_back(K_[i].get_matrix());
00020 }
00021 
00022 
00023 //: Constructor
00024 //  Each image point is assigned an inverse covariance (error projector) matrix
00025 // \note image points are not homogeneous because they require finite points to measure projection error
00026 vpgl_ba_fixed_k_lsqr::
00027 vpgl_ba_fixed_k_lsqr(const vcl_vector<vpgl_calibration_matrix<double> >& K,
00028                      const vcl_vector<vgl_point_2d<double> >& image_points,
00029                      const vcl_vector<vnl_matrix<double> >& inv_covars,
00030                      const vcl_vector<vcl_vector<bool> >& mask)
00031  : vpgl_bundle_adjust_lsqr(6,3,0,image_points,inv_covars,mask),
00032    K_(K)
00033 {
00034   for (unsigned int i=0; i<K_.size(); ++i)
00035     Km_.push_back(K_[i].get_matrix());
00036 }
00037 
00038 
00039 //: compute the Jacobian Aij
00040 void vpgl_ba_fixed_k_lsqr::jac_Aij(unsigned int i,
00041                                    unsigned int j,
00042                                    vnl_double_3x4 const& Pi,
00043                                    vnl_vector<double> const& ai,
00044                                    vnl_vector<double> const& bj,
00045                                    vnl_vector<double> const& c,
00046                                    vnl_matrix<double>& Aij)
00047 {
00048   // the translation part
00049   // --------------------
00050   vnl_double_3x3 M = Pi.extract(3,3);
00051   // This is semi const incorrect - there is no vnl_vector_ref_const
00052   const vnl_vector_ref<double> C(3,const_cast<double*>(ai.data_block())+3);
00053   vnl_matrix<double> Aij_sub(2,3);
00054   jac_camera_center(M,C,bj,Aij_sub);
00055   Aij.update(Aij_sub,0,3);
00056 
00057 
00058   // the rotation part
00059   // -----------------
00060   // This is semi const incorrect - there is no vnl_vector_ref_const
00061   const vnl_vector_ref<double> r(3,const_cast<double*>(ai.data_block()));
00062   jac_camera_rotation(Km_[i],C,r,bj,Aij);
00063 }
00064 
00065 //: compute the Jacobian Bij
00066 void vpgl_ba_fixed_k_lsqr::jac_Bij(unsigned int i,
00067                                    unsigned int j,
00068                                    vnl_double_3x4 const& Pi,
00069                                    vnl_vector<double> const& ai,
00070                                    vnl_vector<double> const& bj,
00071                                    vnl_vector<double> const& c,
00072                                    vnl_matrix<double>& Bij)
00073 {
00074   jac_inhomg_3d_point(Pi, bj, Bij);
00075 }
00076 
00077 //: compute the Jacobian Cij
00078 void vpgl_ba_fixed_k_lsqr::jac_Cij(unsigned int i,
00079                                    unsigned int j,
00080                                    vnl_double_3x4 const& Pi,
00081                                    vnl_vector<double> const& ai,
00082                                    vnl_vector<double> const& bj,
00083                                    vnl_vector<double> const& c,
00084                                    vnl_matrix<double>& Cij)
00085 {
00086   // do nothing, c parameters are not used
00087 }
00088 
00089 //: construct the \param j-th perspective camera from a pointer to the j-th parameters of \param b and parameters \param c
00090 vgl_homg_point_3d<double>
00091 vpgl_ba_fixed_k_lsqr::param_to_point(int j,
00092                                      const double* bj,
00093                                      const vnl_vector<double>& c) const
00094 {
00095   return vgl_homg_point_3d<double>(bj[0], bj[1], bj[2]);
00096 }
00097 
00098 //: construct the \param j-th perspective camera from a pointer to the j-th parameters of \param b and parameters \param c
00099 vnl_vector_fixed<double,4>
00100 vpgl_ba_fixed_k_lsqr::param_to_pt_vector(int j,
00101                                          const double* bj,
00102                                          const vnl_vector<double>& c) const
00103 {
00104   return vnl_vector_fixed<double,4>(bj[0], bj[1], bj[2], 1.0);
00105 }
00106 
00107 //: construct the \param i-th perspective camera from a pointer to the i-th parameters of \param a and parameters \param c
00108 vpgl_perspective_camera<double>
00109 vpgl_ba_fixed_k_lsqr::param_to_cam(int i,
00110                                    const double* ai,
00111                                    const vnl_vector<double>& c) const
00112 {
00113   vnl_vector<double> w(ai,3);
00114   vgl_homg_point_3d<double> t(ai[3], ai[4], ai[5]);
00115   return vpgl_perspective_camera<double>(K_[i],t,vgl_rotation_3d<double>(w));
00116 }
00117 
00118 //: compute a 3x4 camera matrix of camera \param i from a pointer to the i-th parameters of \param a and parameters \param c
00119 vnl_double_3x4
00120 vpgl_ba_fixed_k_lsqr::param_to_cam_matrix(int i,
00121                                           const double* ai,
00122                                           const vnl_vector<double>& c) const
00123 {
00124   const vnl_vector_ref<double> r(3,const_cast<double*>(ai));
00125   vnl_double_3x3 M = Km_[i]*rod_to_matrix(r);
00126   vnl_double_3x4 P;
00127   P.set_columns(0, M.as_ref());
00128   const vnl_vector_ref<double> center(3,const_cast<double*>(ai+3));
00129   P.set_column(3,-(M*center));
00130   return P;
00131 }
00132 
00133 
00134 //: Create the parameter vector \p a from a vector of cameras
00135 vnl_vector<double>
00136 vpgl_ba_fixed_k_lsqr::create_param_vector(const vcl_vector<vpgl_perspective_camera<double> >& cameras)
00137 {
00138   vnl_vector<double> a(6*cameras.size(),0.0);
00139   for (unsigned int i=0; i<cameras.size(); ++i)
00140   {
00141     const vpgl_perspective_camera<double>& cam = cameras[i];
00142     const vgl_point_3d<double>& c = cam.get_camera_center();
00143     const vgl_rotation_3d<double>& R = cam.get_rotation();
00144 
00145     // compute the Rodrigues vector from the rotation
00146     vnl_vector_fixed<double,3> w = R.as_rodrigues();
00147 
00148     double* ai = a.data_block() + i*6;
00149     ai[0]=w[0];   ai[1]=w[1];   ai[2]=w[2];
00150     ai[3]=c.x();  ai[4]=c.y();  ai[5]=c.z();
00151   }
00152   return a;
00153 }
00154 
00155 
00156 //: Create the parameter vector \p b from a vector of 3D points
00157 vnl_vector<double>
00158 vpgl_ba_fixed_k_lsqr::create_param_vector(const vcl_vector<vgl_point_3d<double> >& world_points)
00159 {
00160   vnl_vector<double> b(3*world_points.size(),0.0);
00161   for (unsigned int j=0; j<world_points.size(); ++j){
00162     const vgl_point_3d<double>& point = world_points[j];
00163     double* bj = b.data_block() + j*3;
00164     bj[0]=point.x();  bj[1]=point.y();  bj[2]=point.z();
00165   }
00166   return b;
00167 }
00168