g2o
Loading...
Searching...
No Matches
Classes | Namespaces | Typedefs | Functions
bal_example.cpp File Reference
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <cassert>
#include <iostream>
#include <string_view>
#include "g2o/autodiff/autodiff.h"
#include "g2o/core/auto_differentiation.h"
#include "g2o/core/base_binary_edge.h"
#include "g2o/core/base_vertex.h"
#include "g2o/core/batch_stats.h"
#include "g2o/core/block_solver.h"
#include "g2o/core/optimization_algorithm_levenberg.h"
#include "g2o/core/solver.h"
#include "g2o/core/sparse_optimizer.h"
#include "g2o/solvers/pcg/linear_solver_pcg.h"
#include "g2o/stuff/command_args.h"
#include "g2o/solvers/eigen/linear_solver_eigen.h"
Include dependency graph for bal_example.cpp:

Go to the source code of this file.

Classes

class  VertexCameraBAL
 camera vertex which stores the parameters for a pinhole camera More...
 
class  VertexPointBAL
 3D world feature More...
 
class  EdgeObservationBAL
 edge representing the observation of a world feature by a camera More...
 

Namespaces

namespace  g2o
 
namespace  g2o::bal
 

Typedefs

using g2o::bal::Vector9 = VectorN< 9 >
 

Functions

int main (int argc, char **argv)
 

Function Documentation

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 212 of file bal_example.cpp.

