| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #ifndef COLMAP_SRC_OPTIM_BUNDLE_ADJUSTMENT_H_ |
| | #define COLMAP_SRC_OPTIM_BUNDLE_ADJUSTMENT_H_ |
| |
|
| | #include <memory> |
| | #include <unordered_set> |
| |
|
| | #include <Eigen/Core> |
| |
|
| | #include <ceres/ceres.h> |
| |
|
| | #include "PBA/pba.h" |
| | #include "base/camera_rig.h" |
| | #include "base/reconstruction.h" |
| | #include "util/alignment.h" |
| |
|
| | namespace colmap { |
| |
|
| | struct BundleAdjustmentOptions { |
| | |
| | enum class LossFunctionType { TRIVIAL, SOFT_L1, CAUCHY }; |
| | LossFunctionType loss_function_type = LossFunctionType::TRIVIAL; |
| |
|
| | |
| | double loss_function_scale = 1.0; |
| |
|
| | |
| | bool refine_focal_length = true; |
| |
|
| | |
| | bool refine_principal_point = false; |
| |
|
| | |
| | bool refine_extra_params = true; |
| |
|
| | |
| | bool refine_extrinsics = true; |
| |
|
| | |
| | bool print_summary = true; |
| |
|
| | |
| | |
| | |
| | int min_num_residuals_for_multi_threading = 50000; |
| |
|
| | |
| | ceres::Solver::Options solver_options; |
| |
|
| | BundleAdjustmentOptions() { |
| | solver_options.function_tolerance = 0.0; |
| | solver_options.gradient_tolerance = 0.0; |
| | solver_options.parameter_tolerance = 0.0; |
| | solver_options.minimizer_progress_to_stdout = false; |
| | solver_options.max_num_iterations = 100; |
| | solver_options.max_linear_solver_iterations = 200; |
| | solver_options.max_num_consecutive_invalid_steps = 10; |
| | solver_options.max_consecutive_nonmonotonic_steps = 10; |
| | solver_options.num_threads = -1; |
| | #if CERES_VERSION_MAJOR < 2 |
| | solver_options.num_linear_solver_threads = -1; |
| | #endif |
| | } |
| |
|
| | |
| | |
| | ceres::LossFunction* CreateLossFunction() const; |
| |
|
| | bool Check() const; |
| | }; |
| |
|
| | |
| | class BundleAdjustmentConfig { |
| | public: |
| | BundleAdjustmentConfig(); |
| |
|
| | size_t NumImages() const; |
| | size_t NumPoints() const; |
| | size_t NumConstantCameras() const; |
| | size_t NumConstantPoses() const; |
| | size_t NumConstantTvecs() const; |
| | size_t NumVariablePoints() const; |
| | size_t NumConstantPoints() const; |
| |
|
| | |
| | |
| | size_t NumResiduals(const Reconstruction& reconstruction) const; |
| |
|
| | |
| | void AddImage(const image_t image_id); |
| | bool HasImage(const image_t image_id) const; |
| | void RemoveImage(const image_t image_id); |
| |
|
| | |
| | |
| | |
| | void SetConstantCamera(const camera_t camera_id); |
| | void SetVariableCamera(const camera_t camera_id); |
| | bool IsConstantCamera(const camera_t camera_id) const; |
| |
|
| | |
| | |
| | void SetConstantPose(const image_t image_id); |
| | void SetVariablePose(const image_t image_id); |
| | bool HasConstantPose(const image_t image_id) const; |
| |
|
| | |
| | |
| | |
| | void SetConstantTvec(const image_t image_id, const std::vector<int>& idxs); |
| | void RemoveConstantTvec(const image_t image_id); |
| | bool HasConstantTvec(const image_t image_id) const; |
| |
|
| | |
| | |
| | void AddVariablePoint(const point3D_t point3D_id); |
| | void AddConstantPoint(const point3D_t point3D_id); |
| | bool HasPoint(const point3D_t point3D_id) const; |
| | bool HasVariablePoint(const point3D_t point3D_id) const; |
| | bool HasConstantPoint(const point3D_t point3D_id) const; |
| | void RemoveVariablePoint(const point3D_t point3D_id); |
| | void RemoveConstantPoint(const point3D_t point3D_id); |
| |
|
| | |
| | const std::unordered_set<image_t>& Images() const; |
| | const std::unordered_set<point3D_t>& VariablePoints() const; |
| | const std::unordered_set<point3D_t>& ConstantPoints() const; |
| | const std::vector<int>& ConstantTvec(const image_t image_id) const; |
| |
|
| | private: |
| | std::unordered_set<camera_t> constant_camera_ids_; |
| | std::unordered_set<image_t> image_ids_; |
| | std::unordered_set<point3D_t> variable_point3D_ids_; |
| | std::unordered_set<point3D_t> constant_point3D_ids_; |
| | std::unordered_set<image_t> constant_poses_; |
| | std::unordered_map<image_t, std::vector<int>> constant_tvecs_; |
| | }; |
| |
|
| | |
| | |
| | class BundleAdjuster { |
| | public: |
| | BundleAdjuster(const BundleAdjustmentOptions& options, |
| | const BundleAdjustmentConfig& config); |
| |
|
| | bool Solve(Reconstruction* reconstruction); |
| |
|
| | |
| | const ceres::Solver::Summary& Summary() const; |
| |
|
| | private: |
| | void SetUp(Reconstruction* reconstruction, |
| | ceres::LossFunction* loss_function); |
| | void TearDown(Reconstruction* reconstruction); |
| |
|
| | void AddImageToProblem(const image_t image_id, Reconstruction* reconstruction, |
| | ceres::LossFunction* loss_function); |
| |
|
| | void AddPointToProblem(const point3D_t point3D_id, |
| | Reconstruction* reconstruction, |
| | ceres::LossFunction* loss_function); |
| |
|
| | protected: |
| | void ParameterizeCameras(Reconstruction* reconstruction); |
| | void ParameterizePoints(Reconstruction* reconstruction); |
| |
|
| | const BundleAdjustmentOptions options_; |
| | BundleAdjustmentConfig config_; |
| | std::unique_ptr<ceres::Problem> problem_; |
| | ceres::Solver::Summary summary_; |
| | std::unordered_set<camera_t> camera_ids_; |
| | std::unordered_map<point3D_t, size_t> point3D_num_observations_; |
| | }; |
| |
|
| | |
| | |
| | |
| | class ParallelBundleAdjuster { |
| | public: |
| | struct Options { |
| | |
| | bool print_summary = true; |
| |
|
| | |
| | int max_num_iterations = 50; |
| |
|
| | |
| | int gpu_index = -1; |
| |
|
| | |
| | int num_threads = -1; |
| |
|
| | |
| | |
| | |
| | int min_num_residuals_for_multi_threading = 50000; |
| |
|
| | bool Check() const; |
| | }; |
| |
|
| | ParallelBundleAdjuster(const Options& options, |
| | const BundleAdjustmentOptions& ba_options, |
| | const BundleAdjustmentConfig& config); |
| |
|
| | bool Solve(Reconstruction* reconstruction); |
| |
|
| | |
| | const ceres::Solver::Summary& Summary() const; |
| |
|
| | |
| | |
| | static bool IsSupported(const BundleAdjustmentOptions& options, |
| | const Reconstruction& reconstruction); |
| |
|
| | private: |
| | void SetUp(Reconstruction* reconstruction); |
| | void TearDown(Reconstruction* reconstruction); |
| |
|
| | void AddImagesToProblem(Reconstruction* reconstruction); |
| | void AddPointsToProblem(Reconstruction* reconstruction); |
| |
|
| | const Options options_; |
| | const BundleAdjustmentOptions ba_options_; |
| | BundleAdjustmentConfig config_; |
| | ceres::Solver::Summary summary_; |
| |
|
| | size_t num_measurements_; |
| | std::vector<pba::CameraT> cameras_; |
| | std::vector<pba::Point3D> points3D_; |
| | std::vector<pba::Point2D> measurements_; |
| | std::unordered_set<camera_t> camera_ids_; |
| | std::unordered_set<point3D_t> point3D_ids_; |
| | std::vector<int> camera_idxs_; |
| | std::vector<int> point3D_idxs_; |
| | std::vector<image_t> ordered_image_ids_; |
| | std::vector<point3D_t> ordered_point3D_ids_; |
| | std::unordered_map<image_t, int> image_id_to_camera_idx_; |
| | }; |
| |
|
| | class RigBundleAdjuster : public BundleAdjuster { |
| | public: |
| | struct Options { |
| | |
| | bool refine_relative_poses = true; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | double max_reproj_error = 1000.0; |
| | }; |
| |
|
| | RigBundleAdjuster(const BundleAdjustmentOptions& options, |
| | const Options& rig_options, |
| | const BundleAdjustmentConfig& config); |
| |
|
| | bool Solve(Reconstruction* reconstruction, |
| | std::vector<CameraRig>* camera_rigs); |
| |
|
| | private: |
| | void SetUp(Reconstruction* reconstruction, |
| | std::vector<CameraRig>* camera_rigs, |
| | ceres::LossFunction* loss_function); |
| | void TearDown(Reconstruction* reconstruction, |
| | const std::vector<CameraRig>& camera_rigs); |
| |
|
| | void AddImageToProblem(const image_t image_id, Reconstruction* reconstruction, |
| | std::vector<CameraRig>* camera_rigs, |
| | ceres::LossFunction* loss_function); |
| |
|
| | void AddPointToProblem(const point3D_t point3D_id, |
| | Reconstruction* reconstruction, |
| | ceres::LossFunction* loss_function); |
| |
|
| | void ComputeCameraRigPoses(const Reconstruction& reconstruction, |
| | const std::vector<CameraRig>& camera_rigs); |
| |
|
| | void ParameterizeCameraRigs(Reconstruction* reconstruction); |
| |
|
| | const Options rig_options_; |
| |
|
| | |
| | std::unordered_map<image_t, CameraRig*> image_id_to_camera_rig_; |
| |
|
| | |
| | std::unordered_map<image_t, Eigen::Vector4d*> image_id_to_rig_qvec_; |
| | std::unordered_map<image_t, Eigen::Vector3d*> image_id_to_rig_tvec_; |
| |
|
| | |
| | std::vector<std::vector<Eigen::Vector4d>> camera_rig_qvecs_; |
| | std::vector<std::vector<Eigen::Vector3d>> camera_rig_tvecs_; |
| |
|
| | |
| | |
| | std::unordered_set<double*> parameterized_qvec_data_; |
| | }; |
| |
|
| | void PrintSolverSummary(const ceres::Solver::Summary& summary); |
| |
|
| | } |
| |
|
| | #endif |
| |
|