00001
00002 #include "vpgl_ba_shared_k_lsqr.h"
00003
00004
00005
00006 #include <vnl/vnl_vector_ref.h>
00007 #include <vgl/algo/vgl_rotation_3d.h>
00008 #include <vnl/vnl_double_3.h>
00009
00010
00011
00012 vpgl_ba_shared_k_lsqr::
00013 vpgl_ba_shared_k_lsqr(const vpgl_calibration_matrix<double>& K,
00014 const vcl_vector<vgl_point_2d<double> >& image_points,
00015 const vcl_vector<vcl_vector<bool> >& mask)
00016 : vpgl_bundle_adjust_lsqr(6,3,1,image_points,mask),
00017 K_(K)
00018 {
00019
00020 if (K_.x_scale() != 1.0)
00021 {
00022 K_.set_focal_length(K_.focal_length() * K_.x_scale());
00023 K_.set_y_scale(K_.y_scale() * K_.x_scale());
00024 K_.set_x_scale(1.0);
00025 }
00026 Km_ = K_.get_matrix();
00027 }
00028
00029
00030
00031
00032
00033 vpgl_ba_shared_k_lsqr::
00034 vpgl_ba_shared_k_lsqr(const vpgl_calibration_matrix<double>& K,
00035 const vcl_vector<vgl_point_2d<double> >& image_points,
00036 const vcl_vector<vnl_matrix<double> >& inv_covars,
00037 const vcl_vector<vcl_vector<bool> >& mask)
00038 : vpgl_bundle_adjust_lsqr(6,3,1,image_points,inv_covars,mask),
00039 K_(K)
00040 {
00041
00042 if (K_.x_scale() != 1.0)
00043 {
00044 K_.set_focal_length(K_.focal_length() * K_.x_scale());
00045 K_.set_y_scale(K_.y_scale() * K_.x_scale());
00046 K_.set_x_scale(1.0);
00047 }
00048 Km_ = K_.get_matrix();
00049 }
00050
00051
00052
00053 void vpgl_ba_shared_k_lsqr::jac_Aij(unsigned int i,
00054 unsigned int j,
00055 vnl_double_3x4 const& Pi,
00056 vnl_vector<double> const& ai,
00057 vnl_vector<double> const& bj,
00058 vnl_vector<double> const& c,
00059 vnl_matrix<double>& Aij)
00060 {
00061
00062
00063 vnl_double_3x3 M = Pi.extract(3,3);
00064
00065 const vnl_vector_ref<double> C(3,const_cast<double*>(ai.data_block())+3);
00066 vnl_matrix<double> Aij_sub(2,3);
00067 jac_camera_center(M,C,bj,Aij_sub);
00068 Aij.update(Aij_sub,0,3);
00069
00070
00071
00072
00073
00074 const vnl_vector_ref<double> r(3,const_cast<double*>(ai.data_block()));
00075 Km_(0,0) = c[0];
00076 Km_(1,1) = c[0] * K_.y_scale();
00077 jac_camera_rotation(Km_,C,r,bj,Aij);
00078 }
00079
00080
00081 void vpgl_ba_shared_k_lsqr::jac_Bij(unsigned int i,
00082 unsigned int j,
00083 vnl_double_3x4 const& Pi,
00084 vnl_vector<double> const& ai,
00085 vnl_vector<double> const& bj,
00086 vnl_vector<double> const& c,
00087 vnl_matrix<double>& Bij)
00088 {
00089 jac_inhomg_3d_point(Pi, bj, Bij);
00090 }
00091
00092
00093 void vpgl_ba_shared_k_lsqr::jac_Cij(unsigned int i,
00094 unsigned int j,
00095 vnl_double_3x4 const& Pi,
00096 vnl_vector<double> const& ai,
00097 vnl_vector<double> const& bj,
00098 vnl_vector<double> const& c,
00099 vnl_matrix<double>& Cij)
00100 {
00101 vnl_double_3 p = Pi*vnl_vector_fixed<double,4>(bj[0], bj[1], bj[2], 1.0);
00102
00103 double inv_f = 1.0/c[0];
00104 double skew_term = K_.skew()*inv_f/K_.y_scale();
00105 vgl_point_2d<double> pp = K_.principal_point();
00106 Cij(1,0) = inv_f * (p[1]/p[2] - pp.y());
00107 Cij(0,0) = inv_f * (p[0]/p[2] - pp.x()) - skew_term*Cij(1,0);
00108 }
00109
00110
00111 vgl_homg_point_3d<double>
00112 vpgl_ba_shared_k_lsqr::param_to_point(int j,
00113 const double* bj,
00114 const vnl_vector<double>& c) const
00115 {
00116 return vgl_homg_point_3d<double>(bj[0], bj[1], bj[2]);
00117 }
00118
00119
00120 vnl_vector_fixed<double,4>
00121 vpgl_ba_shared_k_lsqr::param_to_pt_vector(int j,
00122 const double* bj,
00123 const vnl_vector<double>& c) const
00124 {
00125 return vnl_vector_fixed<double,4>(bj[0], bj[1], bj[2], 1.0);
00126 }
00127
00128
00129 vpgl_perspective_camera<double>
00130 vpgl_ba_shared_k_lsqr::param_to_cam(int i,
00131 const double* ai,
00132 const vnl_vector<double>& c) const
00133 {
00134 K_.set_focal_length(c[0]);
00135 vnl_vector<double> w(ai,3);
00136 vgl_homg_point_3d<double> t(ai[3], ai[4], ai[5]);
00137 return vpgl_perspective_camera<double>(K_,t,vgl_rotation_3d<double>(w));
00138 }
00139
00140
00141 vnl_double_3x4
00142 vpgl_ba_shared_k_lsqr::param_to_cam_matrix(int i,
00143 const double* ai,
00144 const vnl_vector<double>& c) const
00145 {
00146 Km_(0,0) = c[0];
00147 Km_(1,1) = c[0] * K_.y_scale();
00148 const vnl_vector_ref<double> r(3,const_cast<double*>(ai));
00149 vnl_double_3x3 M = Km_*rod_to_matrix(r);
00150 vnl_double_3x4 P;
00151 P.update(M);
00152 const vnl_vector_ref<double> center(3,const_cast<double*>(ai+3));
00153 P.set_column(3,-(M*center));
00154 return P;
00155 }
00156
00157
00158
00159 void
00160 vpgl_ba_shared_k_lsqr::
00161 create_param_vector(const vcl_vector<vpgl_perspective_camera<double> >& cameras,
00162 vnl_vector<double>& a,
00163 vnl_vector<double>& c)
00164 {
00165 a.set_size(6*cameras.size());
00166 c.set_size(1);
00167
00168 c[0] = 0.0;
00169 for (unsigned int i=0; i<cameras.size(); ++i)
00170 {
00171 const vpgl_perspective_camera<double>& cam = cameras[i];
00172 const vgl_point_3d<double>& C = cam.get_camera_center();
00173 const vgl_rotation_3d<double>& R = cam.get_rotation();
00174 const vpgl_calibration_matrix<double>& K = cam.get_calibration();
00175
00176 c[0] += K.focal_length() * K.x_scale();
00177
00178
00179 vnl_vector<double> w = R.as_rodrigues();
00180
00181 double* ai = a.data_block() + i*6;
00182 ai[0]=w[0]; ai[1]=w[1]; ai[2]=w[2];
00183 ai[3]=C.x(); ai[4]=C.y(); ai[5]=C.z();
00184 }
00185 c[0] /= cameras.size();
00186 }
00187
00188
00189
00190 vnl_vector<double>
00191 vpgl_ba_shared_k_lsqr::create_param_vector(const vcl_vector<vgl_point_3d<double> >& world_points)
00192 {
00193 vnl_vector<double> b(3*world_points.size(),0.0);
00194 for (unsigned int j=0; j<world_points.size(); ++j){
00195 const vgl_point_3d<double>& point = world_points[j];
00196 double* bj = b.data_block() + j*3;
00197 bj[0]=point.x(); bj[1]=point.y(); bj[2]=point.z();
00198 }
00199 return b;
00200 }
00201