30#include <gtsam/slam/TriangulationFactor.h>
38 std::runtime_error(
"Triangulation Underconstrained Exception.") {
47 "Triangulation Cheirality Exception: The resulting landmark is behind one or more cameras.") {
59 const std::vector<Matrix34, Eigen::aligned_allocator<Matrix34>>& projection_matrices,
60 const Point2Vector& measurements,
double rank_tol = 1e-9);
70 const std::vector<Matrix34, Eigen::aligned_allocator<Matrix34>>& projection_matrices,
71 const Point2Vector& measurements,
72 double rank_tol = 1e-9);
83template<
class CALIBRATION>
85 const std::vector<Pose3>& poses, boost::shared_ptr<CALIBRATION> sharedCal,
86 const Point2Vector& measurements,
Key landmarkKey,
87 const Point3& initialEstimate) {
89 values.
insert(landmarkKey, initialEstimate);
93 for (
size_t i = 0; i < measurements.size(); i++) {
94 const Pose3& pose_i = poses[i];
96 Camera camera_i(pose_i, sharedCal);
98 (camera_i, measurements[i], unit2, landmarkKey);
100 return std::make_pair(graph, values);
112template<
class CAMERA>
115 const typename CAMERA::MeasurementVector& measurements,
Key landmarkKey,
116 const Point3& initialEstimate) {
118 values.
insert(landmarkKey, initialEstimate);
122 for (
size_t i = 0; i < measurements.size(); i++) {
123 const CAMERA& camera_i = cameras[i];
125 (camera_i, measurements[i], unit, landmarkKey);
127 return std::make_pair(graph, values);
138 const Values& values,
Key landmarkKey);
148template<
class CALIBRATION>
150 boost::shared_ptr<CALIBRATION> sharedCal,
151 const Point2Vector& measurements,
const Point3& initialEstimate) {
156 boost::tie(graph, values) = triangulationGraph<CALIBRATION>
157 (poses, sharedCal, measurements,
Symbol(
'p', 0), initialEstimate);
169template<
class CAMERA>
172 const typename CAMERA::MeasurementVector& measurements,
const Point3& initialEstimate) {
177 boost::tie(graph, values) = triangulationGraph<CAMERA>
178 (cameras, measurements,
Symbol(
'p', 0), initialEstimate);
190template<
class CALIBRATION>
193 K_(calibration.K()) {
195 Matrix34 operator()(
const Pose3& pose)
const {
216template<
class CALIBRATION>
218 boost::shared_ptr<CALIBRATION> sharedCal,
219 const Point2Vector& measurements,
double rank_tol = 1e-9,
222 assert(poses.size() == measurements.size());
223 if (poses.size() < 2)
227 std::vector<Matrix34, Eigen::aligned_allocator<Matrix34>> projection_matrices;
229 for(
const Pose3& pose: poses)
230 projection_matrices.push_back(createP(pose));
237 point = triangulateNonlinear<CALIBRATION>
238 (poses, sharedCal, measurements, point);
240#ifdef GTSAM_THROW_CHEIRALITY_EXCEPTION
242 for(
const Pose3& pose: poses) {
243 const Point3& p_local = pose.transformTo(point);
244 if (p_local.z() <= 0)
264template<
class CAMERA>
267 const typename CAMERA::MeasurementVector& measurements,
double rank_tol = 1e-9,
270 size_t m = cameras.size();
271 assert(measurements.size() == m);
277 std::vector<Matrix34, Eigen::aligned_allocator<Matrix34>> projection_matrices;
278 for(
const CAMERA& camera: cameras)
279 projection_matrices.push_back(
286 point = triangulateNonlinear<CAMERA>(cameras, measurements, point);
288#ifdef GTSAM_THROW_CHEIRALITY_EXCEPTION
290 for(
const CAMERA& camera: cameras) {
291 const Point3& p_local = camera.pose().transformTo(point);
292 if (p_local.z() <= 0)
301template<
class CALIBRATION>
304 const Point2Vector& measurements,
double rank_tol = 1e-9,
306 return triangulatePoint3<PinholeCamera<CALIBRATION> >
307 (cameras, measurements, rank_tol,
optimize);
338 const bool _enableEPI =
false,
double _landmarkDistanceThreshold = -1,
339 double _dynamicOutlierRejectionThreshold = -1) :
340 rankTolerance(_rankTolerance), enableEPI(_enableEPI),
341 landmarkDistanceThreshold(_landmarkDistanceThreshold),
342 dynamicOutlierRejectionThreshold(_dynamicOutlierRejectionThreshold) {
346 friend std::ostream &operator<<(std::ostream &os,
349 os <<
"enableEPI = " << p.
enableEPI << std::endl;
352 os <<
"dynamicOutlierRejectionThreshold = "
360 friend class boost::serialization::access;
361 template<
class ARCHIVE>
362 void serialize(ARCHIVE & ar,
const unsigned int version) {
363 ar & BOOST_SERIALIZATION_NVP(rankTolerance);
364 ar & BOOST_SERIALIZATION_NVP(enableEPI);
365 ar & BOOST_SERIALIZATION_NVP(landmarkDistanceThreshold);
366 ar & BOOST_SERIALIZATION_NVP(dynamicOutlierRejectionThreshold);
375 VALID, DEGENERATE, BEHIND_CAMERA, OUTLIER, FAR_POINT
408 return status_ == VALID;
410 bool degenerate()
const {
411 return status_ == DEGENERATE;
413 bool outlier()
const {
414 return status_ == OUTLIER;
416 bool farPoint()
const {
417 return status_ == FAR_POINT;
419 bool behindCamera()
const {
420 return status_ == BEHIND_CAMERA;
423 friend std::ostream &operator<<(std::ostream &os,
426 os <<
"point = " << *result << std::endl;
428 os <<
"no point, status = " << result.status_ << std::endl;
436 template<
class ARCHIVE>
437 void serialize(ARCHIVE & ar,
const unsigned int version) {
438 ar & BOOST_SERIALIZATION_NVP(status_);
443template<
class CAMERA>
445 const typename CAMERA::MeasurementVector& measured,
448 size_t m = cameras.size();
452 return TriangulationResult::Degenerate();
456 Point3 point = triangulatePoint3<CAMERA>(cameras, measured,
461 double maxReprojError = 0.0;
462 for(
const CAMERA& camera: cameras) {
463 const Pose3& pose = camera.pose();
467 return TriangulationResult::FarPoint();
468#ifdef GTSAM_THROW_CHEIRALITY_EXCEPTION
472 if (p_local.z() <= 0)
473 return TriangulationResult::BehindCamera();
477 const Point2& zi = measured.at(i);
478 Point2 reprojectionError(camera.project(point) - zi);
479 maxReprojError = std::max(maxReprojError, reprojectionError.norm());
486 return TriangulationResult::Outlier();
494 return TriangulationResult::Degenerate();
497 return TriangulationResult::BehindCamera();
502using CameraSetCal3Bundler = CameraSet<PinholeCamera<Cal3Bundler>>;
503using CameraSetCal3_S2 = CameraSet<PinholeCamera<Cal3_S2>>;
504using CameraSetCal3Fisheye = CameraSet<PinholeCamera<Cal3Fisheye>>;
505using CameraSetCal3Unified = CameraSet<PinholeCamera<Cal3Unified>>;
#define GTSAM_MAKE_ALIGNED_OPERATOR_NEW
This marks a GTSAM object to require alignment.
Definition: types.h:277
The most common 5DOF 3D->2D calibration.
Unified Calibration Model, see Mei07icra for details.
Base class to create smart factors on poses or cameras.
Base class for all pinhole cameras.
Calibration used by Bundler.
Calibration of a fisheye camera.
Factor Graph consisting of non-linear factors.
Global functions in a separate testing namespace.
Definition: chartTesting.h:28
std::string serialize(const T &input)
serializes to a string
Definition: serialization.h:112
std::pair< NonlinearFactorGraph, Values > triangulationGraph(const std::vector< Pose3 > &poses, boost::shared_ptr< CALIBRATION > sharedCal, const Point2Vector &measurements, Key landmarkKey, const Point3 &initialEstimate)
Create a factor graph with projection factors from poses and one calibration.
Definition: triangulation.h:84
Point3 optimize(const NonlinearFactorGraph &graph, const Values &values, Key landmarkKey)
Optimize for triangulation.
Definition: triangulation.cpp:73
Vector2 Point2
As of GTSAM 4, in order to make GTSAM more lean, it is now possible to just typedef Point2 to Vector2...
Definition: Point2.h:27
TriangulationResult triangulateSafe(const CameraSet< CAMERA > &cameras, const typename CAMERA::MeasurementVector &measured, const TriangulationParameters ¶ms)
triangulateSafe: extensive checking of the outcome
Definition: triangulation.h:444
double distance3(const Point3 &p1, const Point3 &q, OptionalJacobian< 1, 3 > H1, OptionalJacobian< 1, 3 > H2)
distance between two points
Definition: Point3.cpp:26
Vector3 Point3
As of GTSAM 4, in order to make GTSAM more lean, it is now possible to just typedef Point3 to Vector3...
Definition: Point3.h:35
noiseModel::Base::shared_ptr SharedNoiseModel
Note, deliberately not in noiseModel namespace.
Definition: NoiseModel.h:736
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:69
Point3 triangulatePoint3(const std::vector< Pose3 > &poses, boost::shared_ptr< CALIBRATION > sharedCal, const Point2Vector &measurements, double rank_tol=1e-9, bool optimize=false)
Function to triangulate 3D landmark point from an arbitrary number of poses (at least 2) using the DL...
Definition: triangulation.h:217
Point3 triangulateDLT(const std::vector< Matrix34, Eigen::aligned_allocator< Matrix34 > > &projection_matrices, const Point2Vector &measurements, double rank_tol)
DLT triangulation: See Hartley and Zisserman, 2nd Ed., page 312.
Definition: triangulation.cpp:56
Vector4 triangulateHomogeneousDLT(const std::vector< Matrix34, Eigen::aligned_allocator< Matrix34 > > &projection_matrices, const Point2Vector &measurements, double rank_tol)
DLT triangulation: See Hartley and Zisserman, 2nd Ed., page 312.
Definition: triangulation.cpp:26
Point3 triangulateNonlinear(const std::vector< Pose3 > &poses, boost::shared_ptr< CALIBRATION > sharedCal, const Point2Vector &measurements, const Point3 &initialEstimate)
Given an initial estimate , refine a point using measurements in several cameras.
Definition: triangulation.h:149
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition: concepts.h:30
A set of cameras, all with their own calibration.
Definition: CameraSet.h:35
Definition: PinholeCamera.h:33
Definition: PinholePose.h:237
Point3 transformTo(const Point3 &point, OptionalJacobian< 3, 6 > Hself=boost::none, OptionalJacobian< 3, 3 > Hpoint=boost::none) const
takes point in world coordinates and transforms it to Pose coordinates
Definition: Pose3.cpp:358
const Point3 & translation(OptionalJacobian< 3, 6 > Hself=boost::none) const
get translation
Definition: Pose3.cpp:303
Matrix4 matrix() const
convert to 4*4 matrix
Definition: Pose3.cpp:318
Pose3 inverse() const
inverse transformation with derivatives
Definition: Pose3.cpp:50
Exception thrown by triangulateDLT when SVD returns rank < 3.
Definition: triangulation.h:35
Exception thrown by triangulateDLT when landmark is behind one or more of the cameras.
Definition: triangulation.h:43
Create a 3*4 camera projection matrix from calibration and pose.
Definition: triangulation.h:191
Definition: triangulation.h:310
double dynamicOutlierRejectionThreshold
If this is nonnegative the we will check if the average reprojection error is smaller than this thres...
Definition: triangulation.h:327
TriangulationParameters(const double _rankTolerance=1.0, const bool _enableEPI=false, double _landmarkDistanceThreshold=-1, double _dynamicOutlierRejectionThreshold=-1)
Constructor.
Definition: triangulation.h:337
double rankTolerance
threshold to decide whether triangulation is result.degenerate
Definition: triangulation.h:312
double landmarkDistanceThreshold
if the landmark is triangulated at distance larger than this, result is flagged as degenerate.
Definition: triangulation.h:320
bool enableEPI
if set to true, will refine triangulation using LM
Definition: triangulation.h:314
TriangulationResult is an optional point, along with the reasons why it is invalid.
Definition: triangulation.h:373
TriangulationResult()
Default constructor, only for serialization.
Definition: triangulation.h:386
TriangulationResult(const Point3 &p)
Constructor.
Definition: triangulation.h:391
friend class boost::serialization::access
Serialization function.
Definition: triangulation.h:435
Character and index key used to refer to variables.
Definition: Symbol.h:35
static shared_ptr Sigma(size_t dim, double sigma, bool smart=true)
An isotropic noise model created by specifying a standard devation sigma.
Definition: NoiseModel.cpp:567
static shared_ptr Create(size_t dim)
Create a unit covariance noise model.
Definition: NoiseModel.h:611
A non-linear factor graph is a graph of non-Gaussian, i.e.
Definition: NonlinearFactorGraph.h:78
A non-templated config holding any types of Manifold-group elements.
Definition: Values.h:63
void insert(Key j, const Value &val)
Add a variable with the given j, throws KeyAlreadyExists<J> if j is already present.
Definition: Values.cpp:132
Definition: TriangulationFactor.h:31