@@ -60,6 +60,31 @@ ceres::CostFunction* createCostFunctionFromIntrinsics(const std::shared_ptr<Intr
6060 return costFunction;
6161}
6262
63+ ceres::CostFunction* createSurveyPointCostFunction (const std::shared_ptr<IntrinsicBase> intrinsic,
64+ const Vec3 & point,
65+ const sfmData::Observation& observation)
66+ {
67+ auto costFunction = new ceres::DynamicAutoDiffCostFunction<ProjectionSurveyErrorFunctor>(new ProjectionSurveyErrorFunctor (point, observation, intrinsic));
68+
69+ int distortionSize = 1 ;
70+ auto isod = camera::IntrinsicScaleOffsetDisto::cast (intrinsic);
71+ if (isod)
72+ {
73+ auto distortion = isod->getDistortion ();
74+ if (distortion)
75+ {
76+ distortionSize = distortion->getParameters ().size ();
77+ }
78+ }
79+
80+ costFunction->AddParameterBlock (intrinsic->getParameters ().size ());
81+ costFunction->AddParameterBlock (distortionSize);
82+ costFunction->AddParameterBlock (6 );
83+ costFunction->SetNumResiduals (2 );
84+
85+ return costFunction;
86+ }
87+
6388/* *
6489 * @brief Create the appropriate cost functor according the provided input rig camera intrinsic model
6590 * @param[in] intrinsicPtr The intrinsic pointer
@@ -723,6 +748,58 @@ void BundleAdjustmentCeres::addLandmarksToProblem(const sfmData::SfMData& sfmDat
723748 }
724749}
725750
751+ void BundleAdjustmentCeres::addSurveyPointsToProblem (const sfmData::SfMData& sfmData, ERefineOptions refineOptions, ceres::Problem& problem)
752+ {
753+
754+ // build the residual blocks corresponding to the track observations
755+ for (const auto & [idView, vspoints] : sfmData.getSurveyPoints ())
756+ {
757+ double * fakeDistortionBlockPtr = _fakeDistortionBlock.data ();
758+
759+ const sfmData::View& view = sfmData.getView (idView);
760+ const IndexT intrinsicId = view.getIntrinsicId ();
761+
762+ // each residual block takes a point and a camera as input and outputs a 2
763+ // dimensional residual. Internally, the cost function stores the observed
764+ // image location and compares the reprojection against the observation.
765+ const auto & pose = sfmData.getPose (view);
766+
767+ // needed parameters to create a residual block (K, pose)
768+ double * poseBlockPtr = _posesBlocks.at (view.getPoseId ()).data ();
769+ double * intrinsicBlockPtr = _intrinsicsBlocks.at (intrinsicId).data ();
770+ const std::shared_ptr<IntrinsicBase> intrinsic = _intrinsicObjects[intrinsicId];
771+
772+ double * distortionBlockPtr = fakeDistortionBlockPtr;
773+ if (_distortionsBlocks.find (intrinsicId) != _distortionsBlocks.end ())
774+ {
775+ distortionBlockPtr = _distortionsBlocks.at (intrinsicId).data ();
776+ }
777+
778+ // apply a specific parameter ordering:
779+ if (_ceresOptions.useParametersOrdering )
780+ {
781+ _linearSolverOrdering.AddElementToGroup (poseBlockPtr, 1 );
782+ _linearSolverOrdering.AddElementToGroup (intrinsicBlockPtr, 2 );
783+ _linearSolverOrdering.AddElementToGroup (distortionBlockPtr, 2 );
784+ }
785+
786+
787+ for (const auto & spoint: vspoints)
788+ {
789+ sfmData::Observation observation (spoint.survey , 0 , 1.0 );
790+ ceres::CostFunction* costFunction = createSurveyPointCostFunction (intrinsic, spoint.point3d , observation);
791+
792+
793+ std::vector<double *> params;
794+ params.push_back (intrinsicBlockPtr);
795+ params.push_back (distortionBlockPtr);
796+ params.push_back (poseBlockPtr);
797+
798+ problem.AddResidualBlock (costFunction, nullptr , params);
799+ }
800+ }
801+ }
802+
726803void BundleAdjustmentCeres::addConstraints2DToProblem (const sfmData::SfMData& sfmData, ERefineOptions refineOptions, ceres::Problem& problem)
727804{
728805 // set a LossFunction to be less penalized by false measurements.
@@ -845,6 +922,9 @@ void BundleAdjustmentCeres::createProblem(const sfmData::SfMData& sfmData, ERefi
845922 // add SfM landmarks to the Ceres problem
846923 addLandmarksToProblem (sfmData, refineOptions, problem);
847924
925+ // add SfM landmarks to the Ceres problem
926+ addSurveyPointsToProblem (sfmData, refineOptions, problem);
927+
848928 // add 2D constraints to the Ceres problem
849929 addConstraints2DToProblem (sfmData, refineOptions, problem);
850930
0 commit comments