212 {
213 int maxIterations;
214 bool verbose;
215 bool usePCG;
216 string outputFilename;
217 string inputFilename;
218 string statsFilename;
220 arg.param("i", maxIterations, 5, "perform n iterations");
221 arg.param("o", outputFilename, "", "write points into a vrml file");
222 arg.param("pcg", usePCG, false, "use PCG instead of the Cholesky");
223 arg.param("v", verbose, false, "verbose output of the optimization process");
224 arg.param("stats", statsFilename, "", "specify a file for the statistics");
225 arg.paramLeftOver("graph-input", inputFilename, "",
226 "file which will be processed");
227
228 arg.parseArgs(argc, argv);
229
230 using BalBlockSolver = g2o::BlockSolver<g2o::BlockSolverTraits<9, 3>>;
231 using BalLinearSolverPCG =
233
234 g2o::SparseOptimizer optimizer;
235 std::unique_ptr<g2o::LinearSolver<BalBlockSolver::PoseMatrixType>>
236 linearSolver;
237 if (usePCG) {
238 cout << "Using PCG" << endl;
239 linearSolver = std::make_unique<BalLinearSolverPCG>();
240 } else {
241#ifdef G2O_HAVE_CHOLMOD
242 string_view choleskySolverName = "CHOLMOD";
243 using BalLinearSolver =
245#else
246 string_view choleskySolverName = "Eigen";
247 using BalLinearSolver =
249#endif
250 cout << "Using Cholesky: " << choleskySolverName << endl;
251 auto cholesky = std::make_unique<BalLinearSolver>();
252 cholesky->setBlockOrdering(true);
253 linearSolver = std::move(cholesky);
254 }
257 std::make_unique<BalBlockSolver>(std::move(linearSolver)));
258
259 // solver->setUserLambdaInit(1);
260 optimizer.setAlgorithm(solver);
261 if (statsFilename.size() > 0) {
262 optimizer.setComputeBatchStatistics(true);
263 }
264
265 vector<VertexPointBAL*> points;
266 vector<VertexCameraBAL*> cameras;
267
268 // parse BAL dataset
269 cout << "Loading BAL dataset " << inputFilename << endl;
270 {
271 ifstream ifs(inputFilename.c_str());
272 int numCameras, numPoints, numObservations;
273 ifs >> numCameras >> numPoints >> numObservations;
274
275 cerr << PVAR(numCameras) << " " << PVAR(numPoints) << " "
276 << PVAR(numObservations) << endl;
277
278 int id = 0;
279 cameras.reserve(numCameras);
280 for (int i = 0; i < numCameras; ++i, ++id) {
282 cam->setId(id);
283 optimizer.addVertex(cam);
284 cameras.push_back(cam);
285 }
286
287 points.reserve(numPoints);
288 for (int i = 0; i < numPoints; ++i, ++id) {
290 p->setId(id);
291 p->setMarginalized(true);
292 bool addedVertex = optimizer.addVertex(p);
293 if (!addedVertex) {
294 cerr << "failing adding vertex" << endl;
295 }
296 points.push_back(p);
297 }
298
299 // read in the observation
300 for (int i = 0; i < numObservations; ++i) {
301 int camIndex, pointIndex;
302 double obsX, obsY;
303 ifs >> camIndex >> pointIndex >> obsX >> obsY;
304
305 assert(camIndex >= 0 && (size_t)camIndex < cameras.size() &&
306 "Index out of bounds");
307 VertexCameraBAL* cam = cameras[camIndex];
308 assert(pointIndex >= 0 && (size_t)pointIndex < points.size() &&
309 "Index out of bounds");
310 VertexPointBAL* point = points[pointIndex];
311
313 e->setVertex(0, cam);
314 e->setVertex(1, point);
315 e->setInformation(g2o::Matrix2::Identity());
316 e->setMeasurement(g2o::Vector2(obsX, obsY));
317 bool addedEdge = optimizer.addEdge(e);
318 if (!addedEdge) {
319 cerr << "error adding edge" << endl;
320 }
321 }
322
323 // read in the camera params
324 for (int i = 0; i < numCameras; ++i) {
325 g2o::bal::Vector9 cameraParameter;
326 for (int j = 0; j < 9; ++j) ifs >> cameraParameter(j);
327 VertexCameraBAL* cam = cameras[i];
328 cam->setEstimate(cameraParameter);
329 }
330
331 // read in the points
332 for (int i = 0; i < numPoints; ++i) {
333 g2o::Vector3 p;
334 ifs >> p(0) >> p(1) >> p(2);
335 VertexPointBAL* point = points[i];
336 point->setEstimate(p);
337 }
338 }
339 cout << "done." << endl;
340
341 cout << "Initializing ... " << flush;
342 optimizer.initializeOptimization();
343 cout << "done." << endl;
344 optimizer.setVerbose(verbose);
345 cout << "Start to optimize" << endl;
346 optimizer.optimize(maxIterations);
347
348 if (statsFilename != "") {
349 cerr << "writing stats to file \"" << statsFilename << "\" ... ";
350 ofstream fout(statsFilename.c_str());
351 const g2o::BatchStatisticsContainer& bsc = optimizer.batchStatistics();
352 for (size_t i = 0; i < bsc.size(); i++) fout << bsc[i] << endl;
353 cerr << "done." << endl;
354 }
355
356 // dump the points
357 if (outputFilename.size() > 0) {
358 ofstream fout(outputFilename.c_str()); // loadable with meshlab
359 fout << "#VRML V2.0 utf8\n"
360 << "Shape {\n"
361 << " appearance Appearance {\n"
362 << " material Material {\n"
363 << " diffuseColor " << 1 << " " << 0 << " " << 0 << "\n"
364 << " ambientIntensity 0.2\n"
365 << " emissiveColor 0.0 0.0 0.0\n"
366 << " specularColor 0.0 0.0 0.0\n"
367 << " shininess 0.2\n"
368 << " transparency 0.0\n"
369 << " }\n"
370 << " }\n"
371 << " geometry PointSet {\n"
372 << " coord Coordinate {\n"
373 << " point [\n";
374 for (vector<VertexPointBAL*>::const_iterator it = points.begin();
375 it != points.end(); ++it) {
376 fout << (*it)->estimate().transpose() << endl;
377 }
378 fout << " ]\n"
379 << " }\n"
380 << "}\n"
381 << " }\n";
382 }
383
384 return 0;
385}
edge representing the observation of a world feature by a camera
camera vertex which stores the parameters for a pinhole camera
3D world feature
virtual void setMeasurement(const Measurement &m)
Definition base_edge.h:122
void setInformation(const InformationType &information)
Definition base_edge.h:111
void setEstimate(const EstimateType &et)
set the estimate for the vertex also calls updateCache()
Implementation of a solver operating on the blocks of the Hessian.
Command line parsing of argc and argv.
bool parseArgs(int argc, char **argv, bool exitOnError=true)
void paramLeftOver(const std::string &name, std::string &p, const std::string &defValue, const std::string &desc, bool optional=false)
void param(const std::string &name, bool &p, bool defValue, const std::string &desc)
void setVertex(size_t i, Vertex *v)
basic solver for Ax = b which has to reimplemented for different linear algebra libraries
linear solver which uses the sparse Cholesky solver from Eigen
linear solver using PCG, pre-conditioner is block Jacobi
void setMarginalized(bool marginalized)
true => this node should be marginalized out during the optimization
Implementation of the Levenberg Algorithm.
int optimize(int iterations, bool online=false)
void setVerbose(bool verbose)
virtual bool initializeOptimization(HyperGraph::EdgeSet &eset)
void setAlgorithm(OptimizationAlgorithm *algorithm)
const BatchStatisticsContainer & batchStatistics() const
void setComputeBatchStatistics(bool computeBatchStatistics)
VectorN< 9 > Vector9
VectorN< 3 > Vector3
Definition eigen_types.h:51
std::vector< G2OBatchStatistics > BatchStatisticsContainer
Definition batch_stats.h:86
VectorN< 2 > Vector2
Definition eigen_types.h:50
virtual bool addEdge(HyperGraph::Edge *e)
virtual bool addVertex(HyperGraph::Vertex *v, Data *userData)

References g2o::OptimizableGraph::addEdge(), g2o::OptimizableGraph::addVertex(), g2o::SparseOptimizer::batchStatistics(), g2o::SparseOptimizer::initializeOptimization(), g2o::SparseOptimizer::optimize(), g2o::CommandArgs::param(), g2o::CommandArgs::paramLeftOver(), g2o::CommandArgs::parseArgs(), g2o::SparseOptimizer::setAlgorithm(), g2o::SparseOptimizer::setComputeBatchStatistics(), g2o::BaseVertex< D, T >::setEstimate(), g2o::OptimizableGraph::Vertex::setId(), g2o::BaseEdge< D, E >::setInformation(), g2o::OptimizableGraph::Vertex::setMarginalized(), g2o::BaseEdge< D, E >::setMeasurement(), g2o::SparseOptimizer::setVerbose(), and g2o::HyperGraph::Edge::setVertex().