gtsam  3.2.1
gtsam
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
19 #pragma once
20 
21 
22 #include <gtsam/geometry/TriangulationFactor.h>
24 #include <gtsam/inference/Symbol.h>
25 #include <gtsam/slam/PriorFactor.h>
26 
27 #include <vector>
28 
29 namespace gtsam {
30 
32 class TriangulationUnderconstrainedException: public std::runtime_error {
33 public:
35  std::runtime_error("Triangulation Underconstrained Exception.") {
36  }
37 };
38 
40 class TriangulationCheiralityException: public std::runtime_error {
41 public:
43  std::runtime_error(
44  "Triangulation Cheirality Exception: The resulting landmark is behind one or more cameras.") {
45  }
46 };
47 
55 GTSAM_EXPORT Point3 triangulateDLT(
56  const std::vector<Matrix>& projection_matrices,
57  const std::vector<Point2>& measurements, double rank_tol);
58 
60 
69 template<class CALIBRATION>
70 std::pair<NonlinearFactorGraph, Values> triangulationGraph(
71  const std::vector<Pose3>& poses, boost::shared_ptr<CALIBRATION> sharedCal,
72  const std::vector<Point2>& measurements, Key landmarkKey,
73  const Point3& initialEstimate) {
74  Values values;
75  values.insert(landmarkKey, initialEstimate); // Initial landmark value
78  static SharedNoiseModel prior_model(noiseModel::Isotropic::Sigma(6, 1e-6));
79  for (size_t i = 0; i < measurements.size(); i++) {
80  const Pose3& pose_i = poses[i];
81  PinholeCamera<CALIBRATION> camera_i(pose_i, *sharedCal);
83  (camera_i, measurements[i], unit2, landmarkKey));
84  }
85  return std::make_pair(graph, values);
86 }
87 
97 template<class CALIBRATION>
98 std::pair<NonlinearFactorGraph, Values> triangulationGraph(
99  const std::vector<PinholeCamera<CALIBRATION> >& cameras,
100  const std::vector<Point2>& measurements, Key landmarkKey,
101  const Point3& initialEstimate) {
102  Values values;
103  values.insert(landmarkKey, initialEstimate); // Initial landmark value
104  NonlinearFactorGraph graph;
106  static SharedNoiseModel prior_model(noiseModel::Isotropic::Sigma(6, 1e-6));
107  for (size_t i = 0; i < measurements.size(); i++) {
108  const PinholeCamera<CALIBRATION>& camera_i = cameras[i];
110  (camera_i, measurements[i], unit2, landmarkKey));
111  }
112  return std::make_pair(graph, values);
113 }
114 
116 
123 GTSAM_EXPORT Point3 optimize(const NonlinearFactorGraph& graph,
124  const Values& values, Key landmarkKey);
125 
134 template<class CALIBRATION>
135 Point3 triangulateNonlinear(const std::vector<Pose3>& poses,
136  boost::shared_ptr<CALIBRATION> sharedCal,
137  const std::vector<Point2>& measurements, const Point3& initialEstimate) {
138 
139  // Create a factor graph and initial values
140  Values values;
141  NonlinearFactorGraph graph;
142  boost::tie(graph, values) = triangulationGraph(poses, sharedCal, measurements,
143  Symbol('p', 0), initialEstimate);
144 
145  return optimize(graph, values, Symbol('p', 0));
146 }
147 
155 template<class CALIBRATION>
157  const std::vector<PinholeCamera<CALIBRATION> >& cameras,
158  const std::vector<Point2>& measurements, const Point3& initialEstimate) {
159 
160  // Create a factor graph and initial values
161  Values values;
162  NonlinearFactorGraph graph;
163  boost::tie(graph, values) = triangulationGraph(cameras, measurements,
164  Symbol('p', 0), initialEstimate);
165 
166  return optimize(graph, values, Symbol('p', 0));
167 }
168 
181 template<class CALIBRATION>
182 Point3 triangulatePoint3(const std::vector<Pose3>& poses,
183  boost::shared_ptr<CALIBRATION> sharedCal,
184  const std::vector<Point2>& measurements, double rank_tol = 1e-9,
185  bool optimize = false) {
186 
187  assert(poses.size() == measurements.size());
188  if (poses.size() < 2)
190 
191  // construct projection matrices from poses & calibration
192  std::vector<Matrix> projection_matrices;
193  BOOST_FOREACH(const Pose3& pose, poses) {
194  projection_matrices.push_back(
195  sharedCal->K() * sub(pose.inverse().matrix(), 0, 3, 0, 4));
196  }
197 
198  // Triangulate linearly
199  Point3 point = triangulateDLT(projection_matrices, measurements, rank_tol);
200 
201  // The n refine using non-linear optimization
202  if (optimize)
203  point = triangulateNonlinear(poses, sharedCal, measurements, point);
204 
205 #ifdef GTSAM_THROW_CHEIRALITY_EXCEPTION
206  // verify that the triangulated point lies infront of all cameras
207  BOOST_FOREACH(const Pose3& pose, poses) {
208  const Point3& p_local = pose.transform_to(point);
209  if (p_local.z() <= 0)
211  }
212 #endif
213 
214  return point;
215 }
216 
229 template<class CALIBRATION>
231  const std::vector<PinholeCamera<CALIBRATION> >& cameras,
232  const std::vector<Point2>& measurements, double rank_tol = 1e-9,
233  bool optimize = false) {
234 
235  size_t m = cameras.size();
236  assert(measurements.size()==m);
237 
238  if (m < 2)
240 
241  // construct projection matrices from poses & calibration
242  typedef PinholeCamera<CALIBRATION> Camera;
243  std::vector<Matrix> projection_matrices;
244  BOOST_FOREACH(const Camera& camera, cameras)
245  projection_matrices.push_back(
246  camera.calibration().K()
247  * sub(camera.pose().inverse().matrix(), 0, 3, 0, 4));
248 
249  Point3 point = triangulateDLT(projection_matrices, measurements, rank_tol);
250 
251  // The n refine using non-linear optimization
252  if (optimize)
253  point = triangulateNonlinear(cameras, measurements, point);
254 
255 #ifdef GTSAM_THROW_CHEIRALITY_EXCEPTION
256  // verify that the triangulated point lies infront of all cameras
257  BOOST_FOREACH(const Camera& camera, cameras) {
258  const Point3& p_local = camera.pose().transform_to(point);
259  if (p_local.z() <= 0)
261  }
262 #endif
263 
264  return point;
265 }
266 
267 } // \namespace gtsam
268 
Matrix4 matrix() const
convert to 4*4 matrix
Definition: Pose3.cpp:225
static shared_ptr Create(size_t dim)
Create a unit covariance noise model.
Definition: NoiseModel.h:585
Character and index key used in VectorValues, GaussianFactorGraph, GaussianFactor, etc.
Definition: Symbol.h:33
Pose3 inverse(boost::optional< Matrix & > H1=boost::none) const
inverse transformation with derivatives
Definition: Pose3.cpp:282
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:127
Point3 triangulateDLT(const std::vector< Matrix > &projection_matrices, const std::vector< Point2 > &measurements, double rank_tol)
DLT triangulation: See Hartley and Zisserman, 2nd Ed., page 312.
Definition: triangulation.cpp:33
Point3 triangulatePoint3(const std::vector< Pose3 > &poses, boost::shared_ptr< CALIBRATION > sharedCal, const std::vector< Point2 > &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:182
Eigen::Block< const MATRIX > sub(const MATRIX &A, size_t i1, size_t i2, size_t j1, size_t j2)
extract submatrix, slice semantics, i.e.
Definition: Matrix.h:205
Exception thrown by triangulateDLT when SVD returns rank < 3.
Definition: triangulation.h:32
boost::enable_if< boost::is_base_of< FactorType, DERIVEDFACTOR > >::type push_back(boost::shared_ptr< DERIVEDFACTOR > factor)
Add a factor directly using a shared_ptr.
Definition: FactorGraph.h:155
Definition: Pose3.h:42
Factor Graph Constsiting of non-linear factors.
A non-templated config holding any types of Manifold-group elements.
Definition: Values.h:75
Definition: PinholeCamera.h:40
Point3 triangulateNonlinear(const std::vector< Pose3 > &poses, boost::shared_ptr< CALIBRATION > sharedCal, const std::vector< Point2 > &measurements, const Point3 &initialEstimate)
Given an initial estimate , refine a point using measurements in several cameras. ...
Definition: triangulation.h:135
double z() const
get z
Definition: Point3.h:205
A non-linear factor graph is a graph of non-Gaussian, i.e.
Definition: NonlinearFactorGraph.h:69
size_t Key
Integer nonlinear key type.
Definition: types.h:59
Definition: TriangulationFactor.h:32
Point3 optimize(const NonlinearFactorGraph &graph, const Values &values, Key landmarkKey)
Optimize for triangulation.
Definition: triangulation.cpp:72
Point3 transform_to(const Point3 &p, boost::optional< Matrix & > Dpose=boost::none, boost::optional< Matrix & > Dpoint=boost::none) const
takes point in world coordinates and transforms it to Pose coordinates
Definition: Pose3.cpp:257
Exception thrown by triangulateDLT when landmark is behind one or more of the cameras.
Definition: triangulation.h:40
noiseModel::Base::shared_ptr SharedNoiseModel
Note, deliberately not in noiseModel namespace.
Definition: NoiseModel.h:884
std::pair< NonlinearFactorGraph, Values > triangulationGraph(const std::vector< Pose3 > &poses, boost::shared_ptr< CALIBRATION > sharedCal, const std::vector< Point2 > &measurements, Key landmarkKey, const Point3 &initialEstimate)
Create a factor graph with projection factors from poses and one calibration.
Definition: triangulation.h:70
Definition: Point3.h:39
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:491