-
Notifications
You must be signed in to change notification settings - Fork 28
/
Bundle.h
157 lines (132 loc) · 4.77 KB
/
Bundle.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// -*- c++ -*-
// Copyright 2008 Isis Innovation Limited
#ifndef __BUNDLE_H
#define __BUNDLE_H
// Bundle.h
//
// This file declares the Bundle class along with a few helper classes.
// Bundle is the bundle adjustment core of the mapping system; instances
// of Bundle are generated by MapMaker to adjust the positions of
// keyframes (called Cameras in this file) and map points.
//
// It's a pretty straight-forward Levenberg-Marquardt bundle adjustment
// implementation closely following Hartley and Zisserman's MVG book, with
// the addition of a robust M-Estimator.
//
// Unfortunately, having undergone a few tweaks, the code is now
// not the easiest to read!
//
// Basic operation: MapMaker creates a new Bundle object;
// then adds map points and keyframes to adjust;
// then adds measurements of map points in keyframes;
// then calls Compute() to do bundle adjustment;
// then reads results back to update the map.
#include "ATANCamera.h"
#include <TooN/TooN.h>
using namespace TooN;
#include <TooN/se3.h>
#include <vector>
#include <map>
#include <set>
#include <list>
// An index into the big measurement map which stores all the measurements.
// Camera struct holds the pose of a keyframe
// and some computation intermediates
struct Camera
{
bool bFixed;
SE3<> se3CfW;
SE3<> se3CfWNew;
Matrix<6> m6U; // Accumulator
Vector<6> v6EpsilonA; // Accumulator
int nStartRow;
};
// Camera-camera pair index
struct OffDiagScriptEntry
{
int j;
int k;
};
// A map point, plus computation intermediates.
struct Point
{
inline Point()
{ nMeasurements = 0; nOutliers = 0;}
Vector<3> v3Pos;
Vector<3> v3PosNew;
Matrix<3> m3V; // Accumulator
Vector<3> v3EpsilonB; // Accumulator
Matrix<3> m3VStarInv;
int nMeasurements;
int nOutliers;
std::set<int> sCameras; // Which cameras observe this point?
std::vector<OffDiagScriptEntry> vOffDiagonalScript; // A record of all camera-camera pairs observing this point
};
// A measurement of a point by a camera, plus
// computation intermediates.
struct Meas
{
inline Meas()
{bBad = false;}
// Which camera/point did this measurement come from?
int p; // The point - called i in MVG
int c; // The camera - called j in MVG
inline bool operator<(const Meas &rhs) const
{ return(c<rhs.c ||(c==rhs.c && p < rhs.p)); }
bool bBad;
Vector<2> v2Found;
Vector<2> v2Epsilon;
Matrix<2,6> m26A;
Matrix<2,3> m23B;
Matrix<6,3> m63W;
Matrix<6,3> m63Y;
double dSqrtInvNoise;
// Temporary projection quantities
Vector<3> v3Cam;
double dErrorSquared;
Matrix<2> m2CamDerivs;
};
// Core bundle adjustment class
class Bundle
{
public:
Bundle(const ATANCamera &TCam); // We need the camera model because we do full distorting projection in the bundle adjuster. Could probably get away with a linear approximation.
int AddCamera(SE3<> se3CamFromWorld, bool bFixed); // Add a viewpoint. bFixed signifies that this one is not to be adjusted.
int AddPoint(Vector<3> v3Pos); // Add a map point.
void AddMeas(int nCam, int nPoint, Vector<2> v2Pos, double dSigmaSquared); // Add a measurement
int Compute(bool *pbAbortSignal); // Perform bundle adjustment. Aborts if *pbAbortSignal gets set to true. Returns number of accepted update iterations, or negative on error.
inline bool Converged() { return mbConverged;} // Has bundle adjustment converged?
Vector<3> GetPoint(int n); // Point coords after adjustment
SE3<> GetCamera(int n); // Camera pose after adjustment
std::vector<std::pair<int,int> > GetOutlierMeasurements(); // Measurements flagged as outliers
std::set<int> GetOutliers(); // Points flagged as outliers
protected:
inline void ProjectAndFindSquaredError(Meas &meas); // Project a single point in a single view, compare to measurement
template<class MEstimator> bool Do_LM_Step(bool *pbAbortSignal);
template<class MEstimator> double FindNewError();
void GenerateMeasLUTs();
void GenerateOffDiagScripts();
void ClearAccumulators(); // Zero temporary quantities stored in cameras and points
void ModifyLambda_GoodStep();
void ModifyLambda_BadStep();
std::vector<Point> mvPoints;
std::vector<Camera> mvCameras;
std::list<Meas> mMeasList;
std::vector<std::pair<int,int> > mvOutlierMeasurementIdx; // p-c pair
std::vector<std::vector<Meas*> > mvMeasLUTs; //Each camera gets a per-point table of pointers to valid measurements
ATANCamera mCamera;
int mnCamsToUpdate;
int mnStartRow;
double mdSigmaSquared;
double mdLambda;
double mdLambdaFactor;
bool mbConverged;
bool mbHitMaxIterations;
int mnCounter;
int mnAccepted;
GVars3::gvar3<int> mgvnMaxIterations;
GVars3::gvar3<double> mgvdUpdateConvergenceLimit;
GVars3::gvar3<int> mgvnBundleCout;
bool *mpbAbortSignal;
};
#endif