40 #include <glog/logging.h>
42 #include "../optimization/cost_functors.h"
50 const std::vector<ViewIndex>& view_indices)
const {
52 ceres::Problem problem;
58 std::vector<Vector3d> rotations(view_indices.size());
59 std::vector<Vector3d> translations(view_indices.size());
61 for (
size_t ii = 0; ii < view_indices.size(); ++ii) {
63 if (view ==
nullptr) {
64 LOG(WARNING) <<
"View is null. Cannot perform bundle adjustment.";
69 rotations[ii] = view->Camera().AxisAngleRotation();
70 translations[ii] = view->Camera().Translation();
73 Matrix3d K = view->Camera().K();
77 const std::vector<Observation::Ptr> observations = view->Observations();
78 for (
size_t jj = 0; jj < observations.size(); ++jj) {
79 CHECK_NOTNULL(observations[jj].
get());
80 if (!observations[jj]->IsIncorporated())
84 if (landmark ==
nullptr) {
85 LOG(WARNING) <<
"Landmark is null. Cannot perform bundle adjustment.";
91 if (!landmark->SeenByAtLeastTwoViews(view_indices))
95 problem.AddResidualBlock(
99 translations[ii].data(),
100 landmark->PositionData());
105 ceres::Solver::Options ceres_options;
107 LOG(WARNING) <<
"Bundle adjustment options are not valid.";
110 ceres::Solver::Summary summary;
111 ceres::Solve(ceres_options, &problem, &summary);
115 std::cout << summary.FullReport() << std::endl;
119 for (
size_t ii = 0; ii < view_indices.size(); ++ii) {
125 view->MutableCamera().MutableExtrinsics().SetWorldToCamera(pose);
126 view->MutableCamera().MutableExtrinsics().SetTranslation(translations[ii]);
129 return summary.IsSolutionUsable();
134 ceres::Solver::Options* ceres_options)
const {
135 CHECK_NOTNULL(ceres_options);
138 ceres_options->trust_region_strategy_type = ceres::LEVENBERG_MARQUARDT;
142 ceres_options->linear_solver_type = ceres::DENSE_QR;
143 }
else if (options.
solver_type.compare(
"DENSE_NORMAL_CHOLESKY")==0) {
144 ceres_options->linear_solver_type = ceres::DENSE_NORMAL_CHOLESKY;
145 }
else if (options.
solver_type.compare(
"SPARSE_NORMAL_CHOLESKY")==0) {
146 ceres_options->linear_solver_type = ceres::SPARSE_NORMAL_CHOLESKY;
147 }
else if (options.
solver_type.compare(
"CGNR")==0) {
148 ceres_options->linear_solver_type = ceres::CGNR;
149 }
else if (options.
solver_type.compare(
"DENSE_SCHUR")==0) {
150 ceres_options->linear_solver_type = ceres::DENSE_SCHUR;
151 }
else if (options.
solver_type.compare(
"SPARSE_SCHUR")==0) {
152 ceres_options->linear_solver_type = ceres::SPARSE_SCHUR;
153 }
else if (options.
solver_type.compare(
"ITERATIVE_SCHUR")==0) {
154 ceres_options->linear_solver_type = ceres::ITERATIVE_SCHUR;
156 ceres_options->linear_solver_type = ceres::SPARSE_SCHUR;
161 ceres_options->logging_type = ceres::PER_MINIMIZER_ITERATION;
162 ceres_options->minimizer_progress_to_stdout =
true;
164 ceres_options->logging_type = ceres::SILENT;
165 ceres_options->minimizer_progress_to_stdout =
false;
173 std::string error_message;
174 bool valid_options = ceres_options->IsValid(&error_message);
175 if (!valid_options) {
176 LOG(WARNING) <<
"Ceres options error: " << error_message;
178 return valid_options;
bool Solve(const BundleAdjustmentOptions &options, const std::vector< ViewIndex > &view_indices) const
static ceres::CostFunction * Create(const Feature &x, const Matrix3d &K)
static View::Ptr GetView(ViewIndex view_index)
std::shared_ptr< Landmark > Ptr
std::shared_ptr< View > Ptr
Matrix4d FromAxisAngle(const Vector3d &aa)
double gradient_tolerance
double function_tolerance
bool ConvertOptionsToCeresOptions(const BundleAdjustmentOptions &options, ceres::Solver::Options *ceres_options) const