00001
00002 #ifndef vpgl_bundle_adjust_h_
00003 #define vpgl_bundle_adjust_h_
00004
00005
00006
00007
00008
00009
00010 #include <vnl/vnl_vector.h>
00011 #include <vnl/vnl_sparse_lst_sqr_function.h>
00012 #include <vgl/vgl_point_2d.h>
00013 #include <vgl/vgl_point_3d.h>
00014 #include <vgl/vgl_homg_point_3d.h>
00015 #include <vgl/algo/vgl_rotation_3d.h>
00016 #include <vpgl/vpgl_perspective_camera.h>
00017 #include <vcl_vector.h>
00018
00019
00020
00021 class vpgl_bundle_adj_lsqr : public vnl_sparse_lst_sqr_function
00022 {
00023 public:
00024
00025
00026 vpgl_bundle_adj_lsqr(const vcl_vector<vpgl_calibration_matrix<double> >& K,
00027 const vcl_vector<vgl_point_2d<double> >& image_points,
00028 const vcl_vector<vcl_vector<bool> >& mask,
00029 bool use_confidence_weights = true);
00030
00031
00032
00033
00034 vpgl_bundle_adj_lsqr(const vcl_vector<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 bool use_confidence_weights = true);
00039
00040
00041 virtual ~vpgl_bundle_adj_lsqr() {}
00042
00043
00044
00045
00046
00047
00048
00049
00050 virtual void f(vnl_vector<double> const& a, vnl_vector<double> const& b,
00051 vnl_vector<double>& e);
00052
00053
00054
00055
00056 virtual void fij(int i, int j, vnl_vector<double> const& ai,
00057 vnl_vector<double> const& bj, vnl_vector<double>& fij);
00058
00059
00060 virtual void jac_blocks(vnl_vector<double> const& a, vnl_vector<double> const& b,
00061 vcl_vector<vnl_matrix<double> >& A,
00062 vcl_vector<vnl_matrix<double> >& B);
00063
00064
00065 void jac_Aij(vnl_double_3x4 const& Pi, vnl_double_3x3 const& K,
00066 vnl_vector<double> const& ai, vnl_vector<double> const& bj,
00067 vnl_matrix<double>& Aij);
00068
00069
00070 void jac_Bij(vnl_double_3x4 const& Pi, vnl_vector<double> const& bj,
00071 vnl_matrix<double>& Bij);
00072
00073
00074
00075 vgl_homg_point_3d<double> param_to_point(int j, const vnl_vector<double>& b) const
00076 {
00077 const double* d = b.data_block() + index_b(j);
00078 return vgl_homg_point_3d<double>(d[0], d[1], d[2]);
00079 }
00080
00081
00082 vpgl_perspective_camera<double> param_to_cam(int i, const vnl_vector<double>& a) const
00083 {
00084 return param_to_cam(i, a.data_block()+index_a(i));
00085 }
00086 vpgl_perspective_camera<double> param_to_cam(int i, const double* d) const
00087 {
00088 vnl_vector<double> w(d,3);
00089 vgl_homg_point_3d<double> t(d[3], d[4], d[5]);
00090 return vpgl_perspective_camera<double>(K_[i],t,vgl_rotation_3d<double>(w));
00091 }
00092
00093
00094
00095 vnl_double_3x4 param_to_cam_matrix(int i, const vnl_vector<double>& a) const
00096 {
00097 return param_to_cam_matrix(i, a.data_block()+index_a(i));
00098 }
00099 vnl_double_3x4 param_to_cam_matrix(int i, const double* d) const
00100 {
00101 vnl_double_3x3 M = Km_[i]*rod_to_matrix(d);
00102 vnl_double_3x4 P;
00103 P.update(M);
00104 const vnl_vector_ref<double> c(3,const_cast<double*>(d+3));
00105 P.set_column(3,-(M*c));
00106 return P;
00107 }
00108
00109
00110 vnl_matrix_fixed<double,3,3> rod_to_matrix(const double* r) const;
00111
00112
00113 static vnl_vector<double>
00114 create_param_vector(const vcl_vector<vpgl_perspective_camera<double> >& cameras);
00115
00116
00117 static vnl_vector<double>
00118 create_param_vector(const vcl_vector<vgl_point_3d<double> >& world_points);
00119
00120
00121 void reset() { iteration_count_ = 0; for (unsigned int i=0; i<weights_.size(); ++i) weights_[i] = 1.0; }
00122
00123
00124 vcl_vector<double> weights() const { return weights_; }
00125
00126 protected:
00127
00128 vcl_vector<vpgl_calibration_matrix<double> > K_;
00129
00130 vcl_vector<vnl_double_3x3> Km_;
00131
00132 vcl_vector<vgl_point_2d<double> > image_points_;
00133
00134 vcl_vector<vnl_matrix<double> > factored_inv_covars_;
00135
00136 bool use_covars_;
00137
00138 bool use_weights_;
00139
00140 vcl_vector<double> weights_;
00141 int iteration_count_;
00142 };
00143
00144
00145
00146 class vpgl_bundle_adjust
00147 {
00148 public:
00149
00150 vpgl_bundle_adjust();
00151
00152 ~vpgl_bundle_adjust();
00153
00154 void set_use_weights(bool use_weights) { use_weights_ = use_weights; }
00155 void set_use_gradient(bool use_gradient) { use_gradient_ = use_gradient; }
00156
00157
00158 double end_error() const { return end_error_; }
00159
00160 double start_error() const { return start_error_; }
00161
00162 int num_iterations() const { return num_iterations_; }
00163
00164
00165 const vnl_vector<double>& cam_params() const { return a_; }
00166
00167 const vnl_vector<double>& point_params() const { return b_; }
00168
00169
00170 bool optimize(vcl_vector<vpgl_perspective_camera<double> >& cameras,
00171 vcl_vector<vgl_point_3d<double> >& world_points,
00172 const vcl_vector<vgl_point_2d<double> >& image_points,
00173 const vcl_vector<vcl_vector<bool> >& mask);
00174
00175
00176 static void write_vrml(const vcl_string& filename,
00177 vcl_vector<vpgl_perspective_camera<double> >& cameras,
00178 vcl_vector<vgl_point_3d<double> >& world_points);
00179
00180 private:
00181
00182 vpgl_bundle_adj_lsqr* ba_func_;
00183
00184 vnl_vector<double> a_;
00185
00186 vnl_vector<double> b_;
00187
00188 bool use_weights_;
00189 bool use_gradient_;
00190
00191 double start_error_;
00192 double end_error_;
00193 int num_iterations_;
00194 };
00195
00196 #endif // vpgl_bundle_adjust_h_