|
7 | 7 |
|
8 | 8 | #include <aliceVision/sfm/bundle/BundleAdjustmentCeres.hpp> |
9 | 9 | #include <aliceVision/sfm/bundle/costfunctions/constraint2d.hpp> |
| 10 | +#include <aliceVision/sfm/bundle/costfunctions/constraintPoint.hpp> |
10 | 11 | #include <aliceVision/sfm/bundle/costfunctions/projection.hpp> |
11 | 12 | #include <aliceVision/sfm/bundle/costfunctions/rotationPrior.hpp> |
12 | 13 | #include <aliceVision/sfm/bundle/manifolds/intrinsics.hpp> |
@@ -86,6 +87,17 @@ ceres::CostFunction* createConstraintsCostFunctionFromIntrinsics(std::shared_ptr |
86 | 87 | return costFunction; |
87 | 88 | } |
88 | 89 |
|
| 90 | +ceres::CostFunction* createCostFunctionFromContraintPoint(const sfmData::Landmark & landmark, const Vec3 & normal) |
| 91 | +{ |
| 92 | + const double weight = 100.0; |
| 93 | + auto costFunction = new ceres::DynamicAutoDiffCostFunction<ConstraintPointErrorFunctor>(new ConstraintPointErrorFunctor(weight, normal, landmark.X)); |
| 94 | + |
| 95 | + costFunction->AddParameterBlock(3); |
| 96 | + costFunction->SetNumResiduals(1); |
| 97 | + |
| 98 | + return costFunction; |
| 99 | +} |
| 100 | + |
89 | 101 | void BundleAdjustmentCeres::CeresOptions::setDenseBA() |
90 | 102 | { |
91 | 103 | // default configuration use a DENSE representation |
@@ -671,6 +683,33 @@ void BundleAdjustmentCeres::addConstraints2DToProblem(const sfmData::SfMData& sf |
671 | 683 | } |
672 | 684 | } |
673 | 685 |
|
| 686 | +void BundleAdjustmentCeres::addConstraintsPointToProblem(const sfmData::SfMData& sfmData, ERefineOptions refineOptions, ceres::Problem& problem) |
| 687 | +{ |
| 688 | + // set a LossFunction to be less penalized by false measurements. |
| 689 | + // note: set it to NULL if you don't want use a lossFunction. |
| 690 | + ceres::LossFunction* lossFunction = _ceresOptions.lossFunction.get(); |
| 691 | + |
| 692 | + for (const auto& [landmarkId, constraint] : sfmData.getConstraintsPoint()) |
| 693 | + { |
| 694 | + if (sfmData.getLandmarks().find(landmarkId) == sfmData.getLandmarks().end()) |
| 695 | + { |
| 696 | + continue; |
| 697 | + } |
| 698 | + |
| 699 | + if (_landmarksBlocks.find(landmarkId) == _landmarksBlocks.end()) |
| 700 | + { |
| 701 | + continue; |
| 702 | + } |
| 703 | + |
| 704 | + const sfmData::Landmark & l = sfmData.getLandmarks().at(landmarkId); |
| 705 | + double * ldata = _landmarksBlocks.at(landmarkId).data(); |
| 706 | + |
| 707 | + ceres::CostFunction* costFunction = createCostFunctionFromContraintPoint(l, constraint.normal); |
| 708 | + |
| 709 | + problem.AddResidualBlock(costFunction, lossFunction, ldata); |
| 710 | + } |
| 711 | +} |
| 712 | + |
674 | 713 | void BundleAdjustmentCeres::addRotationPriorsToProblem(const sfmData::SfMData& sfmData, ERefineOptions refineOptions, ceres::Problem& problem) |
675 | 714 | { |
676 | 715 | // set a LossFunction to be less penalized by false measurements. |
@@ -718,6 +757,9 @@ void BundleAdjustmentCeres::createProblem(const sfmData::SfMData& sfmData, ERefi |
718 | 757 | // add 2D constraints to the Ceres problem |
719 | 758 | addConstraints2DToProblem(sfmData, refineOptions, problem); |
720 | 759 |
|
| 760 | + // add 2D constraints to the Ceres problem |
| 761 | + addConstraintsPointToProblem(sfmData, refineOptions, problem); |
| 762 | + |
721 | 763 | // add rotation priors to the Ceres problem |
722 | 764 | addRotationPriorsToProblem(sfmData, refineOptions, problem); |
723 | 765 | } |
|
0 commit comments