32 #define TEST_NAME "optim/bundle_adjustment"
41 #define CheckVariableCamera(camera, orig_camera) \
43 const size_t focal_length_idx = \
44 SimpleRadialCameraModel::focal_length_idxs[0]; \
45 const size_t extra_param_idx = \
46 SimpleRadialCameraModel::extra_params_idxs[0]; \
47 BOOST_CHECK_NE(camera.Params(focal_length_idx), \
48 orig_camera.Params(focal_length_idx)); \
49 BOOST_CHECK_NE(camera.Params(extra_param_idx), \
50 orig_camera.Params(extra_param_idx)); \
53 #define CheckConstantCamera(camera, orig_camera) \
55 const size_t focal_length_idx = \
56 SimpleRadialCameraModel::focal_length_idxs[0]; \
57 const size_t extra_param_idx = \
58 SimpleRadialCameraModel::extra_params_idxs[0]; \
59 BOOST_CHECK_EQUAL(camera.Params(focal_length_idx), \
60 orig_camera.Params(focal_length_idx)); \
61 BOOST_CHECK_EQUAL(camera.Params(extra_param_idx), \
62 orig_camera.Params(extra_param_idx)); \
65 #define CheckVariableImage(image, orig_image) \
67 BOOST_CHECK_NE(image.Qvec(), orig_image.Qvec()); \
68 BOOST_CHECK_NE(image.Tvec(), orig_image.Tvec()); \
71 #define CheckConstantImage(image, orig_image) \
73 BOOST_CHECK_EQUAL(image.Qvec(), orig_image.Qvec()); \
74 BOOST_CHECK_EQUAL(image.Tvec(), orig_image.Tvec()); \
77 #define CheckConstantXImage(image, orig_image) \
79 CheckVariableImage(image, orig_image); \
80 BOOST_CHECK_EQUAL(image.Tvec(0), orig_image.Tvec(0)); \
83 #define CheckConstantCameraRig(camera_rig, orig_camera_rig, camera_id) \
85 BOOST_CHECK_EQUAL(camera_rig.RelativeQvec(camera_id), \
86 orig_camera_rig.RelativeQvec(camera_id)); \
87 BOOST_CHECK_EQUAL(camera_rig.RelativeTvec(camera_id), \
88 orig_camera_rig.RelativeTvec(camera_id)); \
91 #define CheckVariableCameraRig(camera_rig, orig_camera_rig, camera_id) \
93 if (camera_rig.RefCameraId() == camera_id) { \
94 CheckConstantCameraRig(camera_rig, orig_camera_rig, camera_id); \
96 BOOST_CHECK_NE(camera_rig.RelativeQvec(camera_id), \
97 orig_camera_rig.RelativeQvec(camera_id)); \
98 BOOST_CHECK_NE(camera_rig.RelativeTvec(camera_id), \
99 orig_camera_rig.RelativeTvec(camera_id)); \
103 #define CheckVariablePoint(point, orig_point) \
104 { BOOST_CHECK_NE(point.XYZ(), orig_point.XYZ()); }
106 #define CheckConstantPoint(point, orig_point) \
107 { BOOST_CHECK_EQUAL(point.XYZ(), orig_point.XYZ()); }
112 const Eigen::Vector3d& max,
114 for (
size_t i = 0; i < num_points; ++i) {
129 Eigen::Vector3d(1, 1, 1), reconstruction);
131 const double kFocalLengthFactor = 1.2;
132 const size_t kImageSize = 1000;
134 for (
size_t i = 0; i < num_images; ++i) {
140 kFocalLengthFactor * kImageSize, kImageSize,
146 image.SetImageId(image_id);
147 image.SetCameraId(camera_id);
152 image.SetRegistered(
true);
157 std::vector<Eigen::Vector2d> points2D;
158 for (
const auto& point3D : reconstruction->
Points3D()) {
161 Eigen::Vector2d point2D =
165 points2D.push_back(point2D);
168 correspondence_graph->
AddImage(image_id, num_points);
172 reconstruction->
SetUp(correspondence_graph);
174 for (
size_t i = 0; i < num_images; ++i) {
179 for (
const auto& point3D : reconstruction->
Points3D()) {
195 BOOST_CHECK_EQUAL(config.
NumResiduals(reconstruction), 400);
198 BOOST_CHECK_EQUAL(config.
NumResiduals(reconstruction), 404);
201 BOOST_CHECK_EQUAL(config.
NumResiduals(reconstruction), 408);
204 BOOST_CHECK_EQUAL(config.
NumResiduals(reconstruction), 604);
207 BOOST_CHECK_EQUAL(config.
NumResiduals(reconstruction), 800);
214 const auto orig_reconstruction = reconstruction;
224 BOOST_REQUIRE(bundle_adjuster.
Solve(&reconstruction));
226 const auto summary = bundle_adjuster.
Summary();
229 BOOST_CHECK_EQUAL(summary.num_residuals_reduced, 400);
233 BOOST_CHECK_EQUAL(summary.num_effective_parameters_reduced, 309);
241 for (
const auto& point3D : reconstruction.
Points3D()) {
243 orig_reconstruction.Point3D(point3D.first));
251 const auto orig_reconstruction = reconstruction;
262 BOOST_REQUIRE(bundle_adjuster.
Solve(&reconstruction));
264 const auto summary = bundle_adjuster.
Summary();
267 BOOST_CHECK_EQUAL(summary.num_residuals_reduced, 400);
270 BOOST_CHECK_EQUAL(summary.num_effective_parameters_reduced, 302);
278 for (
const auto& point3D : reconstruction.
Points3D()) {
280 orig_reconstruction.Point3D(point3D.first));
288 const auto variable_point3D_id =
292 const auto orig_reconstruction = reconstruction;
302 BOOST_REQUIRE(bundle_adjuster.
Solve(&reconstruction));
304 const auto summary = bundle_adjuster.
Summary();
307 BOOST_CHECK_EQUAL(summary.num_residuals_reduced, 400);
310 BOOST_CHECK_EQUAL(summary.num_effective_parameters_reduced, 7);
321 for (
const auto& point3D : reconstruction.
Points3D()) {
322 if (point3D.first == variable_point3D_id) {
324 orig_reconstruction.Point3D(point3D.first));
327 orig_reconstruction.Point3D(point3D.first));
338 const point3D_t add_variable_point3D_id =
340 const point3D_t add_constant_point3D_id =
344 const auto orig_reconstruction = reconstruction;
356 BOOST_REQUIRE(bundle_adjuster.
Solve(&reconstruction));
358 const auto summary = bundle_adjuster.
Summary();
364 BOOST_CHECK_EQUAL(summary.num_residuals_reduced, 402);
367 BOOST_CHECK_EQUAL(summary.num_effective_parameters_reduced, 10);
378 for (
const auto& point3D : reconstruction.
Points3D()) {
379 if (point3D.first == variable_point3D_id ||
380 point3D.first == add_variable_point3D_id) {
382 orig_reconstruction.Point3D(point3D.first));
385 orig_reconstruction.Point3D(point3D.first));
394 const auto orig_reconstruction = reconstruction;
396 const point3D_t constant_point3D_id1 = 1;
397 const point3D_t constant_point3D_id2 = 2;
409 BOOST_REQUIRE(bundle_adjuster.
Solve(&reconstruction));
411 const auto summary = bundle_adjuster.
Summary();
414 BOOST_CHECK_EQUAL(summary.num_residuals_reduced, 400);
417 BOOST_CHECK_EQUAL(summary.num_effective_parameters_reduced, 298);
425 for (
const auto& point3D : reconstruction.
Points3D()) {
426 if (point3D.first == constant_point3D_id1 ||
427 point3D.first == constant_point3D_id2) {
429 orig_reconstruction.Point3D(point3D.first));
432 orig_reconstruction.Point3D(point3D.first));
441 const auto orig_reconstruction = reconstruction;
452 BOOST_REQUIRE(bundle_adjuster.
Solve(&reconstruction));
454 const auto summary = bundle_adjuster.
Summary();
457 BOOST_CHECK_EQUAL(summary.num_residuals_reduced, 600);
462 BOOST_CHECK_EQUAL(summary.num_effective_parameters_reduced, 317);
473 for (
const auto& point3D : reconstruction.
Points3D()) {
475 orig_reconstruction.Point3D(point3D.first));
483 const auto orig_reconstruction = reconstruction;
494 BOOST_REQUIRE(bundle_adjuster.
Solve(&reconstruction));
496 const auto summary = bundle_adjuster.
Summary();
499 BOOST_CHECK_EQUAL(summary.num_residuals_reduced, 400);
503 BOOST_CHECK_EQUAL(summary.num_effective_parameters_reduced, 307);
511 const auto& camera0 = reconstruction.
Camera(0);
512 const auto& orig_camera0 = orig_reconstruction.
Camera(0);
513 BOOST_CHECK(camera0.Params(focal_length_idx) ==
514 orig_camera0.Params(focal_length_idx));
515 BOOST_CHECK(camera0.Params(extra_param_idx) !=
516 orig_camera0.Params(extra_param_idx));
518 const auto& camera1 = reconstruction.
Camera(1);
519 const auto& orig_camera1 = orig_reconstruction.
Camera(1);
520 BOOST_CHECK(camera1.Params(focal_length_idx) ==
521 orig_camera1.Params(focal_length_idx));
522 BOOST_CHECK(camera1.Params(extra_param_idx) !=
523 orig_camera1.Params(extra_param_idx));
525 for (
const auto& point3D : reconstruction.
Points3D()) {
527 orig_reconstruction.Point3D(point3D.first));
535 const auto orig_reconstruction = reconstruction;
546 BOOST_REQUIRE(bundle_adjuster.
Solve(&reconstruction));
548 const auto summary = bundle_adjuster.
Summary();
551 BOOST_CHECK_EQUAL(summary.num_residuals_reduced, 400);
555 BOOST_CHECK_EQUAL(summary.num_effective_parameters_reduced, 313);
561 const size_t principal_point_idx_x =
563 const size_t principal_point_idx_y =
567 const auto& camera0 = reconstruction.
Camera(0);
568 const auto& orig_camera0 = orig_reconstruction.
Camera(0);
569 BOOST_CHECK(camera0.Params(focal_length_idx) !=
570 orig_camera0.Params(focal_length_idx));
571 BOOST_CHECK(camera0.Params(principal_point_idx_x) !=
572 orig_camera0.Params(principal_point_idx_x));
573 BOOST_CHECK(camera0.Params(principal_point_idx_y) !=
574 orig_camera0.Params(principal_point_idx_y));
575 BOOST_CHECK(camera0.Params(extra_param_idx) !=
576 orig_camera0.Params(extra_param_idx));
578 const auto& camera1 = reconstruction.
Camera(1);
579 const auto& orig_camera1 = orig_reconstruction.
Camera(1);
580 BOOST_CHECK(camera1.Params(focal_length_idx) !=
581 orig_camera1.Params(focal_length_idx));
582 BOOST_CHECK(camera1.Params(principal_point_idx_x) !=
583 orig_camera1.Params(principal_point_idx_x));
584 BOOST_CHECK(camera1.Params(principal_point_idx_y) !=
585 orig_camera1.Params(principal_point_idx_y));
586 BOOST_CHECK(camera1.Params(extra_param_idx) !=
587 orig_camera1.Params(extra_param_idx));
589 for (
const auto& point3D : reconstruction.
Points3D()) {
591 orig_reconstruction.Point3D(point3D.first));
599 const auto orig_reconstruction = reconstruction;
610 BOOST_REQUIRE(bundle_adjuster.
Solve(&reconstruction));
612 const auto summary = bundle_adjuster.
Summary();
615 BOOST_CHECK_EQUAL(summary.num_residuals_reduced, 400);
619 BOOST_CHECK_EQUAL(summary.num_effective_parameters_reduced, 307);
627 const auto& camera0 = reconstruction.
Camera(0);
628 const auto& orig_camera0 = orig_reconstruction.
Camera(0);
629 BOOST_CHECK(camera0.Params(focal_length_idx) !=
630 orig_camera0.Params(focal_length_idx));
631 BOOST_CHECK(camera0.Params(extra_param_idx) ==
632 orig_camera0.Params(extra_param_idx));
634 const auto& camera1 = reconstruction.
Camera(1);
635 const auto& orig_camera1 = orig_reconstruction.
Camera(1);
636 BOOST_CHECK(camera1.Params(focal_length_idx) !=
637 orig_camera1.Params(focal_length_idx));
638 BOOST_CHECK(camera1.Params(extra_param_idx) ==
639 orig_camera1.Params(extra_param_idx));
641 for (
const auto& point3D : reconstruction.
Points3D()) {
643 orig_reconstruction.Point3D(point3D.first));
656 BOOST_CHECK(ParallelBundleAdjuster::IsSupported(options, reconstruction));
659 BOOST_CHECK(!ParallelBundleAdjuster::IsSupported(options, reconstruction));
662 BOOST_CHECK(ParallelBundleAdjuster::IsSupported(options, reconstruction));
665 BOOST_CHECK(!ParallelBundleAdjuster::IsSupported(options, reconstruction));
669 BOOST_CHECK(!ParallelBundleAdjuster::IsSupported(options, reconstruction));
672 BOOST_CHECK(ParallelBundleAdjuster::IsSupported(options, reconstruction));
675 BOOST_CHECK(!ParallelBundleAdjuster::IsSupported(options, reconstruction));
682 const auto orig_reconstruction = reconstruction;
688 ParallelBundleAdjuster::Options options;
693 ParallelBundleAdjuster bundle_adjuster(options, ba_options, config);
694 BOOST_REQUIRE(bundle_adjuster.Solve(&reconstruction));
696 const auto summary = bundle_adjuster.Summary();
699 BOOST_CHECK_EQUAL(summary.num_residuals_reduced, 400);
703 BOOST_CHECK_EQUAL(summary.num_effective_parameters_reduced, 316);
711 for (
const auto& point3D : reconstruction.
Points3D()) {
713 orig_reconstruction.Point3D(point3D.first));
721 const auto orig_reconstruction = reconstruction;
727 ParallelBundleAdjuster::Options options;
732 ParallelBundleAdjuster bundle_adjuster(options, ba_options, config);
733 BOOST_REQUIRE(bundle_adjuster.Solve(&reconstruction));
735 const auto summary = bundle_adjuster.Summary();
738 BOOST_CHECK_EQUAL(summary.num_residuals_reduced, 400);
742 BOOST_CHECK_EQUAL(summary.num_effective_parameters_reduced, 316);
750 for (
const auto& point3D : reconstruction.
Points3D()) {
752 orig_reconstruction.Point3D(point3D.first));
761 const auto orig_reconstruction = reconstruction;
767 std::vector<CameraRig> camera_rigs;
768 camera_rigs.emplace_back();
770 Eigen::Vector3d(0, 0, 0));
772 Eigen::Vector3d(0, 0, 0));
773 camera_rigs[0].AddSnapshot({0, 1});
774 camera_rigs[0].SetRefCameraId(0);
775 const auto orig_camera_rigs = camera_rigs;
780 BOOST_REQUIRE(bundle_adjuster.
Solve(&reconstruction, &camera_rigs));
782 const auto summary = bundle_adjuster.
Summary();
785 BOOST_CHECK_EQUAL(summary.num_residuals_reduced, 400);
790 BOOST_CHECK_EQUAL(summary.num_effective_parameters_reduced, 316);
801 for (
const auto& point3D : reconstruction.
Points3D()) {
803 orig_reconstruction.Point3D(point3D.first));
813 const auto orig_reconstruction = reconstruction;
821 std::vector<CameraRig> camera_rigs;
822 camera_rigs.emplace_back();
824 Eigen::Vector3d(0, 0, 0));
826 Eigen::Vector3d(0, 0, 0));
827 camera_rigs[0].AddSnapshot({0, 1});
828 camera_rigs[0].AddSnapshot({2, 3});
829 camera_rigs[0].SetRefCameraId(0);
830 const auto orig_camera_rigs = camera_rigs;
835 BOOST_REQUIRE(bundle_adjuster.
Solve(&reconstruction, &camera_rigs));
837 const auto summary = bundle_adjuster.
Summary();
840 BOOST_CHECK_EQUAL(summary.num_residuals_reduced, 800);
845 BOOST_CHECK_EQUAL(summary.num_effective_parameters_reduced, 322);
856 for (
const auto& point3D : reconstruction.
Points3D()) {
858 orig_reconstruction.Point3D(point3D.first));
868 const auto orig_reconstruction = reconstruction;
876 std::vector<CameraRig> camera_rigs;
877 camera_rigs.emplace_back();
879 Eigen::Vector3d(0, 0, 0));
881 Eigen::Vector3d(0, 0, 0));
882 camera_rigs[0].AddSnapshot({0, 1});
883 camera_rigs[0].AddSnapshot({2, 3});
884 camera_rigs[0].SetRefCameraId(0);
885 const auto orig_camera_rigs = camera_rigs;
891 BOOST_REQUIRE(bundle_adjuster.
Solve(&reconstruction, &camera_rigs));
893 const auto summary = bundle_adjuster.
Summary();
896 BOOST_CHECK_EQUAL(summary.num_residuals_reduced, 800);
900 BOOST_CHECK_EQUAL(summary.num_effective_parameters_reduced, 316);
911 for (
const auto& point3D : reconstruction.
Points3D()) {
913 orig_reconstruction.Point3D(point3D.first));
923 const auto orig_reconstruction = reconstruction;
931 std::vector<CameraRig> camera_rigs;
932 camera_rigs.emplace_back();
934 Eigen::Vector3d(0, 0, 0));
936 Eigen::Vector3d(0, 0, 0));
937 camera_rigs[0].AddSnapshot({0, 1});
938 camera_rigs[0].AddSnapshot({2});
939 camera_rigs[0].SetRefCameraId(0);
940 const auto orig_camera_rigs = camera_rigs;
945 BOOST_REQUIRE(bundle_adjuster.
Solve(&reconstruction, &camera_rigs));
947 const auto summary = bundle_adjuster.
Summary();
950 BOOST_CHECK_EQUAL(summary.num_residuals_reduced, 800);
956 BOOST_CHECK_EQUAL(summary.num_effective_parameters_reduced, 328);
967 for (
const auto& point3D : reconstruction.
Points3D()) {
969 orig_reconstruction.Point3D(point3D.first));
std::shared_ptr< core::Tensor > image
#define CheckConstantImage(image, orig_image)
#define CheckVariableCamera(camera, orig_camera)
#define CheckVariableCameraRig(camera_rig, orig_camera_rig, camera_id)
#define CheckConstantXImage(image, orig_image)
#define CheckConstantPoint(point, orig_point)
#define CheckConstantCamera(camera, orig_camera)
#define CheckConstantCameraRig(camera_rig, orig_camera_rig, camera_id)
BOOST_AUTO_TEST_CASE(TestConfigNumObservations)
void GenerateReconstruction(const size_t num_images, const size_t num_points, Reconstruction *reconstruction, CorrespondenceGraph *correspondence_graph)
void GeneratePointCloud(const size_t num_points, const Eigen::Vector3d &min, const Eigen::Vector3d &max, Reconstruction *reconstruction)
#define CheckVariableImage(image, orig_image)
#define CheckVariablePoint(point, orig_point)
const ceres::Solver::Summary & Summary() const
bool Solve(Reconstruction *reconstruction)
void AddVariablePoint(const point3D_t point3D_id)
void SetConstantCamera(const camera_t camera_id)
void SetConstantPose(const image_t image_id)
void AddImage(const image_t image_id)
void SetConstantTvec(const image_t image_id, const std::vector< int > &idxs)
void AddConstantPoint(const point3D_t point3D_id)
size_t NumResiduals(const Reconstruction &reconstruction) const
void InitializeWithId(const int model_id, const double focal_length, const size_t width, const size_t height)
void SetModelIdFromName(const std::string &model_name)
void SetCameraId(const camera_t camera_id)
void AddImage(const image_t image_id, const size_t num_points2D)
void SetPoints2D(const std::vector< Eigen::Vector2d > &points)
void SetCameraId(const camera_t camera_id)
const class Point2D & Point2D(const point2D_t point2D_idx) const
point3D_t Point3DId() const
void AddImage(const class Image &image)
void AddCamera(const class Camera &camera)
void DeleteObservation(const image_t image_id, const point2D_t point2D_idx)
const class Image & Image(const image_t image_id) const
const class Camera & Camera(const camera_t camera_id) const
const std::unordered_map< point3D_t, class Point3D > & Points3D() const
void AddObservation(const point3D_t point3D_id, const TrackElement &track_el)
point3D_t AddPoint3D(const Eigen::Vector3d &xyz, const Track &track, const Eigen::Vector3ub &color=Eigen::Vector3ub::Zero())
void SetUp(const CorrespondenceGraph *correspondence_graph)
bool Solve(Reconstruction *reconstruction, std::vector< CameraRig > *camera_rigs)
Matrix< double, 3, 4 > Matrix3x4d
bool HasPointPositiveDepth(const Eigen::Matrix3x4d &proj_matrix, const Eigen::Vector3d &point3D)
void SetPRNGSeed(unsigned seed)
Eigen::Vector4d ComposeIdentityQuaternion()
T RandomReal(const T min, const T max)
Eigen::Vector2d ProjectPointToImage(const Eigen::Vector3d &point3D, const Eigen::Matrix3x4d &proj_matrix, const Camera &camera)
std::string to_string(const T &n)
bool refine_principal_point
bool refine_relative_poses
static const std::vector< size_t > principal_point_idxs
static const std::vector< size_t > focal_length_idxs
static const std::vector< size_t > extra_params_idxs
static const int model_id