| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #define TEST_NAME "base/generalized_absolute_pose" |
| | #include "util/testing.h" |
| |
|
| | #include <array> |
| |
|
| | #include <Eigen/Core> |
| |
|
| | #include "base/pose.h" |
| | #include "base/projection.h" |
| | #include "base/similarity_transform.h" |
| | #include "estimators/generalized_absolute_pose.h" |
| | #include "optim/ransac.h" |
| | #include "util/random.h" |
| |
|
| | using namespace colmap; |
| |
|
| | BOOST_AUTO_TEST_CASE(Estimate) { |
| | SetPRNGSeed(0); |
| |
|
| | std::vector<Eigen::Vector3d> points3D; |
| | points3D.emplace_back(1, 1, 1); |
| | points3D.emplace_back(0, 1, 1); |
| | points3D.emplace_back(3, 1.0, 4); |
| | points3D.emplace_back(3, 1.1, 4); |
| | points3D.emplace_back(3, 1.2, 4); |
| | points3D.emplace_back(3, 1.3, 4); |
| | points3D.emplace_back(3, 1.4, 4); |
| | points3D.emplace_back(2, 1, 7); |
| |
|
| | auto points3D_faulty = points3D; |
| | for (size_t i = 0; i < points3D.size(); ++i) { |
| | points3D_faulty[i](0) = 20; |
| | } |
| |
|
| | for (double qx = 0; qx < 1; qx += 0.2) { |
| | for (double tx = 0; tx < 1; tx += 0.1) { |
| | const int kRefTform = 1; |
| | const int kNumTforms = 3; |
| |
|
| | const std::array<SimilarityTransform3, kNumTforms> orig_tforms = {{ |
| | SimilarityTransform3(1, Eigen::Vector4d(1, qx, 0, 0), |
| | Eigen::Vector3d(tx, -0.1, 0)), |
| | SimilarityTransform3(1, Eigen::Vector4d(1, qx, 0, 0), |
| | Eigen::Vector3d(tx, 0, 0)), |
| | SimilarityTransform3(1, Eigen::Vector4d(1, qx, 0, 0), |
| | Eigen::Vector3d(tx, 0.1, 0)), |
| | }}; |
| |
|
| | std::array<Eigen::Matrix3x4d, kNumTforms> rel_tforms; |
| | for (size_t i = 0; i < kNumTforms; ++i) { |
| | Eigen::Vector4d rel_qvec; |
| | Eigen::Vector3d rel_tvec; |
| | ComputeRelativePose(orig_tforms[kRefTform].Rotation(), |
| | orig_tforms[kRefTform].Translation(), |
| | orig_tforms[i].Rotation(), |
| | orig_tforms[i].Translation(), &rel_qvec, &rel_tvec); |
| | rel_tforms[i] = ComposeProjectionMatrix(rel_qvec, rel_tvec); |
| | } |
| |
|
| | |
| | std::vector<GP3PEstimator::X_t> points2D; |
| | for (size_t i = 0; i < points3D.size(); ++i) { |
| | Eigen::Vector3d point3D_camera = points3D[i]; |
| | orig_tforms[i % kNumTforms].TransformPoint(&point3D_camera); |
| | points2D.emplace_back(); |
| | points2D.back().rel_tform = rel_tforms[i % kNumTforms]; |
| | points2D.back().xy = point3D_camera.hnormalized(); |
| | } |
| |
|
| | RANSACOptions options; |
| | options.max_error = 1e-5; |
| | RANSAC<GP3PEstimator> ransac(options); |
| | const auto report = ransac.Estimate(points2D, points3D); |
| |
|
| | BOOST_CHECK_EQUAL(report.success, true); |
| |
|
| | |
| | const double matrix_diff = |
| | (orig_tforms[kRefTform].Matrix().topLeftCorner<3, 4>() - report.model) |
| | .norm(); |
| | BOOST_CHECK(matrix_diff < 1e-2); |
| |
|
| | |
| | std::vector<double> residuals; |
| | ransac.estimator.Residuals(points2D, points3D, report.model, &residuals); |
| | for (size_t i = 0; i < residuals.size(); ++i) { |
| | BOOST_CHECK(residuals[i] < 1e-10); |
| | } |
| |
|
| | |
| | ransac.estimator.Residuals(points2D, points3D_faulty, report.model, |
| | &residuals); |
| | for (size_t i = 0; i < residuals.size(); ++i) { |
| | BOOST_CHECK(residuals[i] > 1e-10); |
| | } |
| | } |
| | } |
| | } |
| |
|