26 #include <gtsam/inference/Symbol.h>
29 #include <boost/optional.hpp>
30 #include <boost/make_shared.hpp>
48 bool calculatedHessian;
51 std::vector<Matrix> Gs;
52 std::vector<Vector> gs;
56 enum LinearizationMode {
57 HESSIAN, JACOBIAN_SVD, JACOBIAN_Q
64 template<
class POSE,
class LANDMARK,
class CALIBRATION,
size_t D>
82 mutable bool degenerate_;
83 mutable bool cheiralityException_;
89 boost::shared_ptr<SmartProjectionFactorState> state_;
97 double landmarkDistanceThreshold_;
100 double dynamicOutlierRejectionThreshold_;
114 typedef std::vector<Camera> Cameras;
126 const bool manageDegeneracy,
const bool enableEPI,
127 boost::optional<POSE> body_P_sensor = boost::none,
128 double landmarkDistanceThreshold = 1e10,
129 double dynamicOutlierRejectionThreshold = -1,
133 linThreshold), degenerate_(false), cheiralityException_(false),
throwCheirality_(
135 landmarkDistanceThreshold_(landmarkDistanceThreshold),
136 dynamicOutlierRejectionThreshold_(dynamicOutlierRejectionThreshold) {
149 DefaultKeyFormatter)
const {
150 std::cout << s <<
"SmartProjectionFactor, z = \n";
152 std::cout <<
"degenerate_ = " << degenerate_ << std::endl;
153 std::cout <<
"cheiralityException_ = " << cheiralityException_ << std::endl;
163 size_t m = cameras.size();
165 bool retriangulate =
false;
170 retriangulate =
true;
172 if (!retriangulate) {
173 for (
size_t i = 0; i < cameras.size(); i++) {
176 retriangulate =
true;
185 for (
size_t i = 0; i < m; i++)
190 return retriangulate;
207 Pose3 firstCameraPose, firstCameraPoseOld;
208 for (
size_t i = 0; i < cameras.size(); i++) {
211 firstCameraPose = cameras[i].pose();
217 Pose3 localCameraPose = firstCameraPose.
between(cameras[i].pose());
220 if (!localCameraPose.
equals(localCameraPoseOld,
221 this->linearizationThreshold_))
235 size_t m = cameras.size();
249 cheiralityException_ =
false;
252 double totalReprojError = 0.0;
254 BOOST_FOREACH(
const Camera& camera, cameras) {
257 if(cameraTranslation.
distance(
point_) > landmarkDistanceThreshold_){
261 const Point2& zi = this->measured_.at(i);
266 cheiralityException_ =
true;
271 if(dynamicOutlierRejectionThreshold_ > 0 &&
272 totalReprojError/m > dynamicOutlierRejectionThreshold_)
281 cheiralityException_ =
false;
285 cheiralityException_ =
true;
294 bool isDebug =
false;
299 && (this->cheiralityException_ || this->degenerate_))) {
301 std::cout <<
"createImplicitSchurFactor: degenerate configuration"
308 if (this->cheiralityException_ || this->degenerate_) {
309 this->degenerate_ =
true;
317 const Cameras&
cameras,
const double lambda = 0.0)
const {
319 bool isDebug =
false;
320 size_t numKeys = this->
keys_.size();
322 std::vector < Key > js;
323 std::vector < Matrix > Gs(numKeys * (numKeys + 1) / 2);
324 std::vector < Vector > gs(numKeys);
326 if (this->
measured_.size() != cameras.size()) {
328 <<
"SmartProjectionHessianFactor: this->measured_.size() inconsistent with input"
337 && (this->cheiralityException_ || this->degenerate_))) {
339 BOOST_FOREACH(gtsam::Matrix& m, Gs)
341 BOOST_FOREACH(Vector& v, gs)
343 return boost::make_shared<RegularHessianFactor<D> >(this->
keys_, Gs, gs,
348 if (this->cheiralityException_ || this->degenerate_) {
349 this->degenerate_ =
true;
355 for (
size_t i = 0; i < cameras.size(); i++)
359 std::cout <<
"=============================" << std::endl;
360 std::cout <<
"doLinearize " << doLinearize << std::endl;
361 std::cout <<
"this->linearizationThreshold_ "
363 std::cout <<
"this->degenerate_ " << this->degenerate_ << std::endl;
365 <<
"something wrong in SmartProjectionHessianFactor: selective relinearization should be disabled"
368 return boost::make_shared<RegularHessianFactor<D> >(this->
keys_,
369 this->state_->Gs, this->state_->gs, this->state_->f);
381 Matrix H(D * numKeys, D * numKeys);
384 H.noalias() = F.transpose() * (F - (E * (PointCov * (E.transpose() * F))));
385 gs_vector.noalias() = F.transpose()
386 * (b - (E * (PointCov * (E.transpose() * b))));
388 std::cout <<
"gs_vector size " << gs_vector.size() << std::endl;
394 gs.at(i1) = gs_vector.segment < D > (i1D);
397 Gs.at(GsCount2) = H.block < D, D > (i1D, i2 * D);
404 this->state_->Gs = Gs;
405 this->state_->gs = gs;
408 return boost::make_shared<RegularHessianFactor<D> >(this->
keys_, Gs, gs, f);
412 boost::shared_ptr<ImplicitSchurFactor<D> > createImplicitSchurFactor(
413 const Cameras&
cameras,
double lambda)
const {
415 return Base::createImplicitSchurFactor(cameras,
point_, lambda);
417 return boost::shared_ptr<ImplicitSchurFactor<D> >();
422 const Cameras& cameras,
double lambda)
const {
424 return Base::createJacobianQFactor(cameras,
point_, lambda);
426 return boost::make_shared< JacobianFactorQ<D> >(this->
keys_);
431 const Values& values,
double lambda)
const {
438 return boost::make_shared< JacobianFactorQ<D> >(this->
keys_);
443 double lambda)
const {
445 return Base::createJacobianSVDFactor(cameras,
point_, lambda);
447 return boost::make_shared< JacobianFactorSVD<D> >(this->
keys_);
452 Cameras& myCameras)
const {
456 BOOST_FOREACH(
const Key key, this->
keys_)
457 valuesFactor.
insert(key, values.
at(key));
459 myCameras = this->
cameras(valuesFactor);
464 && (this->cheiralityException_ || this->degenerate_)))
468 if (this->cheiralityException_ || this->degenerate_)
469 this->degenerate_ =
true;
471 if (this->degenerate_) {
472 std::cout <<
"SmartProjectionFactor: this is not ready" << std::endl;
473 std::cout <<
"this->cheiralityException_ " << this->cheiralityException_
475 std::cout <<
"this->degenerate_ " << this->degenerate_ << std::endl;
486 return nonDegenerate;
490 void computeEP(Matrix& E, Matrix& PointCov,
const Cameras& cameras)
const {
496 Matrix& E, Matrix& PointCov, Vector& b,
const Values& values)
const {
501 return nonDegenerate;
508 Matrix& E, Vector& b,
const Cameras& cameras)
const {
510 if (this->degenerate_) {
512 std::cout <<
"point " <<
point_ << std::endl;
514 <<
"SmartProjectionFactor: Management of degeneracy is disabled - not ready to be used"
518 <<
"Management of degeneracy is not yet ready when one also optimizes for the calibration "
522 int numKeys = this->
keys_.size();
523 E =
zeros(2 * numKeys, 2);
524 b =
zero(2 * numKeys);
526 for (
size_t i = 0; i < this->
measured_.size(); i++) {
528 this->
point_ = cameras[i].backprojectPointAtInfinity(
533 Vector bi = -(cameras[i].projectPointAtInfinity(this->
point_, Fi, Ei)
536 this->
noise_.at(i)->WhitenSystem(Fi, Ei, bi);
537 f += bi.squaredNorm();
538 Fblocks.push_back(
typename Base::KeyMatrix2D(this->
keys_[i], Fi));
539 E.block < 2, 2 > (2 * i, 0) = Ei;
551 Matrix& E, Matrix& PointCov, Vector& b,
const Cameras& cameras,
552 const double lambda = 0.0)
const {
557 PointCov.noalias() = (E.transpose() * E + lambda *
eye(E.cols())).inverse();
564 Matrix& Enull, Vector& b,
const Values& values)
const {
565 typename Base::Cameras myCameras;
574 Matrix& Enull, Vector& b,
const Cameras& cameras)
const {
581 const Cameras& cameras)
const {
587 const Cameras& cameras,
const double lambda)
const {
604 return zero(myCameras.size() * 2);
614 boost::optional<Point3> externalPoint = boost::none)
const {
618 nrCameras = this->
keys_.size();
621 cheiralityException_ =
false;
628 && (this->cheiralityException_ || this->degenerate_))) {
634 if (this->cheiralityException_) {
636 <<
"SmartProjectionHessianFactor: cheirality exception (this should not happen if CheiralityException is disabled)!"
638 this->degenerate_ =
true;
641 if (this->degenerate_) {
644 <<
"SmartProjectionHessianFactor: trying to manage degeneracy (this should not happen is manageDegeneracy is disabled)!"
647 double overallError = 0;
648 BOOST_FOREACH(
const Camera& camera, cameras) {
669 boost::optional<Point3>
point()
const {
681 return (cheiralityException_ || degenerate_);
686 return cheiralityException_;
701 friend class boost::serialization::access;
702 template<
class ARCHIVE>
703 void serialize(ARCHIVE & ar,
const unsigned int version) {
704 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(
Base);
const double rankTolerance_
threshold to decide whether triangulation is degenerate_
Definition: SmartProjectionFactor.h:69
void computeEP(Matrix &E, Matrix &PointCov, const Cameras &cameras, const Point3 &point) const
Assumes non-degenerate !
Definition: SmartFactorBase.h:235
bool decideIfTriangulate(const Cameras &cameras) const
Check if the new linearization point_ is the same as the one used for previous triangulation.
Definition: SmartProjectionFactor.h:158
boost::shared_ptr< RegularHessianFactor< D > > createHessianFactor(const Cameras &cameras, const double lambda=0.0) const
linearize returns a Hessianfactor that is an approximation of error(p)
Definition: SmartProjectionFactor.h:316
const double retriangulationThreshold_
threshold to decide whether to re-triangulate
Definition: SmartProjectionFactor.h:70
bool triangulateForLinearize(const Cameras &cameras) const
triangulate
Definition: SmartProjectionFactor.h:292
bool throwCheirality() const
return flag for throwing cheirality exceptions
Definition: SmartProjectionFactor.h:694
double computeJacobiansSVD(std::vector< KeyMatrix2D > &Fblocks, Matrix &Enull, Vector &b, const Cameras &cameras, const Point3 &point, double lambda=0.0, bool diagonalDamping=false) const
SVD version.
Definition: SmartFactorBase.h:342
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
SmartProjectionFactor: triangulates point TODO: why LANDMARK parameter?
Definition: SmartProjectionFactor.h:65
boost::shared_ptr< JacobianFactorQ< D > > createJacobianQFactor(const Values &values, double lambda) const
Create a factor, takes values.
Definition: SmartProjectionFactor.h:430
PinholeCamera< CALIBRATION > Camera
shorthand for a pinhole camera
Definition: SmartProjectionFactor.h:113
const double linearizationThreshold_
threshold to decide whether to re-linearize
Definition: SmartProjectionFactor.h:77
Matrix eye(size_t m, size_t n)
Creates an identity matrix, with matlab-like syntax.
Definition: Matrix.cpp:50
std::vector< Pose3 > cameraPosesLinearization_
current linearization poses
Definition: SmartProjectionFactor.h:78
const Point3 & translation() const
get translation
Definition: Pose3.h:264
Point3 backprojectPointAtInfinity(const Point2 &p) const
backproject a 2-dimensional point to a 3-dimensional point at infinity
Definition: PinholeCamera.h:417
FastVector< Key > keys_
The keys involved in this factor.
Definition: Factor.h:69
double computeJacobians(std::vector< typename Base::KeyMatrix2D > &Fblocks, Matrix &E, Matrix &PointCov, Vector &b, const Cameras &cameras, const double lambda=0.0) const
Version that computes PointCov, with optional lambda parameter.
Definition: SmartProjectionFactor.h:550
Exception thrown by triangulateDLT when SVD returns rank < 3.
Definition: triangulation.h:32
double distance(const Point3 &p2) const
distance between two points
Definition: Point3.h:167
bool computeJacobians(std::vector< typename Base::KeyMatrix2D > &Fblocks, Matrix &E, Matrix &PointCov, Vector &b, const Values &values) const
Version that takes values, and creates the point.
Definition: SmartProjectionFactor.h:495
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
std::vector< Pose3 > cameraPosesTriangulation_
current triangulation poses
Definition: SmartProjectionFactor.h:71
This is the base class for all factor types.
Definition: Factor.h:51
const bool enableEPI_
if set to true, will refine triangulation using LM
Definition: SmartProjectionFactor.h:75
std::vector< Point2 > measured_
2D measurement for each of the m views
Definition: SmartFactorBase.h:44
bool decideIfLinearize(const Cameras &cameras) const
This function checks if the new linearization point_ is 'close' to the previous one used for lineariz...
Definition: SmartProjectionFactor.h:194
Point3 point_
Current estimate of the 3D point.
Definition: SmartProjectionFactor.h:80
Vector reprojectionError(const Cameras &cameras) const
Calculate vector of re-projection errors, before applying noise model Assumes triangulation was done ...
Definition: SmartProjectionFactor.h:593
A non-templated config holding any types of Manifold-group elements.
Definition: Values.h:75
bool zero(const Vector &v)
check if all zero
Definition: Vector.cpp:39
utility functions for loading datasets
bool computeEP(Matrix &E, Matrix &PointCov, const Values &values) const
Takes values.
Definition: SmartProjectionFactor.h:481
SmartProjectionFactor(const double rankTol, const double linThreshold, const bool manageDegeneracy, const bool enableEPI, boost::optional< POSE > body_P_sensor=boost::none, double landmarkDistanceThreshold=1e10, double dynamicOutlierRejectionThreshold=-1, SmartFactorStatePtr state=SmartFactorStatePtr(new SmartProjectionFactorState()))
Constructor.
Definition: SmartProjectionFactor.h:125
void subInsert(Vector &fullVector, const Vector &subVector, size_t i)
Inserts a subvector into a vector IN PLACE.
Definition: Vector.cpp:180
bool isDegenerate() const
return the degenerate state
Definition: SmartProjectionFactor.h:680
Definition: PinholeCamera.h:40
boost::optional< Point3 > point(const Values &values) const
COMPUTE the landmark.
Definition: SmartProjectionFactor.h:674
Functions for triangulation.
double totalReprojectionError(const Cameras &cameras, boost::optional< Point3 > externalPoint=boost::none) const
Calculate the error of the factor.
Definition: SmartProjectionFactor.h:613
bool equals(const Pose3 &pose, double tol=1e-9) const
assert equality up to a tolerance
Definition: Pose3.cpp:124
Base class with no internal point, completely functional.
Definition: SmartFactorBase.h:40
size_t triangulateSafe(const Values &values) const
triangulateSafe
Definition: SmartProjectionFactor.h:228
const ValueType & at(Key j) const
Retrieve a variable by key j.
Definition: Values-inl.h:219
Definition: CalibratedCamera.h:27
bool isPointBehindCamera() const
return the cheirality status flag
Definition: SmartProjectionFactor.h:685
void computeEP(Matrix &E, Matrix &PointCov, const Cameras &cameras) const
Assumes non-degenerate !
Definition: SmartProjectionFactor.h:490
std::vector< SharedNoiseModel > noise_
noise model used
Definition: SmartFactorBase.h:45
virtual ~SmartProjectionFactor()
Virtual destructor.
Definition: SmartProjectionFactor.h:140
size_t Key
Integer nonlinear key type.
Definition: types.h:59
double computeJacobiansSVD(std::vector< typename Base::KeyMatrix2D > &Fblocks, Matrix &Enull, Vector &b, const Cameras &cameras) const
SVD version.
Definition: SmartProjectionFactor.h:573
bool computeJacobiansSVD(std::vector< typename Base::KeyMatrix2D > &Fblocks, Matrix &Enull, Vector &b, const Values &values) const
takes values
Definition: SmartProjectionFactor.h:563
boost::shared_ptr< SmartProjectionFactorState > SmartFactorStatePtr
shorthand for smart projection factor state variable
Definition: SmartProjectionFactor.h:92
ptrdiff_t DenseIndex
The index type for Eigen objects.
Definition: types.h:74
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
const bool verboseCheirality_
If true, prints text for Cheirality exceptions (default: false)
Definition: SmartProjectionFactor.h:87
bool verboseCheirality() const
return chirality verbosity
Definition: SmartProjectionFactor.h:689
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
double computeJacobians(Matrix &F, Matrix &E, Matrix3 &PointCov, Vector &b, const Cameras &cameras, const double lambda) const
Returns Matrix, TODO: maybe should not exist -> not sparse !
Definition: SmartProjectionFactor.h:586
void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
print
Definition: SmartFactorBase.h:153
Vector reprojectionError(const Values &values) const
Calculate vector of re-projection errors, before applying noise model.
Definition: SmartProjectionFactor.h:598
const bool manageDegeneracy_
if set to true will use the rotation-only version for degenerate cases
Definition: SmartProjectionFactor.h:73
void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
print
Definition: SmartProjectionFactor.h:148
Definition: SmartProjectionFactor.h:39
double totalReprojectionError(const Cameras &cameras, const Point3 &point) const
Calculate the error of the factor.
Definition: SmartFactorBase.h:212
Exception thrown by triangulateDLT when landmark is behind one or more of the cameras.
Definition: triangulation.h:40
Vector reprojectionError(const Cameras &cameras, const Point3 &point) const
Calculate vector of re-projection errors, before applying noise model.
Definition: SmartFactorBase.h:183
boost::optional< Point3 > point() const
return the landmark
Definition: SmartProjectionFactor.h:669
double computeJacobians(std::vector< KeyMatrix2D > &Fblocks, Matrix &E, Vector &b, const Cameras &cameras, const Point3 &point) const
Compute F, E only (called below in both vanilla and SVD versions) Given a Point3, assumes dimensional...
Definition: SmartFactorBase.h:261
boost::shared_ptr< JacobianFactorQ< D > > createJacobianQFactor(const Cameras &cameras, double lambda) const
create factor
Definition: SmartProjectionFactor.h:421
SmartFactorBase< POSE, CALIBRATION, D > Base
shorthand for base class type
Definition: SmartProjectionFactor.h:95
size_t triangulateSafe(const Cameras &cameras) const
triangulateSafe
Definition: SmartProjectionFactor.h:233
const bool throwCheirality_
If true, rethrows Cheirality exceptions (default: false)
Definition: SmartProjectionFactor.h:86
boost::shared_ptr< This > shared_ptr
shorthand for a smart pointer to a factor
Definition: SmartProjectionFactor.h:110
Pose3 & pose()
return pose
Definition: PinholeCamera.h:149
double computeJacobians(std::vector< typename Base::KeyMatrix2D > &Fblocks, Matrix &E, Vector &b, const Cameras &cameras) const
Compute F, E only (called below in both vanilla and SVD versions) Assumes the point has been computed...
Definition: SmartProjectionFactor.h:507
boost::shared_ptr< JacobianFactor > createJacobianSVDFactor(const Cameras &cameras, double lambda) const
different (faster) way to compute Jacobian factor
Definition: SmartProjectionFactor.h:442
Matrix zeros(size_t m, size_t n)
Creates an zeros matrix, with matlab-like syntax.
Definition: Matrix.cpp:40
bool computeCamerasAndTriangulate(const Values &values, Cameras &myCameras) const
Returns true if nonDegenerate.
Definition: SmartProjectionFactor.h:451
boost::function< std::string(Key)> KeyFormatter
Typedef for a function to format a key, i.e. to convert it to a string.
Definition: types.h:62
double computeJacobiansSVD(Matrix &F, Matrix &Enull, Vector &b, const Cameras &cameras) const
Returns Matrix, TODO: maybe should not exist -> not sparse !
Definition: SmartProjectionFactor.h:580
Base class to create smart factors on poses or cameras.
SmartProjectionFactor< POSE, LANDMARK, CALIBRATION, D > This
shorthand for this class
Definition: SmartProjectionFactor.h:105
virtual Cameras cameras(const Values &values) const =0
Cameras are computed in derived class.