22 #include <boost/optional.hpp>
23 #include <boost/serialization/nvp.hpp>
24 #include <gtsam/base/DerivedValue.h>
39 template<
typename Calibration>
77 const double st = sin(pose2.
theta()), ct = cos(pose2.
theta());
78 const Point3 x(st, -ct, 0), y(0, 0, -1), z(ct, st, 0);
79 const Rot3 wRc(x, y, z);
80 const Point3 t(pose2.
x(), pose2.
y(), height);
81 const Pose3 pose3(wRc, t);
100 const Point3& upVector,
const Calibration& K = Calibration()) {
103 Point3 xc = (-upVector).cross(zc);
117 K_ = Calibration(v.tail(Calibration::Dim()));
122 pose_(Pose3::Expmap(v)), K_(K) {
136 void print(
const std::string& s =
"PinholeCamera")
const {
137 pose_.
print(s +
".pose");
138 K_.print(s +
".calibration");
174 boost::optional<Matrix&> H1 = boost::none, boost::optional<Matrix&> H2 =
178 H1->conservativeResize(
Dim(),
Dim());
181 H1->bottomRows(Calibration::Dim()) =
zeros(Calibration::Dim(),
Dim());
184 H2->conservativeResize(
Dim(),
Dim());
187 H2->bottomRows(Calibration::Dim()) =
zeros(Calibration::Dim(),
Dim());
194 boost::optional<Matrix&> H1 = boost::none, boost::optional<Matrix&> H2 =
198 H1->conservativeResize(
Dim(),
Dim());
201 H1->bottomRows(Calibration::Dim()) =
zeros(Calibration::Dim(),
Dim());
204 H2->conservativeResize(
Dim(),
Dim());
207 H2->bottomRows(Calibration::Dim()) =
zeros(Calibration::Dim(),
Dim());
214 boost::optional<Matrix&> H1 = boost::none)
const {
217 H1->conservativeResize(
Dim(),
Dim());
220 H1->bottomRows(Calibration::Dim()) =
zeros(Calibration::Dim(),
Dim());
236 if ((
size_t) d.size() == pose_.
dim())
253 inline size_t dim()
const {
254 return pose_.
dim() + K_.dim();
258 inline static size_t Dim() {
273 boost::optional<Matrix&> Dpoint = boost::none) {
274 #ifdef GTSAM_THROW_CHEIRALITY_EXCEPTION
278 double d = 1.0 / P.
z();
279 const double u = P.
x() * d, v = P.
y() * d;
281 *Dpoint = (Matrix(2, 3) << d, 0.0, -u * d, 0.0, d, -v * d);
290 return std::make_pair(K_.uncalibrate(pn), pc.
z() > 0);
301 boost::optional<Matrix&> Dpose = boost::none,
302 boost::optional<Matrix&> Dpoint = boost::none,
303 boost::optional<Matrix&> Dcal = boost::none)
const {
311 if (Dpose || Dpoint) {
312 const double z = pc.
z(), d = 1.0 / z;
316 const Point2 pi = K_.uncalibrate(pn, Dcal, Dpi_pn);
321 calculateDpose(pn, d, Dpi_pn, *Dpose);
324 Dpoint->resize(2, 3);
325 calculateDpoint(pn, d, pose_.
rotation().
matrix(), Dpi_pn, *Dpoint);
329 return K_.uncalibrate(pn, Dcal);
340 boost::optional<Matrix&> Dpose = boost::none,
341 boost::optional<Matrix&> Dpoint = boost::none,
342 boost::optional<Matrix&> Dcal = boost::none)
const {
344 if (!Dpose && !Dpoint && !Dcal) {
347 return K_.uncalibrate(pn);
351 Matrix Dpc_rot , Dpc_point ;
354 Matrix Dpc_pose = Matrix::Zero(3, 6);
355 Dpc_pose.block(0, 0, 3, 3) = Dpc_rot;
363 const Point2 pi = K_.uncalibrate(pn, Dcal, Dpi_pn);
366 const Matrix Dpi_pc = Dpi_pn * Dpn_pc;
368 *Dpose = Dpi_pc * Dpc_pose;
370 *Dpoint = (Dpi_pc * Dpc_point).block(0, 0, 2, 2);
381 boost::optional<Matrix&> Dcamera = boost::none,
382 boost::optional<Matrix&> Dpoint = boost::none)
const {
387 if (!Dcamera && !Dpoint) {
388 return K_.uncalibrate(pn);
390 const double z = pc.
z(), d = 1.0 / z;
393 Matrix Dcal, Dpi_pn(2, 2);
394 const Point2 pi = K_.uncalibrate(pn, Dcal, Dpi_pn);
397 Dcamera->resize(2, this->
dim());
398 calculateDpose(pn, d, Dpi_pn, Dcamera->leftCols<6>());
399 Dcamera->rightCols(K_.dim()) = Dcal;
402 Dpoint->resize(2, 3);
403 calculateDpoint(pn, d, pose_.
rotation().
matrix(), Dpi_pn, *Dpoint);
411 const Point2 pn = K_.calibrate(p);
412 const Point3 pc(pn.
x() * depth, pn.
y() * depth, depth);
418 const Point2 pn = K_.calibrate(p);
419 const Point3 pc(pn.
x(), pn.
y(), 1.0);
432 boost::optional<Matrix&> Dpose = boost::none,
433 boost::optional<Matrix&> Dpoint = boost::none)
const {
434 double result = pose_.
range(point, Dpose, Dpoint);
438 H1r.conservativeResize(Eigen::NoChange, pose_.
dim() + K_.dim());
439 H1r.block(0, pose_.
dim(), 1, K_.dim()) = Matrix::Zero(1, K_.dim());
453 boost::optional<Matrix&> Dpose = boost::none,
454 boost::optional<Matrix&> Dpose2 = boost::none)
const {
455 double result = pose_.
range(pose, Dpose, Dpose2);
459 H1r.conservativeResize(Eigen::NoChange, pose_.
dim() + K_.dim());
460 H1r.block(0, pose_.
dim(), 1, K_.dim()) = Matrix::Zero(1, K_.dim());
472 template<
class CalibrationB>
475 boost::optional<Matrix&> Dpose = boost::none,
476 boost::optional<Matrix&> Dother = boost::none)
const {
477 double result = pose_.
range(camera.pose_, Dpose, Dother);
481 H1r.conservativeResize(Eigen::NoChange, pose_.
dim() + K_.dim());
482 H1r.block(0, pose_.
dim(), 1, K_.dim()) = Matrix::Zero(1, K_.dim());
486 Matrix& H2r(*Dother);
487 H2r.conservativeResize(Eigen::NoChange,
504 boost::optional<Matrix&> Dpose = boost::none,
505 boost::optional<Matrix&> Dother = boost::none)
const {
506 return pose_.
range(camera.pose_, Dpose, Dother);
519 template<
typename Derived>
520 static void calculateDpose(
const Point2& pn,
double d,
const Matrix& Dpi_pn,
521 Eigen::MatrixBase<Derived>
const & Dpose) {
523 const double u = pn.
x(), v = pn.
y();
524 double uv = u * v, uu = u * u, vv = v * v;
525 Eigen::Matrix<double, 2, 6> Dpn_pose;
526 Dpn_pose << uv, -1 - uu, v, -d, 0, d * u, 1 + vv, -uv, -u, 0, -d, d * v;
527 assert(Dpose.rows()==2 && Dpose.cols()==6);
528 const_cast<Eigen::MatrixBase<Derived>&
>(Dpose) =
529 Dpi_pn.block<2, 2>(0, 0) * Dpn_pose;
540 template<
typename Derived>
541 static void calculateDpoint(
const Point2& pn,
double d,
const Matrix& R,
542 const Matrix& Dpi_pn, Eigen::MatrixBase<Derived>
const & Dpoint) {
544 const double u = pn.x(), v = pn.y();
545 Eigen::Matrix<double, 2, 3> Dpn_point;
547 R(0, 0) - u * R(0, 2), R(1, 0) - u * R(1, 2), R(2, 0) - u * R(2, 2),
548 R(0, 1) - v * R(0, 2), R(1, 1) - v * R(1, 2), R(2, 1) - v * R(2, 2);
550 assert(Dpoint.rows()==2 && Dpoint.cols()==3);
551 const_cast<Eigen::MatrixBase<Derived>&
>(Dpoint) =
552 Dpi_pn.block<2, 2>(0, 0) * Dpn_point;
561 template<
class Archive>
562 void serialize(Archive & ar,
const unsigned int version) {
563 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(
Value);
564 ar & BOOST_SERIALIZATION_NVP(pose_);
565 ar & BOOST_SERIALIZATION_NVP(K_);
Pose3 compose(const Pose3 &p2, boost::optional< Matrix & > H1=boost::none, boost::optional< Matrix & > H2=boost::none) const
compose this transformation onto another (first *this and then p2)
Definition: Pose3.cpp:272
const Rot3 & rotation() const
get rotation
Definition: Pose3.h:261
PinholeCamera(const Pose3 &pose, const Calibration &K)
constructor with pose and calibration
Definition: PinholeCamera.h:60
double range(const Point3 &point, boost::optional< Matrix & > H1=boost::none, boost::optional< Matrix & > H2=boost::none) const
Calculate range to a landmark.
Definition: Pose3.cpp:302
double norm() const
Distance of the point from the origin.
Definition: Point3.cpp:97
typedef and functions to augment Eigen's VectorXd
void print(const std::string &s="") const
print with optional string
Definition: Pose3.cpp:117
const PinholeCamera compose(const Pose3 &c) const
compose two cameras: TODO Frank says this might not make sense
Definition: PinholeCamera.h:226
std::pair< Point2, bool > projectSafe(const Point3 &pw) const
Project a point into the image and check depth.
Definition: PinholeCamera.h:287
Pose3 inverse(boost::optional< Matrix & > H1=boost::none) const
inverse transformation with derivatives
Definition: Pose3.cpp:282
static size_t Dim()
Manifold dimension.
Definition: PinholeCamera.h:258
Calibration & calibration()
return calibration
Definition: PinholeCamera.h:159
This is the interface class for any value that may be used as a variable assignment in a factor graph...
Definition: Value.h:81
size_t dim() const
Manifold dimension.
Definition: PinholeCamera.h:253
double range(const PinholeCamera< CalibrationB > &camera, boost::optional< Matrix & > Dpose=boost::none, boost::optional< Matrix & > Dother=boost::none) const
Calculate range to another camera.
Definition: PinholeCamera.h:473
Point3 unrotate(const Point3 &p, boost::optional< Matrix & > H1=boost::none, boost::optional< Matrix & > H2=boost::none) const
rotate point from world to rotated frame
Definition: Rot3.cpp:102
Matrix eye(size_t m, size_t n)
Creates an identity matrix, with matlab-like syntax.
Definition: Matrix.cpp:50
Point3 rotate(const Point3 &p, boost::optional< Matrix & > H1=boost::none, boost::optional< Matrix & > H2=boost::none) const
rotate point from rotated coordinate frame to world
Definition: Rot3M.cpp:174
Vector6 localCoordinates(const Pose3 &T2, Pose3::CoordinatesMode mode=POSE3_DEFAULT_COORDINATES_MODE) const
Local 6D coordinates of Pose3 manifold neighborhood around current pose.
Definition: Pose3.cpp:198
const Pose3 & pose() const
return pose
Definition: PinholeCamera.h:154
Point3 backprojectPointAtInfinity(const Point2 &p) const
backproject a 2-dimensional point to a 3-dimensional point at infinity
Definition: PinholeCamera.h:417
const Calibration & calibration() const
return calibration
Definition: PinholeCamera.h:164
Point2 project(const Point3 &pw, boost::optional< Matrix & > Dpose=boost::none, boost::optional< Matrix & > Dpoint=boost::none, boost::optional< Matrix & > Dcal=boost::none) const
project a point from world coordinate to the image
Definition: PinholeCamera.h:299
Point3 cross(const Point3 &q) const
cross product
Definition: Point3.cpp:86
static Point2 project_to_camera(const Point3 &P, boost::optional< Matrix & > Dpoint=boost::none)
projects a 3-dimensional point in camera coordinates into the camera and returns a 2-dimensional poin...
Definition: PinholeCamera.h:272
PinholeCamera(const Pose3 &pose)
constructor with pose
Definition: PinholeCamera.h:55
PinholeCamera()
default constructor
Definition: PinholeCamera.h:51
Definition: PinholeCamera.h:40
Definition: CalibratedCamera.h:42
bool equals(const Pose3 &pose, double tol=1e-9) const
assert equality up to a tolerance
Definition: Pose3.cpp:124
double z() const
get z
Definition: Point3.h:205
Point3 transform_from(const Point3 &p, boost::optional< Matrix & > Dpose=boost::none, boost::optional< Matrix & > Dpoint=boost::none) const
takes point in Pose coordinates and transforms it to world coordinates
Definition: Pose3.cpp:243
Matrix3 matrix() const
return 3*3 rotation matrix
Definition: Rot3M.cpp:281
Definition: CalibratedCamera.h:27
Pose3 retract(const Vector &d, Pose3::CoordinatesMode mode=POSE3_DEFAULT_COORDINATES_MODE) const
Retraction from R^6 to Pose3 manifold neighborhood around current pose.
Definition: Pose3.cpp:181
double range(const CalibratedCamera &camera, boost::optional< Matrix & > Dpose=boost::none, boost::optional< Matrix & > Dother=boost::none) const
Calculate range to another camera.
Definition: PinholeCamera.h:502
double y() const
get y
Definition: Point3.h:202
double x() const
get x
Definition: Pose2.h:203
static PinholeCamera Level(const Calibration &K, const Pose2 &pose2, double height)
Create a level camera at the given 2D pose and height.
Definition: PinholeCamera.h:75
const PinholeCamera inverse(boost::optional< Matrix & > H1=boost::none) const
inverse camera: TODO Frank says this might not make sense
Definition: PinholeCamera.h:213
static PinholeCamera Level(const Pose2 &pose2, double height)
PinholeCamera::level with default calibration.
Definition: PinholeCamera.h:86
Point2 projectPointAtInfinity(const Point3 &pw, boost::optional< Matrix & > Dpose=boost::none, boost::optional< Matrix & > Dpoint=boost::none, boost::optional< Matrix & > Dcal=boost::none) const
project a point at infinity from world coordinate to the image
Definition: PinholeCamera.h:338
double y() const
get y
Definition: Point2.h:213
static PinholeCamera Lookat(const Point3 &eye, const Point3 &target, const Point3 &upVector, const Calibration &K=Calibration())
Create a camera at the given eye position looking at a target point in the scene with the specified u...
Definition: PinholeCamera.h:99
double y() const
get y
Definition: Pose2.h:206
double range(const Point3 &point, boost::optional< Matrix & > Dpose=boost::none, boost::optional< Matrix & > Dpoint=boost::none) const
Calculate range to a landmark.
Definition: PinholeCamera.h:430
const PinholeCamera between(const PinholeCamera &c, boost::optional< Matrix & > H1=boost::none, boost::optional< Matrix & > H2=boost::none) const
between two cameras: TODO Frank says this might not make sense
Definition: PinholeCamera.h:193
Point2 project2(const Point3 &pw, boost::optional< Matrix & > Dcamera=boost::none, boost::optional< Matrix & > Dpoint=boost::none) const
project a point from world coordinate to the image
Definition: PinholeCamera.h:379
typedef and functions to augment Eigen's MatrixXd
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
Pose3 between(const Pose3 &p2, boost::optional< Matrix & > H1=boost::none, boost::optional< Matrix & > H2=boost::none) const
Return relative pose between p1 and p2, in p1 coordinate frame as well as optionally the derivatives...
Definition: Pose3.cpp:291
Calibrated camera for which only pose is unknown.
double x() const
get x
Definition: Point3.h:199
double x() const
get x
Definition: Point2.h:210
friend class boost::serialization::access
Serialization function.
Definition: PinholeCamera.h:560
bool equals(const PinholeCamera &camera, double tol=1e-9) const
assert equality up to a tolerance
Definition: PinholeCamera.h:130
static Pose3 Expmap(const Vector &xi)
Exponential map at identity - create a rotation from canonical coordinates .
Definition: Pose3.cpp:130
static size_t Dim()
Dimensionality of tangent space = 6 DOF - used to autodetect sizes.
Definition: Pose3.h:134
void print(const std::string &s="PinholeCamera") const
print
Definition: PinholeCamera.h:136
double theta() const
get theta
Definition: Pose2.h:209
Point3 backproject(const Point2 &p, double depth) const
backproject a 2-dimensional point to a 3-dimensional point at given depth
Definition: PinholeCamera.h:410
Vector localCoordinates(const PinholeCamera &T2) const
return canonical coordinate
Definition: PinholeCamera.h:244
Definition: DerivedValue.h:44
double range(const Pose3 &pose, boost::optional< Matrix & > Dpose=boost::none, boost::optional< Matrix & > Dpose2=boost::none) const
Calculate range to another pose.
Definition: PinholeCamera.h:451
PinholeCamera retract(const Vector &d) const
move a cameras according to d
Definition: PinholeCamera.h:235
const PinholeCamera compose(const PinholeCamera &c, boost::optional< Matrix & > H1=boost::none, boost::optional< Matrix & > H2=boost::none) const
compose two cameras: TODO Frank says this might not make sense
Definition: PinholeCamera.h:173
Pose3 & pose()
return pose
Definition: PinholeCamera.h:149
size_t dim() const
Dimensionality of the tangent space = 6 DOF.
Definition: Pose3.h:139
Matrix zeros(size_t m, size_t n)
Creates an zeros matrix, with matlab-like syntax.
Definition: Matrix.cpp:40