GTSAM  4.0.2
C++ library for smoothing and mapping (SAM)
triangulation.h
Go to the documentation of this file.
1 /* ----------------------------------------------------------------------------
2 
3  * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4  * Atlanta, Georgia 30332-0415
5  * All Rights Reserved
6  * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7 
8  * See LICENSE for the license information
9 
10  * -------------------------------------------------------------------------- */
11 
21 #pragma once
22 
23 #include "gtsam/geometry/Point3.h"
27 #include <gtsam/geometry/Cal3_S2.h>
28 #include <gtsam/geometry/Cal3DS2.h>
32 #include <gtsam/geometry/Pose2.h>
33 #include <gtsam/inference/Symbol.h>
35 #include <gtsam/slam/TriangulationFactor.h>
36 
37 #include <optional>
38 
39 namespace gtsam {
40 
42 class GTSAM_EXPORT TriangulationUnderconstrainedException: public std::runtime_error {
43 public:
45  std::runtime_error("Triangulation Underconstrained Exception.") {
46  }
47 };
48 
50 class GTSAM_EXPORT TriangulationCheiralityException: public std::runtime_error {
51 public:
53  std::runtime_error(
54  "Triangulation Cheirality Exception: The resulting landmark is behind one or more cameras.") {
55  }
56 };
57 
65 GTSAM_EXPORT Vector4 triangulateHomogeneousDLT(
66  const std::vector<Matrix34, Eigen::aligned_allocator<Matrix34>>& projection_matrices,
67  const Point2Vector& measurements, double rank_tol = 1e-9);
68 
77 GTSAM_EXPORT Vector4 triangulateHomogeneousDLT(
78  const std::vector<Matrix34, Eigen::aligned_allocator<Matrix34>>& projection_matrices,
79  const std::vector<Unit3>& measurements, double rank_tol = 1e-9);
80 
88 GTSAM_EXPORT Point3 triangulateDLT(
89  const std::vector<Matrix34, Eigen::aligned_allocator<Matrix34>>& projection_matrices,
90  const Point2Vector& measurements,
91  double rank_tol = 1e-9);
92 
96 GTSAM_EXPORT Point3 triangulateDLT(
97  const std::vector<Matrix34, Eigen::aligned_allocator<Matrix34>>& projection_matrices,
98  const std::vector<Unit3>& measurements,
99  double rank_tol = 1e-9);
100 
111 GTSAM_EXPORT Point3 triangulateLOST(const std::vector<Pose3>& poses,
112  const Point3Vector& calibratedMeasurements,
113  const SharedIsotropic& measurementNoise);
114 
124 template<class CALIBRATION>
125 std::pair<NonlinearFactorGraph, Values> triangulationGraph(
126  const std::vector<Pose3>& poses, std::shared_ptr<CALIBRATION> sharedCal,
127  const Point2Vector& measurements, Key landmarkKey,
128  const Point3& initialEstimate,
129  const SharedNoiseModel& model = noiseModel::Unit::Create(2)) {
130  Values values;
131  values.insert(landmarkKey, initialEstimate); // Initial landmark value
132  NonlinearFactorGraph graph;
133  for (size_t i = 0; i < measurements.size(); i++) {
134  const Pose3& pose_i = poses[i];
135  typedef PinholePose<CALIBRATION> Camera;
136  Camera camera_i(pose_i, sharedCal);
138  (camera_i, measurements[i], model, landmarkKey);
139  }
140  return {graph, values};
141 }
142 
152 template<class CAMERA>
153 std::pair<NonlinearFactorGraph, Values> triangulationGraph(
154  const CameraSet<CAMERA>& cameras,
155  const typename CAMERA::MeasurementVector& measurements, Key landmarkKey,
156  const Point3& initialEstimate,
157  const SharedNoiseModel& model = nullptr) {
158  Values values;
159  values.insert(landmarkKey, initialEstimate); // Initial landmark value
160  NonlinearFactorGraph graph;
163  for (size_t i = 0; i < measurements.size(); i++) {
164  const CAMERA& camera_i = cameras[i];
166  (camera_i, measurements[i], model? model : unit, landmarkKey);
167  }
168  return {graph, values};
169 }
170 
178 GTSAM_EXPORT Point3 optimize(const NonlinearFactorGraph& graph,
179  const Values& values, Key landmarkKey);
180 
189 template<class CALIBRATION>
190 Point3 triangulateNonlinear(const std::vector<Pose3>& poses,
191  std::shared_ptr<CALIBRATION> sharedCal,
192  const Point2Vector& measurements, const Point3& initialEstimate,
193  const SharedNoiseModel& model = nullptr) {
194 
195  // Create a factor graph and initial values
196  const auto [graph, values] = triangulationGraph<CALIBRATION> //
197  (poses, sharedCal, measurements, Symbol('p', 0), initialEstimate, model);
198 
199  return optimize(graph, values, Symbol('p', 0));
200 }
201 
209 template<class CAMERA>
211  const CameraSet<CAMERA>& cameras,
212  const typename CAMERA::MeasurementVector& measurements, const Point3& initialEstimate,
213  const SharedNoiseModel& model = nullptr) {
214 
215  // Create a factor graph and initial values
216  const auto [graph, values] = triangulationGraph<CAMERA> //
217  (cameras, measurements, Symbol('p', 0), initialEstimate, model);
218 
219  return optimize(graph, values, Symbol('p', 0));
220 }
221 
222 template<class CAMERA>
223 std::vector<Matrix34, Eigen::aligned_allocator<Matrix34>>
224 projectionMatricesFromCameras(const CameraSet<CAMERA> &cameras) {
225  std::vector<Matrix34, Eigen::aligned_allocator<Matrix34>> projection_matrices;
226  for (const CAMERA &camera: cameras) {
227  projection_matrices.push_back(camera.cameraProjectionMatrix());
228  }
229  return projection_matrices;
230 }
231 
232 // overload, assuming pinholePose
233 template<class CALIBRATION>
234 std::vector<Matrix34, Eigen::aligned_allocator<Matrix34>> projectionMatricesFromPoses(
235  const std::vector<Pose3> &poses, std::shared_ptr<CALIBRATION> sharedCal) {
236  std::vector<Matrix34, Eigen::aligned_allocator<Matrix34>> projection_matrices;
237  for (size_t i = 0; i < poses.size(); i++) {
238  PinholePose<CALIBRATION> camera(poses.at(i), sharedCal);
239  projection_matrices.push_back(camera.cameraProjectionMatrix());
240  }
241  return projection_matrices;
242 }
243 
251 template <class CALIBRATION>
252 Cal3_S2 createPinholeCalibration(const CALIBRATION& cal) {
253  const auto& K = cal.K();
254  return Cal3_S2(K(0, 0), K(1, 1), K(0, 1), K(0, 2), K(1, 2));
255 }
256 
259 template <class CALIBRATION, class MEASUREMENT>
261  const CALIBRATION& cal, const MEASUREMENT& measurement,
262  std::optional<Cal3_S2> pinholeCal = {}) {
263  if (!pinholeCal) {
264  pinholeCal = createPinholeCalibration(cal);
265  }
266  return pinholeCal->uncalibrate(cal.calibrate(measurement));
267 }
268 
280 template <class CALIBRATION>
281 Point2Vector undistortMeasurements(const CALIBRATION& cal,
282  const Point2Vector& measurements) {
283  Cal3_S2 pinholeCalibration = createPinholeCalibration(cal);
284  Point2Vector undistortedMeasurements;
285  // Calibrate with cal and uncalibrate with pinhole version of cal so that
286  // measurements are undistorted.
287  std::transform(measurements.begin(), measurements.end(),
288  std::back_inserter(undistortedMeasurements),
289  [&cal, &pinholeCalibration](const Point2& measurement) {
290  return undistortMeasurementInternal<CALIBRATION>(
291  cal, measurement, pinholeCalibration);
292  });
293  return undistortedMeasurements;
294 }
295 
297 template <>
298 inline Point2Vector undistortMeasurements(const Cal3_S2& cal,
299  const Point2Vector& measurements) {
300  return measurements;
301 }
302 
314 template <class CAMERA>
315 typename CAMERA::MeasurementVector undistortMeasurements(
316  const CameraSet<CAMERA>& cameras,
317  const typename CAMERA::MeasurementVector& measurements) {
318  const size_t nrMeasurements = measurements.size();
319  assert(nrMeasurements == cameras.size());
320  typename CAMERA::MeasurementVector undistortedMeasurements(nrMeasurements);
321  for (size_t ii = 0; ii < nrMeasurements; ++ii) {
322  // Calibrate with cal and uncalibrate with pinhole version of cal so that
323  // measurements are undistorted.
324  undistortedMeasurements[ii] =
325  undistortMeasurementInternal<typename CAMERA::CalibrationType>(
326  cameras[ii].calibration(), measurements[ii]);
327  }
328  return undistortedMeasurements;
329 }
330 
332 template <class CAMERA = PinholeCamera<Cal3_S2>>
333 inline PinholeCamera<Cal3_S2>::MeasurementVector undistortMeasurements(
334  const CameraSet<PinholeCamera<Cal3_S2>>& cameras,
335  const PinholeCamera<Cal3_S2>::MeasurementVector& measurements) {
336  return measurements;
337 }
338 
340 template <class CAMERA = SphericalCamera>
341 inline SphericalCamera::MeasurementVector undistortMeasurements(
342  const CameraSet<SphericalCamera>& cameras,
343  const SphericalCamera::MeasurementVector& measurements) {
344  return measurements;
345 }
346 
355 template <class CALIBRATION>
356 inline Point3Vector calibrateMeasurementsShared(
357  const CALIBRATION& cal, const Point2Vector& measurements) {
358  Point3Vector calibratedMeasurements;
359  // Calibrate with cal and uncalibrate with pinhole version of cal so that
360  // measurements are undistorted.
361  std::transform(measurements.begin(), measurements.end(),
362  std::back_inserter(calibratedMeasurements),
363  [&cal](const Point2& measurement) {
364  Point3 p;
365  p << cal.calibrate(measurement), 1.0;
366  return p;
367  });
368  return calibratedMeasurements;
369 }
370 
379 template <class CAMERA>
380 inline Point3Vector calibrateMeasurements(
381  const CameraSet<CAMERA>& cameras,
382  const typename CAMERA::MeasurementVector& measurements) {
383  const size_t nrMeasurements = measurements.size();
384  assert(nrMeasurements == cameras.size());
385  Point3Vector calibratedMeasurements(nrMeasurements);
386  for (size_t ii = 0; ii < nrMeasurements; ++ii) {
387  calibratedMeasurements[ii]
388  << cameras[ii].calibration().calibrate(measurements[ii]),
389  1.0;
390  }
391  return calibratedMeasurements;
392 }
393 
395 template <class CAMERA = SphericalCamera>
396 inline Point3Vector calibrateMeasurements(
397  const CameraSet<SphericalCamera>& cameras,
398  const SphericalCamera::MeasurementVector& measurements) {
399  Point3Vector calibratedMeasurements(measurements.size());
400  for (size_t ii = 0; ii < measurements.size(); ++ii) {
401  calibratedMeasurements[ii] << measurements[ii].point3();
402  }
403  return calibratedMeasurements;
404 }
405 
419 template <class CALIBRATION>
420 Point3 triangulatePoint3(const std::vector<Pose3>& poses,
421  std::shared_ptr<CALIBRATION> sharedCal,
422  const Point2Vector& measurements,
423  double rank_tol = 1e-9, bool optimize = false,
424  const SharedNoiseModel& model = nullptr,
425  const bool useLOST = false) {
426  assert(poses.size() == measurements.size());
427  if (poses.size() < 2) throw(TriangulationUnderconstrainedException());
428 
429  // Triangulate linearly
430  Point3 point;
431  if (useLOST) {
432  // Reduce input noise model to an isotropic noise model using the mean of
433  // the diagonal.
434  const double measurementSigma = model ? model->sigmas().mean() : 1e-4;
435  SharedIsotropic measurementNoise =
436  noiseModel::Isotropic::Sigma(2, measurementSigma);
437  // calibrate the measurements to obtain homogenous coordinates in image
438  // plane.
439  auto calibratedMeasurements =
440  calibrateMeasurementsShared<CALIBRATION>(*sharedCal, measurements);
441 
442  point = triangulateLOST(poses, calibratedMeasurements, measurementNoise);
443  } else {
444  // construct projection matrices from poses & calibration
445  auto projection_matrices = projectionMatricesFromPoses(poses, sharedCal);
446 
447  // Undistort the measurements, leaving only the pinhole elements in effect.
448  auto undistortedMeasurements =
449  undistortMeasurements<CALIBRATION>(*sharedCal, measurements);
450 
451  point =
452  triangulateDLT(projection_matrices, undistortedMeasurements, rank_tol);
453  }
454 
455  // Then refine using non-linear optimization
456  if (optimize)
457  point = triangulateNonlinear<CALIBRATION> //
458  (poses, sharedCal, measurements, point, model);
459 
460 #ifdef GTSAM_THROW_CHEIRALITY_EXCEPTION
461  // verify that the triangulated point lies in front of all cameras
462  for (const Pose3& pose : poses) {
463  const Point3& p_local = pose.transformTo(point);
464  if (p_local.z() <= 0) throw(TriangulationCheiralityException());
465  }
466 #endif
467 
468  return point;
469 }
470 
485 template <class CAMERA>
487  const typename CAMERA::MeasurementVector& measurements,
488  double rank_tol = 1e-9, bool optimize = false,
489  const SharedNoiseModel& model = nullptr,
490  const bool useLOST = false) {
491  size_t m = cameras.size();
492  assert(measurements.size() == m);
493 
494  if (m < 2) throw(TriangulationUnderconstrainedException());
495 
496  // Triangulate linearly
497  Point3 point;
498  if (useLOST) {
499  // Reduce input noise model to an isotropic noise model using the mean of
500  // the diagonal.
501  const double measurementSigma = model ? model->sigmas().mean() : 1e-4;
502  SharedIsotropic measurementNoise =
503  noiseModel::Isotropic::Sigma(2, measurementSigma);
504 
505  // construct poses from cameras.
506  std::vector<Pose3> poses;
507  poses.reserve(cameras.size());
508  for (const auto& camera : cameras) poses.push_back(camera.pose());
509 
510  // calibrate the measurements to obtain homogenous coordinates in image
511  // plane.
512  auto calibratedMeasurements =
513  calibrateMeasurements<CAMERA>(cameras, measurements);
514 
515  point = triangulateLOST(poses, calibratedMeasurements, measurementNoise);
516  } else {
517  // construct projection matrices from poses & calibration
518  auto projection_matrices = projectionMatricesFromCameras(cameras);
519 
520  // Undistort the measurements, leaving only the pinhole elements in effect.
521  auto undistortedMeasurements =
522  undistortMeasurements<CAMERA>(cameras, measurements);
523 
524  point =
525  triangulateDLT(projection_matrices, undistortedMeasurements, rank_tol);
526  }
527 
528  // Then refine using non-linear optimization
529  if (optimize) {
530  point = triangulateNonlinear<CAMERA>(cameras, measurements, point, model);
531  }
532 
533 #ifdef GTSAM_THROW_CHEIRALITY_EXCEPTION
534  // verify that the triangulated point lies in front of all cameras
535  for (const CAMERA& camera : cameras) {
536  const Point3& p_local = camera.pose().transformTo(point);
537  if (p_local.z() <= 0) throw(TriangulationCheiralityException());
538  }
539 #endif
540 
541  return point;
542 }
543 
545 template <class CALIBRATION>
547  const Point2Vector& measurements,
548  double rank_tol = 1e-9, bool optimize = false,
549  const SharedNoiseModel& model = nullptr,
550  const bool useLOST = false) {
551  return triangulatePoint3<PinholeCamera<CALIBRATION>> //
552  (cameras, measurements, rank_tol, optimize, model, useLOST);
553 }
554 
555 struct GTSAM_EXPORT TriangulationParameters {
556 
557  double rankTolerance;
558  bool enableEPI;
560 
566 
573 
575 
585  TriangulationParameters(const double _rankTolerance = 1.0,
586  const bool _enableEPI = false, double _landmarkDistanceThreshold = -1,
587  double _dynamicOutlierRejectionThreshold = -1,
588  const SharedNoiseModel& _noiseModel = nullptr) :
589  rankTolerance(_rankTolerance), enableEPI(_enableEPI), //
590  landmarkDistanceThreshold(_landmarkDistanceThreshold), //
591  dynamicOutlierRejectionThreshold(_dynamicOutlierRejectionThreshold),
592  noiseModel(_noiseModel){
593  }
594 
595  // stream to output
596  friend std::ostream &operator<<(std::ostream &os,
597  const TriangulationParameters& p) {
598  os << "rankTolerance = " << p.rankTolerance << std::endl;
599  os << "enableEPI = " << p.enableEPI << std::endl;
600  os << "landmarkDistanceThreshold = " << p.landmarkDistanceThreshold
601  << std::endl;
602  os << "dynamicOutlierRejectionThreshold = "
603  << p.dynamicOutlierRejectionThreshold << std::endl;
604  os << "noise model" << std::endl;
605  return os;
606  }
607 
608 private:
609 
610 #ifdef GTSAM_ENABLE_BOOST_SERIALIZATION
611  friend class boost::serialization::access;
613  template<class ARCHIVE>
614  void serialize(ARCHIVE & ar, const unsigned int version) {
615  ar & BOOST_SERIALIZATION_NVP(rankTolerance);
616  ar & BOOST_SERIALIZATION_NVP(enableEPI);
617  ar & BOOST_SERIALIZATION_NVP(landmarkDistanceThreshold);
618  ar & BOOST_SERIALIZATION_NVP(dynamicOutlierRejectionThreshold);
619  }
620 #endif
621 };
622 
627 class TriangulationResult : public std::optional<Point3> {
628  public:
629  enum Status { VALID, DEGENERATE, BEHIND_CAMERA, OUTLIER, FAR_POINT };
630  Status status;
631 
632  private:
633  TriangulationResult(Status s) : status(s) {}
634 
635  public:
640 
644  TriangulationResult(const Point3& p) : status(VALID) { emplace(p); }
645  static TriangulationResult Degenerate() {
646  return TriangulationResult(DEGENERATE);
647  }
648  static TriangulationResult Outlier() { return TriangulationResult(OUTLIER); }
649  static TriangulationResult FarPoint() {
650  return TriangulationResult(FAR_POINT);
651  }
652  static TriangulationResult BehindCamera() {
653  return TriangulationResult(BEHIND_CAMERA);
654  }
655  bool valid() const { return status == VALID; }
656  bool degenerate() const { return status == DEGENERATE; }
657  bool outlier() const { return status == OUTLIER; }
658  bool farPoint() const { return status == FAR_POINT; }
659  bool behindCamera() const { return status == BEHIND_CAMERA; }
660  const gtsam::Point3& get() const {
661  if (!has_value()) throw std::runtime_error("TriangulationResult has no value");
662  return value();
663  }
664  // stream to output
665  friend std::ostream& operator<<(std::ostream& os,
666  const TriangulationResult& result) {
667  if (result)
668  os << "point = " << *result << std::endl;
669  else
670  os << "no point, status = " << result.status << std::endl;
671  return os;
672  }
673 
674  private:
675 #ifdef GTSAM_ENABLE_BOOST_SERIALIZATION
676  friend class boost::serialization::access;
678  template <class ARCHIVE>
679  void serialize(ARCHIVE& ar, const unsigned int version) {
680  ar& BOOST_SERIALIZATION_NVP(status);
681  }
682 #endif
683 };
684 
686 template<class CAMERA>
688  const typename CAMERA::MeasurementVector& measured,
689  const TriangulationParameters& params) {
690 
691  size_t m = cameras.size();
692 
693  // if we have a single pose the corresponding factor is uninformative
694  if (m < 2)
695  return TriangulationResult::Degenerate();
696  else
697  // We triangulate the 3D position of the landmark
698  try {
699  Point3 point =
700  triangulatePoint3<CAMERA>(cameras, measured, params.rankTolerance,
701  params.enableEPI, params.noiseModel);
702 
703  // Check landmark distance and re-projection errors to avoid outliers
704  size_t i = 0;
705  double maxReprojError = 0.0;
706  for(const CAMERA& camera: cameras) {
707  const Pose3& pose = camera.pose();
708  if (params.landmarkDistanceThreshold > 0
709  && distance3(pose.translation(), point)
710  > params.landmarkDistanceThreshold)
711  return TriangulationResult::FarPoint();
712 #ifdef GTSAM_THROW_CHEIRALITY_EXCEPTION
713  // verify that the triangulated point lies in front of all cameras
714  // Only needed if this was not yet handled by exception
715  const Point3& p_local = pose.transformTo(point);
716  if (p_local.z() <= 0)
717  return TriangulationResult::BehindCamera();
718 #endif
719  // Check reprojection error
720  if (params.dynamicOutlierRejectionThreshold > 0) {
721  const typename CAMERA::Measurement& zi = measured.at(i);
722  Point2 reprojectionError = camera.reprojectionError(point, zi);
723  maxReprojError = std::max(maxReprojError, reprojectionError.norm());
724  }
725  i += 1;
726  }
727  // Flag as degenerate if average reprojection error is too large
728  if (params.dynamicOutlierRejectionThreshold > 0
729  && maxReprojError > params.dynamicOutlierRejectionThreshold)
730  return TriangulationResult::Outlier();
731 
732  // all good!
733  return TriangulationResult(point);
735  // This exception is thrown if
736  // 1) There is a single pose for triangulation - this should not happen because we checked the number of poses before
737  // 2) The rank of the matrix used for triangulation is < 3: rotation-only, parallel cameras (or motion towards the landmark)
738  return TriangulationResult::Degenerate();
740  // point is behind one of the cameras: can be the case of close-to-parallel cameras or may depend on outliers
741  return TriangulationResult::BehindCamera();
742  }
743 }
744 
745 // Vector of Cameras - used by the Python/MATLAB wrapper
752 } // \namespace gtsam
753 
TriangulationParameters(const double _rankTolerance=1.0, const bool _enableEPI=false, double _landmarkDistanceThreshold=-1, double _dynamicOutlierRejectionThreshold=-1, const SharedNoiseModel &_noiseModel=nullptr)
Definition: triangulation.h:585
std::pair< NonlinearFactorGraph, Values > triangulationGraph(const std::vector< Pose3 > &poses, std::shared_ptr< CALIBRATION > sharedCal, const Point2Vector &measurements, Key landmarkKey, const Point3 &initialEstimate, const SharedNoiseModel &model=noiseModel::Unit::Create(2))
Definition: triangulation.h:125
TriangulationResult(const Point3 &p)
Definition: triangulation.h:644
GTSAM_EXPORT Vector4 triangulateHomogeneousDLT(const std::vector< Matrix34, Eigen::aligned_allocator< Matrix34 >> &projection_matrices, const Point2Vector &measurements, double rank_tol=1e-9)
IsDerived< DERIVEDFACTOR > emplace_shared(Args &&... args)
Emplace a shared pointer to factor of given type.
Definition: FactorGraph.h:196
SharedNoiseModel noiseModel
used in the nonlinear triangulation
Definition: triangulation.h:574
Factor Graph consisting of non-linear factors.
std::string serialize(const T &input)
serializes to a string
Definition: serialization.h:113
void insert(Key j, const Value &val)
Base class to create smart factors on poses or cameras.
Vector2 Point2
Definition: Point2.h:32
Definition: Group.h:43
double dynamicOutlierRejectionThreshold
Definition: triangulation.h:572
Point3Vector calibrateMeasurements(const CameraSet< CAMERA > &cameras, const typename CAMERA::MeasurementVector &measurements)
Definition: triangulation.h:380
Calibrated camera with spherical projection.
Calibration of a camera with radial distortion, calculations in base class Cal3DS2_Base.
GTSAM_EXPORT Point3 triangulateLOST(const std::vector< Pose3 > &poses, const Point3Vector &calibratedMeasurements, const SharedIsotropic &measurementNoise)
Triangulation using the LOST (Linear Optimal Sine Triangulation) algorithm proposed in https://arxiv...
Point3 transformTo(const Point3 &point, OptionalJacobian< 3, 6 > Hself={}, OptionalJacobian< 3, 3 > Hpoint={}) const
takes point in world coordinates and transforms it to Pose coordinates
A set of cameras, all with their own calibration.
Definition: CameraSet.h:36
static shared_ptr Create(size_t dim)
Definition: NoiseModel.h:610
Definition: TriangulationFactor.h:31
Base class for all pinhole cameras.
GTSAM_EXPORT Point3 optimize(const NonlinearFactorGraph &graph, const Values &values, Key landmarkKey)
double landmarkDistanceThreshold
Definition: triangulation.h:565
Definition: triangulation.h:555
Cal3_S2 createPinholeCalibration(const CALIBRATION &cal)
Definition: triangulation.h:252
bool enableEPI
if set to true, will refine triangulation using LM
Definition: triangulation.h:559
double rankTolerance
(the rank is the number of singular values of the triangulation matrix which are larger than rankTole...
Definition: triangulation.h:557
TriangulationResult()
Definition: triangulation.h:639
Point2Vector undistortMeasurements(const CALIBRATION &cal, const Point2Vector &measurements)
Definition: triangulation.h:281
Exception thrown by triangulateDLT when SVD returns rank < 3.
Definition: triangulation.h:42
The most common 5DOF 3D->2D calibration.
Definition: Cal3_S2.h:34
Point3 triangulatePoint3(const std::vector< Pose3 > &poses, std::shared_ptr< CALIBRATION > sharedCal, const Point2Vector &measurements, double rank_tol=1e-9, bool optimize=false, const SharedNoiseModel &model=nullptr, const bool useLOST=false)
Definition: triangulation.h:420
TriangulationResult triangulateSafe(const CameraSet< CAMERA > &cameras, const typename CAMERA::MeasurementVector &measured, const TriangulationParameters &params)
triangulateSafe: extensive checking of the outcome
Definition: triangulation.h:687
Definition: Values.h:65
Definition: PinholePose.h:239
Definition: NonlinearFactorGraph.h:55
Exception thrown by triangulateDLT when landmark is behind one or more of the cameras.
Definition: triangulation.h:50
Definition: PinholeCamera.h:33
Definition: chartTesting.h:28
GTSAM_EXPORT Point3 triangulateDLT(const std::vector< Matrix34, Eigen::aligned_allocator< Matrix34 >> &projection_matrices, const Point2Vector &measurements, double rank_tol=1e-9)
const Point3 & translation(OptionalJacobian< 3, 6 > Hself={}) const
get translation
GTSAM_EXPORT double distance3(const Point3 &p1, const Point3 &q, OptionalJacobian< 1, 3 > H1={}, OptionalJacobian< 1, 3 > H2={})
distance between two points
3D Point
MEASUREMENT undistortMeasurementInternal(const CALIBRATION &cal, const MEASUREMENT &measurement, std::optional< Cal3_S2 > pinholeCal={})
Definition: triangulation.h:260
Calibration of a fisheye camera.
Definition: Symbol.h:37
Vector3 Point3
Definition: Point3.h:38
Point3 triangulateNonlinear(const std::vector< Pose3 > &poses, std::shared_ptr< CALIBRATION > sharedCal, const Point2Vector &measurements, const Point3 &initialEstimate, const SharedNoiseModel &model=nullptr)
Definition: triangulation.h:190
Unified Calibration Model, see Mei07icra for details.
2D Pose
Definition: triangulation.h:627
Definition: Pose3.h:37
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:102
Calibration used by Bundler.
noiseModel::Base::shared_ptr SharedNoiseModel
Definition: NoiseModel.h:741
The most common 5DOF 3D->2D calibration.
Point3Vector calibrateMeasurementsShared(const CALIBRATION &cal, const Point2Vector &measurements)
Definition: triangulation.h:356
static shared_ptr Sigma(size_t dim, double sigma, bool smart=true)