40 #include <ceres/ceres.h>
42 #include <glog/logging.h>
45 #include "../optimization/cost_functors.h"
50 : T_(Matrix3d::Identity()), U_(Matrix4d::Identity()) {}
57 if (points_2d.size() != points_3d.size()) {
58 VLOG(1) <<
"Inputs 'points_2d' and 'points_3d' do not contain the "
59 "same number of elements.";
71 for (
size_t ii = 0; ii < points_2d.size(); ++ii) {
73 double u = points_2d[ii].u_;
74 double v = points_2d[ii].v_;
75 u =
T_(0, 0) * u +
T_(0, 2);
76 v =
T_(1, 1) * v +
T_(1, 2);
82 for (
size_t ii = 0; ii < points_3d.size(); ++ii) {
84 double x = points_3d[ii].X();
85 double y = points_3d[ii].Y();
86 double z = points_3d[ii].Z();
87 x =
U_(0, 0) * x +
U_(0, 3);
88 y =
U_(1, 1) * y +
U_(1, 3);
89 z =
U_(2, 2) * z +
U_(2, 3);
101 VLOG(1) <<
"Failed to compute an initial solution for P.";
109 VLOG(1) <<
"Failed to optimize P. Continuing using the initial solution.";
115 VLOG(1) <<
"Computed rotation is non-invertible.";
129 for (
size_t ii = 0; ii <
points_2d_.size(); ii++) {
172 A(2*ii+1, 10) = -u*z;
177 Eigen::JacobiSVD<Eigen::MatrixXd> svd;
178 svd.compute(A, Eigen::ComputeThinU | Eigen::ComputeFullV);
179 if (!svd.computeV()) {
180 VLOG(1) <<
"Failed to compute a singular value decomposition of A matrix.";
185 const VectorXd P_vec = svd.matrixV().col(11).normalized();
188 initial_solution.row(0) = P_vec.topRows(4).transpose();
189 initial_solution.row(1) = P_vec.middleRows(4, 4).transpose();
190 initial_solution.row(2) = P_vec.bottomRows(4).transpose();
197 ceres::Problem problem;
201 for (
size_t ii = 0; ii <
points_2d_.size(); ++ii) {
202 problem.AddResidualBlock(
205 optimized_solution.data());
209 ceres::Solver::Summary summary;
210 ceres::Solver::Options options;
211 options.trust_region_strategy_type = ceres::LEVENBERG_MARQUARDT;
212 ceres::Solve(options, &problem, &summary);
215 if (summary.IsSolutionUsable()) {
216 solution = optimized_solution.normalized();
219 return summary.IsSolutionUsable();
232 double det = Rt.block(0, 0, 3, 3).determinant();
233 if (std::abs(det) < 1e-16) {
234 LOG(WARNING) <<
"Computed rotation has a determinant of 0.";
245 Rt *= std::pow(1.0 / det, 1.0 / 3.0);
std::vector< Point3D > Point3DList
bool ExtractPose(const Matrix34d &P, Pose &pose)
bool OptimizeSolution(Matrix34d &solution)
bool Initialize(const FeatureList &points_2d, const Point3DList &points_3d, const CameraIntrinsics &intrinsics)
bool Solve(Pose &camera_pose)
Matrix3d ComputeNormalization(const FeatureMatchList &matched_features, bool use_feature_set1)
std::vector< Feature > FeatureList
static ceres::CostFunction * Create(const Feature &x, const Point3D &X)
CameraIntrinsics intrinsics_
::Eigen::Matrix< double, 3, 4 > Matrix34d
bool ComputeInitialSolution(Matrix34d &initial_solution)