Skip to content

Commit 9464137

Browse files
Fabien Servantcbentejac
authored andcommitted
add depth constraint to bundle
1 parent 81bcf53 commit 9464137

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

src/aliceVision/sfm/bundle/BundleAdjustmentCeres.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <aliceVision/sfm/bundle/costfunctions/constraintPoint.hpp>
1414
#include <aliceVision/sfm/bundle/costfunctions/projection.hpp>
1515
#include <aliceVision/sfm/bundle/costfunctions/rotationPrior.hpp>
16+
#include <aliceVision/sfm/bundle/costfunctions/depth.hpp>
1617
#include <aliceVision/sfm/bundle/manifolds/intrinsics.hpp>
1718
#include <aliceVision/sfmData/SfMData.hpp>
1819
#include <aliceVision/camera/camera.hpp>
@@ -617,6 +618,18 @@ void BundleAdjustmentCeres::addLandmarksToProblem(const sfmData::SfMData& sfmDat
617618
problem.AddResidualBlock(costFunction, lossFunction, params);
618619
}
619620

621+
if (observation.getDepth() > 0.0)
622+
{
623+
const double depthVariance = 0.1; //10 cm ?
624+
ceres::CostFunction* costFunction = DepthErrorFunctor::createCostFunction(observation, depthVariance);
625+
626+
std::vector<double*> params;
627+
params.push_back(poseBlockPtr);
628+
params.push_back(landmarkBlockPtr);
629+
630+
problem.AddResidualBlock(costFunction, nullptr, params);
631+
}
632+
620633
if (!refineStructure || landmark.state == EEstimatorParameterState::CONSTANT)
621634
{
622635
// set the whole landmark parameter block as constant.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// This file is part of the AliceVision project.
2+
// Copyright (c) 2025 AliceVision contributors.
3+
// This Source Code Form is subject to the terms of the Mozilla Public License,
4+
// v. 2.0. If a copy of the MPL was not distributed with this file,
5+
// You can obtain one at https://mozilla.org/MPL/2.0/.
6+
7+
#pragma once
8+
9+
#include <aliceVision/types.hpp>
10+
#include <ceres/rotation.h>
11+
12+
namespace aliceVision {
13+
namespace sfm {
14+
15+
/**
16+
* Compare the "measured" depth with the estimated point Z position in camera's space
17+
*/
18+
struct DepthErrorFunctor
19+
{
20+
explicit DepthErrorFunctor(double depth, double depthVariance)
21+
: _depth(depth), _depthVariance(depthVariance)
22+
{
23+
}
24+
25+
template<typename T>
26+
bool operator()(T const* const* parameters, T* residuals) const
27+
{
28+
const T* parameter_pose = parameters[0];
29+
const T* parameter_point = parameters[1];
30+
31+
//--
32+
// Apply external parameters (Pose)
33+
//--
34+
const T* cam_R = parameter_pose;
35+
const T* cam_t = &parameter_pose[3];
36+
37+
T transformedPoint[3];
38+
// Rotate the point according the camera rotation
39+
ceres::AngleAxisRotatePoint(cam_R, parameter_point, transformedPoint);
40+
41+
// Apply the camera translation
42+
transformedPoint[2] += cam_t[2];
43+
44+
residuals[0] = T(1.0 / _depthVariance) * (transformedPoint[2] - T(_depth));
45+
46+
return true;
47+
}
48+
49+
/**
50+
* @brief Create the appropriate cost function
51+
* @param[in] observation The corresponding observation
52+
* @return cost functor
53+
*/
54+
inline static ceres::CostFunction* createCostFunction(
55+
const sfmData::Observation& observation, double depthVariance)
56+
{
57+
auto costFunction = new ceres::DynamicAutoDiffCostFunction<DepthErrorFunctor>(new DepthErrorFunctor(observation.getDepth(), depthVariance));
58+
59+
costFunction->AddParameterBlock(6);
60+
costFunction->AddParameterBlock(3);
61+
costFunction->SetNumResiduals(1);
62+
63+
return costFunction;
64+
}
65+
66+
const double _depth;
67+
const double _depthVariance;
68+
};
69+
70+
} // namespace sfm
71+
} // namespace aliceVision

0 commit comments

Comments
 (0)