gtsam  4.0.0
gtsam
PinholePose.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 
20 #pragma once
21 
23 #include <gtsam/geometry/Point2.h>
24 #include <boost/make_shared.hpp>
25 
26 namespace gtsam {
27 
33 template<typename CALIBRATION>
34 class GTSAM_EXPORT PinholeBaseK: public PinholeBase {
35 
36 private:
37 
38  GTSAM_CONCEPT_MANIFOLD_TYPE(CALIBRATION);
39 
40  // Get dimensions of calibration type at compile time
41  static const int DimK = FixedDimension<CALIBRATION>::value;
42 
43 public:
44 
45  typedef CALIBRATION CalibrationType;
46 
49 
52  }
53 
55  explicit PinholeBaseK(const Pose3& pose) :
56  PinholeBase(pose) {
57  }
58 
62 
63  explicit PinholeBaseK(const Vector &v) :
64  PinholeBase(v) {
65  }
66 
70 
71  virtual ~PinholeBaseK() {
72  }
73 
75  virtual const CALIBRATION& calibration() const = 0;
76 
80 
82  std::pair<Point2, bool> projectSafe(const Point3& pw) const {
83  std::pair<Point2, bool> pn = PinholeBase::projectSafe(pw);
84  pn.first = calibration().uncalibrate(pn.first);
85  return pn;
86  }
87 
91  Point2 project(const Point3& pw) const {
92  const Point2 pn = PinholeBase::project2(pw); // project to normalized coordinates
93  return calibration().uncalibrate(pn); // uncalibrate to pixel coordinates
94  }
95 
99  Point2 project(const Unit3& pw) const {
100  const Unit3 pc = pose().rotation().unrotate(pw); // convert to camera frame
101  const Point2 pn = PinholeBase::Project(pc); // project to normalized coordinates
102  return calibration().uncalibrate(pn); // uncalibrate to pixel coordinates
103  }
104 
111  template <class POINT>
112  Point2 _project(const POINT& pw, OptionalJacobian<2, 6> Dpose,
114  OptionalJacobian<2, DimK> Dcal) const {
115 
116  // project to normalized coordinates
117  const Point2 pn = PinholeBase::project2(pw, Dpose, Dpoint);
118 
119  // uncalibrate to pixel coordinates
120  Matrix2 Dpi_pn;
121  const Point2 pi = calibration().uncalibrate(pn, Dcal,
122  Dpose || Dpoint ? &Dpi_pn : 0);
123 
124  // If needed, apply chain rule
125  if (Dpose)
126  *Dpose = Dpi_pn * *Dpose;
127  if (Dpoint)
128  *Dpoint = Dpi_pn * *Dpoint;
129 
130  return pi;
131  }
132 
135  OptionalJacobian<2, 3> Dpoint = boost::none,
136  OptionalJacobian<2, DimK> Dcal = boost::none) const {
137  return _project(pw, Dpose, Dpoint, Dcal);
138  }
139 
142  OptionalJacobian<2, 2> Dpoint = boost::none,
143  OptionalJacobian<2, DimK> Dcal = boost::none) const {
144  return _project(pw, Dpose, Dpoint, Dcal);
145  }
146 
148  Point3 backproject(const Point2& p, double depth) const {
149  const Point2 pn = calibration().calibrate(p);
150  return pose().transform_from(backproject_from_camera(pn, depth));
151  }
152 
155  const Point2 pn = calibration().calibrate(p);
156  const Unit3 pc(pn.x(), pn.y(), 1.0); //by convention the last element is 1
157  return pose().rotation().rotate(pc);
158  }
159 
165  double range(const Point3& point,
166  OptionalJacobian<1, 6> Dcamera = boost::none,
167  OptionalJacobian<1, 3> Dpoint = boost::none) const {
168  return pose().range(point, Dcamera, Dpoint);
169  }
170 
176  double range(const Pose3& pose, OptionalJacobian<1, 6> Dcamera = boost::none,
177  OptionalJacobian<1, 6> Dpose = boost::none) const {
178  return this->pose().range(pose, Dcamera, Dpose);
179  }
180 
186  double range(const CalibratedCamera& camera, OptionalJacobian<1, 6> Dcamera =
187  boost::none, OptionalJacobian<1, 6> Dother = boost::none) const {
188  return pose().range(camera.pose(), Dcamera, Dother);
189  }
190 
196  template<class CalibrationB>
197  double range(const PinholeBaseK<CalibrationB>& camera,
198  OptionalJacobian<1, 6> Dcamera = boost::none,
199  OptionalJacobian<1, 6> Dother = boost::none) const {
200  return pose().range(camera.pose(), Dcamera, Dother);
201  }
202 
203 private:
204 
206  friend class boost::serialization::access;
207  template<class Archive>
208  void serialize(Archive & ar, const unsigned int /*version*/) {
209  ar
210  & boost::serialization::make_nvp("PinholeBase",
211  boost::serialization::base_object<PinholeBase>(*this));
212  }
213 
214 };
215 // end of class PinholeBaseK
216 
224 template<typename CALIBRATION>
225 class GTSAM_EXPORT PinholePose: public PinholeBaseK<CALIBRATION> {
226 
227 private:
228 
230  boost::shared_ptr<CALIBRATION> K_;
231 
232 public:
233 
234  enum {
235  dimension = 6
236  };
237 
240 
243  }
244 
246  explicit PinholePose(const Pose3& pose) :
247  Base(pose), K_(new CALIBRATION()) {
248  }
249 
251  PinholePose(const Pose3& pose, const boost::shared_ptr<CALIBRATION>& K) :
252  Base(pose), K_(K) {
253  }
254 
258 
266  static PinholePose Level(const boost::shared_ptr<CALIBRATION>& K,
267  const Pose2& pose2, double height) {
268  return PinholePose(Base::LevelPose(pose2, height), K);
269  }
270 
272  static PinholePose Level(const Pose2& pose2, double height) {
273  return PinholePose::Level(boost::make_shared<CALIBRATION>(), pose2, height);
274  }
275 
285  static PinholePose Lookat(const Point3& eye, const Point3& target,
286  const Point3& upVector, const boost::shared_ptr<CALIBRATION>& K =
287  boost::make_shared<CALIBRATION>()) {
288  return PinholePose(Base::LookatPose(eye, target, upVector), K);
289  }
290 
294 
296  explicit PinholePose(const Vector &v) :
297  Base(v), K_(new CALIBRATION()) {
298  }
299 
301  PinholePose(const Vector &v, const Vector &K) :
302  Base(v), K_(new CALIBRATION(K)) {
303  }
304 
308 
310  bool equals(const Base &camera, double tol = 1e-9) const {
311  const PinholePose* e = dynamic_cast<const PinholePose*>(&camera);
312  return Base::equals(camera, tol) && K_->equals(e->calibration(), tol);
313  }
314 
316  friend std::ostream& operator<<(std::ostream &os, const PinholePose& camera) {
317  os << "{R: " << camera.pose().rotation().rpy().transpose();
318  os << ", t: " << camera.pose().translation().transpose();
319  if (!camera.K_) os << ", K: none";
320  else os << ", K: " << *camera.K_;
321  os << "}";
322  return os;
323  }
324 
326  void print(const std::string& s = "PinholePose") const {
327  Base::print(s);
328  if (!K_)
329  std::cout << "s No calibration given" << std::endl;
330  else
331  K_->print(s + ".calibration");
332  }
333 
337 
338  virtual ~PinholePose() {
339  }
340 
342  const boost::shared_ptr<CALIBRATION>& sharedCalibration() const {
343  return K_;
344  }
345 
347  virtual const CALIBRATION& calibration() const {
348  return *K_;
349  }
350 
356  Point2 project2(const Point3& pw, OptionalJacobian<2, 6> Dpose = boost::none,
357  OptionalJacobian<2, 3> Dpoint = boost::none) const {
358  return Base::project(pw, Dpose, Dpoint);
359  }
360 
362  Point2 project2(const Unit3& pw, OptionalJacobian<2, 6> Dpose = boost::none,
363  OptionalJacobian<2, 2> Dpoint = boost::none) const {
364  return Base::project(pw, Dpose, Dpoint);
365  }
366 
370 
372  size_t dim() const {
373  return 6;
374  }
375 
377  static size_t Dim() {
378  return 6;
379  }
380 
382  PinholePose retract(const Vector6& d) const {
383  return PinholePose(Base::pose().retract(d), K_);
384  }
385 
387  Vector6 localCoordinates(const PinholePose& p) const {
388  return Base::pose().localCoordinates(p.Base::pose());
389  }
390 
393  return PinholePose(); // assumes that the default constructor is valid
394  }
395 
397 
398 private:
399 
401  friend class boost::serialization::access;
402  template<class Archive>
403  void serialize(Archive & ar, const unsigned int /*version*/) {
404  ar
405  & boost::serialization::make_nvp("PinholeBaseK",
406  boost::serialization::base_object<Base>(*this));
407  ar & BOOST_SERIALIZATION_NVP(K_);
408  }
409 
410 };
411 // end of class PinholePose
412 
413 template<typename CALIBRATION>
414 struct traits<PinholePose<CALIBRATION> > : public internal::Manifold<
415  PinholePose<CALIBRATION> > {
416 };
417 
418 template<typename CALIBRATION>
419 struct traits<const PinholePose<CALIBRATION> > : public internal::Manifold<
420  PinholePose<CALIBRATION> > {
421 };
422 
423 } // \ gtsam
Point2 project(const Point3 &pw) const
project a point from world coordinate to the image
Definition: PinholePose.h:91
Vector3 rpy() const
Use RQ to calculate roll-pitch-yaw angle representation.
Definition: Rot3.cpp:172
const Rot3 & rotation(OptionalJacobian< 3, 6 > H=boost::none) const
get rotation
Definition: Pose3.cpp:272
Definition: CalibratedCamera.h:240
Represents a 3D point on a unit sphere.
Definition: Unit3.h:42
Point2 _project(const POINT &pw, OptionalJacobian< 2, 6 > Dpose, OptionalJacobian< 2, FixedDimension< POINT >::value > Dpoint, OptionalJacobian< 2, DimK > Dcal) const
Templated projection of a point (possibly at infinity) from world coordinate to the image...
Definition: PinholePose.h:112
Point3 backproject(const Point2 &p, double depth) const
backproject a 2-dimensional point to a 3-dimensional point at given depth
Definition: PinholePose.h:148
static Point2 Project(const Point3 &pc, OptionalJacobian< 2, 3 > Dpoint=boost::none)
Project from 3D point in camera coordinates into image Does not throw a CheiralityException, even if pc behind image plane.
Definition: CalibratedCamera.cpp:88
void print(const Matrix &A, const string &s, ostream &stream)
print without optional string, must specify cout yourself
Definition: Matrix.cpp:140
Definition: CalibratedCamera.h:45
OptionalJacobian is an Eigen::Ref like class that can take be constructed using either a fixed size o...
Definition: OptionalJacobian.h:39
double y() const
get y
Definition: Point2.h:106
double range(const Point3 &point, OptionalJacobian< 1, 6 > Dcamera=boost::none, OptionalJacobian< 1, 3 > Dpoint=boost::none) const
Calculate range to a landmark.
Definition: PinholePose.h:165
PinholePose(const Vector &v)
Init from 6D vector.
Definition: PinholePose.h:296
Unit3 backprojectPointAtInfinity(const Point2 &p) const
backproject a 2-dimensional point to a 3-dimensional point at infinity
Definition: PinholePose.h:154
Definition: PinholePose.h:225
Definition: Pose3.h:37
Definition: Point3.h:45
double range(const PinholeBaseK< CalibrationB > &camera, OptionalJacobian< 1, 6 > Dcamera=boost::none, OptionalJacobian< 1, 6 > Dother=boost::none) const
Calculate range to a PinholePoseK derived class.
Definition: PinholePose.h:197
Point2 project2(const Point3 &pw, OptionalJacobian< 2, 6 > Dpose=boost::none, OptionalJacobian< 2, 3 > Dpoint=boost::none) const
project a point from world coordinate to the image, 2 derivatives only
Definition: PinholePose.h:356
bool equals(const Base &camera, double tol=1e-9) const
assert equality up to a tolerance
Definition: PinholePose.h:310
PinholeBaseK(const Pose3 &pose)
constructor with pose
Definition: PinholePose.h:55
2D Point
Calibrated camera for which only pose is unknown.
std::pair< Point2, bool > projectSafe(const Point3 &pw) const
Project a point into the image and check depth.
Definition: PinholePose.h:82
Point2 project(const Unit3 &pw, OptionalJacobian< 2, 6 > Dpose, OptionalJacobian< 2, 2 > Dpoint=boost::none, OptionalJacobian< 2, DimK > Dcal=boost::none) const
project a point at infinity from world coordinates into the image
Definition: PinholePose.h:141
Definition: Pose2.h:36
PinholePose(const Vector &v, const Vector &K)
Init from Vector and calibration.
Definition: PinholePose.h:301
Both ManifoldTraits and Testable.
Definition: Manifold.h:120
virtual const CALIBRATION & calibration() const
return calibration
Definition: PinholePose.h:347
Point2 project2(const Unit3 &pw, OptionalJacobian< 2, 6 > Dpose=boost::none, OptionalJacobian< 2, 2 > Dpoint=boost::none) const
project2 version for point at infinity
Definition: PinholePose.h:362
Definition: Point2.h:40
static PinholePose Level(const boost::shared_ptr< CALIBRATION > &K, const Pose2 &pose2, double height)
Create a level camera at the given 2D pose and height.
Definition: PinholePose.h:266
static PinholePose identity()
for Canonical
Definition: PinholePose.h:392
PinholePose()
default constructor
Definition: PinholePose.h:242
Point2 project2(const Point3 &point, OptionalJacobian< 2, 6 > Dpose=boost::none, OptionalJacobian< 2, 3 > Dpoint=boost::none) const
Project point into the image Throws a CheiralityException if point behind image plane iff GTSAM_THROW...
Definition: CalibratedCamera.cpp:116
double range(const CalibratedCamera &camera, OptionalJacobian< 1, 6 > Dcamera=boost::none, OptionalJacobian< 1, 6 > Dother=boost::none) const
Calculate range to a CalibratedCamera.
Definition: PinholePose.h:186
PinholePose retract(const Vector6 &d) const
move a cameras according to d
Definition: PinholePose.h:382
std::pair< Point2, bool > projectSafe(const Point3 &pw) const
Project a point into the image and check depth.
Definition: CalibratedCamera.cpp:109
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition: concepts.h:30
Vector6 localCoordinates(const PinholePose &p) const
return canonical coordinate
Definition: PinholePose.h:387
double range(const Pose3 &pose, OptionalJacobian< 1, 6 > Dcamera=boost::none, OptionalJacobian< 1, 6 > Dpose=boost::none) const
Calculate range to another pose.
Definition: PinholePose.h:176
PinholePose(const Pose3 &pose, const boost::shared_ptr< CALIBRATION > &K)
constructor with pose and calibration
Definition: PinholePose.h:251
size_t dim() const
Definition: PinholePose.h:372
Give fixed size dimension of a type, fails at compile time if dynamic.
Definition: Manifold.h:164
PinholePose(const Pose3 &pose)
constructor with pose, uses default calibration
Definition: PinholePose.h:246
void print(const std::string &s="PinholePose") const
print
Definition: PinholePose.h:326
Point2 project(const Unit3 &pw) const
project a point from world coordinate to the image
Definition: PinholePose.h:99
Definition: PinholePose.h:34
Point2 project(const Point3 &pw, OptionalJacobian< 2, 6 > Dpose, OptionalJacobian< 2, 3 > Dpoint=boost::none, OptionalJacobian< 2, DimK > Dcal=boost::none) const
project a 3D point from world coordinates into the image
Definition: PinholePose.h:134
const boost::shared_ptr< CALIBRATION > & sharedCalibration() const
return shared pointer to calibration
Definition: PinholePose.h:342
const Point3 & translation(OptionalJacobian< 3, 6 > H=boost::none) const
get translation
Definition: Pose3.cpp:265
PinholeBaseK()
default constructor
Definition: PinholePose.h:51
double range(const Point3 &point, OptionalJacobian< 1, 6 > H1=boost::none, OptionalJacobian< 1, 3 > H2=boost::none) const
Calculate range to a landmark.
Definition: Pose3.cpp:339
friend std::ostream & operator<<(std::ostream &os, const PinholePose &camera)
stream operator
Definition: PinholePose.h:316
static PinholePose Lookat(const Point3 &eye, const Point3 &target, const Point3 &upVector, const boost::shared_ptr< CALIBRATION > &K=boost::make_shared< CALIBRATION >())
Create a camera at the given eye position looking at a target point in the scene with the specified u...
Definition: PinholePose.h:285
static PinholePose Level(const Pose2 &pose2, double height)
PinholePose::level with default calibration.
Definition: PinholePose.h:272
static size_t Dim()
Definition: PinholePose.h:377
double x() const
get x
Definition: Point2.h:103
const Pose3 & pose() const
return pose, constant version
Definition: CalibratedCamera.h:146
Global functions in a separate testing namespace.
Definition: chartTesting.h:28