ConcurrentCalibration.cpp
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 #include <gtsam/geometry/Pose3.h>
22 #include <gtsam/nonlinear/Values.h>
27 #include <gtsam/inference/Symbol.h>
30 #include <gtsam/slam/dataset.h>
31 
32 #include <string>
33 #include <fstream>
34 #include <iostream>
35 
36 using namespace std;
37 using namespace gtsam;
41 
42 int main(int argc, char** argv){
43 
44  Values initial_estimate;
46  const auto model = noiseModel::Isotropic::Sigma(2,1);
47 
48  string calibration_loc = findExampleDataFile("VO_calibration00s.txt");
49  string pose_loc = findExampleDataFile("VO_camera_poses00s.txt");
50  string factor_loc = findExampleDataFile("VO_stereo_factors00s.txt");
51 
52  //read camera calibration info from file
53  // focal lengths fx, fy, skew s, principal point u0, v0, baseline b
54  double fx, fy, s, u0, v0, b;
55  ifstream calibration_file(calibration_loc.c_str());
56  cout << "Reading calibration info" << endl;
57  calibration_file >> fx >> fy >> s >> u0 >> v0 >> b;
58 
59  //create stereo camera calibration object
60  const Cal3_S2 true_K(fx,fy,s,u0,v0);
61  const Cal3_S2 noisy_K(fx*1.2,fy*1.2,s,u0-10,v0+10);
62 
63  initial_estimate.insert(K(0), noisy_K);
64 
65  auto calNoise = noiseModel::Diagonal::Sigmas((Vector(5) << 500, 500, 1e-5, 100, 100).finished());
66  graph.addPrior(K(0), noisy_K, calNoise);
67 
68 
69  ifstream pose_file(pose_loc.c_str());
70  cout << "Reading camera poses" << endl;
71  int pose_id;
72  MatrixRowMajor m(4,4);
73  //read camera pose parameters and use to make initial estimates of camera poses
74  while (pose_file >> pose_id) {
75  for (int i = 0; i < 16; i++) {
76  pose_file >> m.data()[i];
77  }
78  initial_estimate.insert(Symbol('x', pose_id), Pose3(m));
79  }
80 
81  auto poseNoise = noiseModel::Isotropic::Sigma(6, 0.01);
82  graph.addPrior(Symbol('x', pose_id), Pose3(m), poseNoise);
83 
84  // camera and landmark keys
85  size_t x, l;
86 
87  // pixel coordinates uL, uR, v (same for left/right images due to rectification)
88  // landmark coordinates X, Y, Z in camera frame, resulting from triangulation
89  double uL, uR, v, _X, Y, Z;
90  ifstream factor_file(factor_loc.c_str());
91  cout << "Reading stereo factors" << endl;
92  //read stereo measurement details from file and use to create and add GenericStereoFactor objects to the graph representation
93  while (factor_file >> x >> l >> uL >> uR >> v >> _X >> Y >> Z) {
94 // graph.emplace_shared<GenericStereoFactor<Pose3, Point3> >(StereoPoint2(uL, uR, v), model, X(x), L(l), K);
95 
96  graph.emplace_shared<GeneralSFMFactor2<Cal3_S2> >(Point2(uL,v), model, X(x), L(l), K(0));
97 
98 
99  //if the landmark variable included in this factor has not yet been added to the initial variable value estimate, add it
100  if (!initial_estimate.exists(L(l))) {
101  Pose3 camPose = initial_estimate.at<Pose3>(X(x));
102  //transformFrom() transforms the input Point3 from the camera pose space, camPose, to the global space
103  Point3 worldPoint = camPose.transformFrom(Point3(_X, Y, Z));
104  initial_estimate.insert(L(l), worldPoint);
105  }
106  }
107 
108  Pose3 first_pose = initial_estimate.at<Pose3>(Symbol('x',1));
109  //constrain the first pose such that it cannot change from its original value during optimization
110  // NOTE: NonlinearEquality forces the optimizer to use QR rather than Cholesky
111  // QR is much slower than Cholesky, but numerically more stable
112  graph.emplace_shared<NonlinearEquality<Pose3> >(Symbol('x',1),first_pose);
113 
114  cout << "Optimizing" << endl;
116  params.verbosityLM = LevenbergMarquardtParams::TRYLAMBDA;
117  params.verbosity = NonlinearOptimizerParams::ERROR;
118 
119  //create Levenberg-Marquardt optimizer to optimize the factor graph
120  LevenbergMarquardtOptimizer optimizer(graph, initial_estimate,params);
121 // Values result = optimizer.optimize();
122 
123  string K_values_file = "K_values.txt";
124  ofstream stream_K(K_values_file.c_str());
125 
126  double currentError;
127 
128 
129  stream_K << optimizer.iterations() << " " << optimizer.values().at<Cal3_S2>(K(0)).vector().transpose() << endl;
130 
131 
132  // Iterative loop
133  do {
134  // Do next iteration
135  currentError = optimizer.error();
136  optimizer.iterate();
137 
138  stream_K << optimizer.iterations() << " " << optimizer.values().at<Cal3_S2>(K(0)).vector().transpose() << endl;
139 
140  if(params.verbosity >= NonlinearOptimizerParams::ERROR) cout << "newError: " << optimizer.error() << endl;
141  } while(optimizer.iterations() < params.maxIterations &&
143  params.errorTol, currentError, optimizer.error(), params.verbosity));
144 
145  Values result = optimizer.values();
146 
147  cout << "Final result sample:" << endl;
148  Values pose_values = utilities::allPose3s(result);
149  pose_values.print("Final camera poses:\n");
150 
151  result.at<Cal3_S2>(K(0)).print("Final K\n");
152 
153  noisy_K.print("Initial noisy K\n");
154  true_K.print("Initial correct K\n");
155 
156  return 0;
157 }
Matrix3f m
const char Y
Scalar * b
Definition: benchVecAdd.cpp:17
IsDerived< DERIVEDFACTOR > emplace_shared(Args &&... args)
Emplace a shared pointer to factor of given type.
Definition: FactorGraph.h:196
A non-templated config holding any types of Manifold-group elements.
Factor Graph consisting of non-linear factors.
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar * data() const
noiseModel::Diagonal::shared_ptr model
const ValueType at(Key j) const
Definition: Values-inl.h:204
Vector2 Point2
Definition: Point2.h:32
size_t iterations() const
return number of iterations in current optimizer state
static Cal3_S2 K(500, 500, 0.1, 640/2, 480/2)
Verbosity verbosity
The printing verbosity during optimization (default SILENT)
MatrixXd L
Definition: LLT_example.cpp:6
Definition: BFloat16.h:88
EIGEN_STRONG_INLINE Packet4f print(const Packet4f &a)
const Values & values() const
return values in current optimizer state
NonlinearFactorGraph graph
double absoluteErrorTol
The maximum absolute error decrease to stop iterating (default 1e-5)
static const SmartProjectionParams params
void addPrior(Key key, const T &prior, const SharedNoiseModel &model=nullptr)
double relativeErrorTol
The maximum relative error decrease to stop iterating (default 1e-5)
bool checkConvergence(double relativeErrorTreshold, double absoluteErrorTreshold, double errorThreshold, double currentError, double newError, NonlinearOptimizerParams::Verbosity verbosity)
double errorTol
The maximum total error to stop iterating (default 0.0)
static Pose3 camPose(Rot3((Matrix3()<< 1., 0., 0., 0.,-1., 0., 0., 0.,-1.).finished()), Point3(0, 0, 6.25))
#define Z
Definition: icosphere.cpp:21
void print(const std::string &str="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
Definition: Values.cpp:66
static const Line3 l(Rot3(), 1, 1)
const double fy
Values result
Array< int, Dynamic, 1 > v
Point3 transformFrom(const Point3 &point, OptionalJacobian< 3, 6 > Hself={}, OptionalJacobian< 3, 3 > Hpoint={}) const
takes point in Pose coordinates and transforms it to world coordinates
Definition: Pose3.cpp:347
A nonlinear optimizer that uses the Levenberg-Marquardt trust-region scheme.
Array< double, 1, 3 > e(1./3., 0.5, 2.)
RealScalar s
Values allPose3s(const Values &values)
Extract all Pose3 values.
The most common 5DOF 3D->2D calibration.
Definition: Cal3_S2.h:34
static const double u0
Reprojection of a LANDMARK to a 2D point.
traits
Definition: chartTesting.h:28
GTSAM_EXPORT std::string findExampleDataFile(const std::string &name)
Definition: dataset.cpp:70
static const double v0
GaussianFactorGraph::shared_ptr iterate() override
int main(int argc, char **argv)
void insert(Key j, const Value &val)
Definition: Values.cpp:155
Vector3 Point3
Definition: Point3.h:38
const double fx
The matrix class, also used for vectors and row-vectors.
VerbosityLM verbosityLM
The verbosity level for Levenberg-Marquardt (default: SILENT), see also NonlinearOptimizerParams::ver...
#define X
Definition: icosphere.cpp:20
a general SFM factor with an unknown calibration
bool exists(Key j) const
Definition: Values.cpp:93
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy x
3D Pose
double error() const
return error in current optimizer state
Eigen::Matrix< double, Eigen::Dynamic, 1 > Vector
utility functions for loading datasets
void print(const std::string &s="Cal3_S2") const override
print with optional string
Definition: Cal3_S2.cpp:34
size_t maxIterations
The maximum iterations to stop iterating (default 100)


gtsam
Author(s):
autogenerated on Tue Jul 4 2023 02:34:03