33 template<
class CAMERA>
42 typedef typename CAMERA::Measurement
Z;
49 const std::vector<Z>& measured) {
52 size_t m = predicted.size();
53 if (measured.size() != m)
54 throw std::runtime_error(
"CameraSet::errors: size mismatch");
58 for (
size_t i = 0,
row = 0; i < m; i++,
row +=
ZDim) {
67 typedef Eigen::Matrix<double, ZDim, D>
MatrixZD;
68 typedef std::vector<MatrixZD> FBlocks;
75 virtual void print(
const std::string& s =
"")
const {
76 std::cout << s <<
"CameraSet, cameras = \n";
77 for (
size_t k = 0; k < this->size(); ++k)
83 if (this->size() != p.size())
85 bool camerasAreEqual =
true;
86 for (
size_t i = 0; i < this->size(); i++) {
87 if (this->at(i).equals(p.at(i), tol) ==
false)
88 camerasAreEqual =
false;
91 return camerasAreEqual;
100 template<
class POINT>
102 boost::optional<FBlocks&> Fs = boost::none,
103 boost::optional<Matrix&> E = boost::none)
const {
108 size_t m = this->size();
113 if (E) E->resize(ZDim * m, N);
114 if (Fs) Fs->resize(m);
117 for (
size_t i = 0; i < m; i++) {
119 Eigen::Matrix<double, ZDim, N> Ei;
120 z.emplace_back(this->at(i).
project2(point, Fs ? &Fi : 0, E ? &Ei : 0));
121 if (Fs) (*Fs)[i] = Fi;
122 if (E) E->block<
ZDim, N>(ZDim * i, 0) = Ei;
129 template<
class POINT>
131 boost::optional<FBlocks&> Fs = boost::none,
132 boost::optional<Matrix&> E = boost::none)
const {
144 const Matrix& E,
const Eigen::Matrix<double, N, N>& P,
const Vector& b) {
147 size_t m = Fs.size();
150 size_t M1 = D * m + 1;
151 std::vector<DenseIndex> dims(m + 1);
152 std::fill(dims.begin(), dims.end() - 1,
D);
157 for (
size_t i = 0; i < m; i++) {
159 const MatrixZD& Fi = Fs[i];
160 const auto FiT = Fi.transpose();
161 const Eigen::Matrix<double, ZDim, N> Ei_P =
162 E.block(ZDim * i, 0, ZDim, N) * P;
166 - FiT * (Ei_P * (E.transpose() * b)));
170 * (Fi - Ei_P * E.block(ZDim * i, 0, ZDim, N).transpose() * Fi));
173 for (
size_t j = i + 1; j < m; j++) {
174 const MatrixZD& Fj = Fs[j];
178 * (Ei_P * E.block(ZDim * j, 0, ZDim, N).transpose() * Fj));
183 return augmentedHessian;
189 const Matrix& E,
double lambda,
bool diagonalDamping =
false) {
191 Matrix EtE = E.transpose() * E;
193 if (diagonalDamping) {
194 EtE.diagonal() += lambda * EtE.diagonal();
197 EtE += lambda * Eigen::MatrixXd::Identity(n, n);
204 static Matrix
PointCov(
const Matrix& E,
const double lambda = 0.0,
205 bool diagonalDamping =
false) {
222 const Matrix& E,
const Vector& b,
const double lambda = 0.0,
223 bool diagonalDamping =
false) {
241 const Eigen::Matrix<double, N, N>& P,
const Vector& b,
245 assert(keys.size()==Fs.size());
246 assert(keys.size()<=allKeys.size());
249 for (
size_t slot = 0; slot < allKeys.size(); slot++)
250 KeySlotMap.insert(std::make_pair(allKeys[slot], slot));
257 size_t m = Fs.size();
258 size_t M = (augmentedHessian.
rows() - 1) / D;
259 assert(allKeys.size()==M);
262 for (
size_t i = 0; i < m; i++) {
264 const MatrixZD& Fi = Fs[i];
265 const auto FiT = Fi.transpose();
266 const Eigen::Matrix<double, 2, N> Ei_P = E.template block<ZDim, N>(
279 FiT * b.segment<ZDim>(ZDim * i)
280 - FiT * (Ei_P * (E.transpose() * b)));
286 ((FiT * (Fi - Ei_P * E.template block<ZDim, N>(ZDim * i, 0).transpose() * Fi))).eval());
289 for (
size_t j = i + 1; j < m; j++) {
290 const MatrixZD& Fj = Fs[j];
299 -FiT * (Ei_P * E.template block<ZDim, N>(ZDim * j, 0).transpose() * Fj));
310 template<
class ARCHIVE>
311 void serialize(ARCHIVE & ar,
const unsigned int ) {
316 template<
class CAMERA>
319 template<
class CAMERA>
322 template<
class CAMERA>
326 template<
class CAMERA>
CAMERA::Measurement Z
2D measurement and noise model for each of the m views The order is kept the same as the keys that we...
Definition: CameraSet.h:42
void updateDiagonalBlock(DenseIndex I, const XprType &xpr)
Increment the diagonal block by the values in xpr. Only reads the upper triangular part of xpr...
Definition: SymmetricBlockMatrix.h:217
static void ComputePointCovariance(Eigen::Matrix< double, N, N > &P, const Matrix &E, double lambda, bool diagonalDamping=false)
Computes Point Covariance P, with lambda parameter.
Definition: CameraSet.h:188
void updateOffDiagonalBlock(DenseIndex I, DenseIndex J, const XprType &xpr)
Update an off diagonal block.
Definition: SymmetricBlockMatrix.h:233
virtual void print(const std::string &s="") const
print
Definition: CameraSet.h:75
static SymmetricBlockMatrix SchurComplement(const FBlocks &Fs, const Matrix &E, const Eigen::Matrix< double, N, N > &P, const Vector &b)
Do Schur complement, given Jacobian as Fs,E,P, return SymmetricBlockMatrix G = F' * F - F' * E * P * ...
Definition: CameraSet.h:143
Vector reprojectionError(const POINT &point, const std::vector< Z > &measured, boost::optional< FBlocks & > Fs=boost::none, boost::optional< Matrix & > E=boost::none) const
Calculate vector [project2(point)-z] of re-projection errors.
Definition: CameraSet.h:130
void setDiagonalBlock(DenseIndex I, const XprType &xpr)
Set a diagonal block. Only the upper triangular portion of xpr is evaluated.
Definition: SymmetricBlockMatrix.h:200
Definition: SymmetricBlockMatrix.h:51
Access to matrices via blocks of pre-defined sizes.
friend class boost::serialization::access
Serialization function.
Definition: CameraSet.h:309
A helper that implements the traits interface for GTSAM types.
Definition: Testable.h:150
Calibrated camera for which only pose is unknown.
static const int ZDim
Measurement dimension.
Definition: CameraSet.h:45
ptrdiff_t DenseIndex
The index type for Eigen objects.
Definition: types.h:60
A set of cameras, all with their own calibration.
Definition: CameraSet.h:34
static void UpdateSchurComplement(const FBlocks &Fs, const Matrix &E, const Eigen::Matrix< double, N, N > &P, const Vector &b, const FastVector< Key > &allKeys, const FastVector< Key > &keys, SymmetricBlockMatrix &augmentedHessian)
Applies Schur complement (exploiting block structure) to get a smart factor on cameras, and adds the contribution of the smart factor to a pre-allocated augmented Hessian.
Definition: CameraSet.h:240
static const int D
Camera dimension.
Definition: CameraSet.h:44
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition: concepts.h:30
bool equals(const CameraSet &p, double tol=1e-9) const
equals
Definition: CameraSet.h:82
static SymmetricBlockMatrix SchurComplement(const FBlocks &Fblocks, const Matrix &E, const Vector &b, const double lambda=0.0, bool diagonalDamping=false)
Do Schur complement, given Jacobian as Fs,E,P, return SymmetricBlockMatrix Dynamic version...
Definition: CameraSet.h:221
Give fixed size dimension of a type, fails at compile time if dynamic.
Definition: Manifold.h:164
std::vector< Z > project2(const POINT &point, boost::optional< FBlocks & > Fs=boost::none, boost::optional< Matrix & > E=boost::none) const
Project a point (possibly Unit3 at infinity), with derivatives Note that F is a sparse block-diagonal...
Definition: CameraSet.h:101
static Vector ErrorVector(const std::vector< Z > &predicted, const std::vector< Z > &measured)
Make a vector of re-projection errors.
Definition: CameraSet.h:48
DenseIndex rows() const
Row size.
Definition: SymmetricBlockMatrix.h:119
static Matrix PointCov(const Matrix &E, const double lambda=0.0, bool diagonalDamping=false)
Computes Point Covariance P, with lambda parameter, dynamic version.
Definition: CameraSet.h:204
const MATRIX::ConstRowXpr row(const MATRIX &A, size_t j)
Extracts a row view from a matrix that avoids a copy.
Definition: Matrix.h:224
Eigen::Matrix< double, ZDim, D > MatrixZD
Definitions for blocks of F.
Definition: CameraSet.h:67
A thin wrapper around std::map that uses boost's fast_pool_allocator.
Eigen::SelfAdjointView< Block, Eigen::Upper > diagonalBlock(DenseIndex J)
Return the J'th diagonal block as a self adjoint view.
Definition: SymmetricBlockMatrix.h:140
void setOffDiagonalBlock(DenseIndex I, DenseIndex J, const XprType &xpr)
Set an off-diagonal block. Only the upper triangular portion of xpr is evaluated. ...
Definition: SymmetricBlockMatrix.h:206
Global functions in a separate testing namespace.
Definition: chartTesting.h:28
Concept check for values that can be used in unit tests.