34 template<
class CAMERA>
35 class CameraSet :
public std::vector<CAMERA, Eigen::aligned_allocator<CAMERA> > {
44 typedef typename CAMERA::MeasurementVector
ZVector;
54 size_t m = predicted.size();
55 if (measured.size() !=
m)
56 throw std::runtime_error(
"CameraSet::errors: size mismatch");
65 b.segment<ZDim>(
row) = bi;
74 typedef std::vector<MatrixZD, Eigen::aligned_allocator<MatrixZD> >
FBlocks;
81 virtual void print(
const std::string&
s =
"")
const {
82 std::cout <<
s <<
"CameraSet, cameras = \n";
83 for (
size_t k = 0; k < this->
size(); ++k)
89 if (this->
size() != p.size())
91 bool camerasAreEqual =
true;
92 for (
size_t i = 0;
i < this->
size();
i++) {
93 if (this->at(
i).equals(p.at(
i),
tol) ==
false)
94 camerasAreEqual =
false;
97 return camerasAreEqual;
106 template<
class POINT>
108 boost::optional<FBlocks&> Fs = boost::none,
109 boost::optional<Matrix&>
E = boost::none)
const {
114 size_t m = this->
size();
119 if (
E)
E->resize(ZDim * m, N);
120 if (Fs) Fs->resize(m);
123 for (
size_t i = 0;
i <
m;
i++) {
126 z.emplace_back(this->at(
i).
project2(point, Fs ? &Fi : 0,
E ? &Ei : 0));
127 if (Fs) (*Fs)[
i] = Fi;
128 if (
E)
E->block<
ZDim, N>(ZDim *
i, 0) = Ei;
135 template<
class POINT>
137 boost::optional<FBlocks&> Fs = boost::none,
138 boost::optional<Matrix&>
E = boost::none)
const {
153 size_t m = Fs.size();
156 size_t M1 = D * m + 1;
157 std::vector<DenseIndex> dims(m + 1);
158 std::fill(dims.begin(), dims.end() - 1,
D);
163 for (
size_t i = 0;
i <
m;
i++) {
165 const MatrixZD& Fi = Fs[
i];
166 const auto FiT = Fi.transpose();
168 E.block(ZDim *
i, 0, ZDim,
N) *
P;
172 - FiT * (Ei_P * (E.transpose() *
b)));
176 * (Fi - Ei_P * E.block(ZDim * i, 0, ZDim,
N).transpose() * Fi));
179 for (
size_t j = i + 1;
j <
m;
j++) {
180 const MatrixZD& Fj = Fs[
j];
184 * (Ei_P * E.block(ZDim *
j, 0, ZDim,
N).transpose() * Fj));
189 return augmentedHessian;
195 const Matrix&
E,
double lambda,
bool diagonalDamping =
false) {
197 Matrix EtE = E.transpose() *
E;
199 if (diagonalDamping) {
200 EtE.diagonal() += lambda * EtE.diagonal();
203 EtE += lambda * Eigen::MatrixXd::Identity(n, n);
211 bool diagonalDamping =
false) {
214 ComputePointCovariance<2>(
P2,
E,
lambda, diagonalDamping);
218 ComputePointCovariance<3>(
P3,
E,
lambda, diagonalDamping);
229 bool diagonalDamping =
false) {
232 ComputePointCovariance<2>(
P,
E,
lambda, diagonalDamping);
233 return SchurComplement<2>(Fblocks,
E,
P,
b);
236 ComputePointCovariance<3>(
P,
E,
lambda, diagonalDamping);
237 return SchurComplement<3>(Fblocks,
E,
P,
b);
251 assert(keys.size()==Fs.size());
252 assert(keys.size()<=allKeys.size());
255 for (
size_t slot = 0; slot < allKeys.size(); slot++)
256 KeySlotMap.insert(std::make_pair(allKeys[slot], slot));
263 size_t m = Fs.size();
264 size_t M = (augmentedHessian.
rows() - 1) / D;
265 assert(allKeys.size()==
M);
268 for (
size_t i = 0;
i <
m;
i++) {
270 const MatrixZD& Fi = Fs[
i];
271 const auto FiT = Fi.transpose();
285 FiT * b.segment<ZDim>(ZDim * i)
286 - FiT * (Ei_P * (E.transpose() *
b)));
292 ((FiT * (Fi - Ei_P * E.template block<ZDim, N>(ZDim * i, 0).transpose() * Fi))).
eval());
295 for (
size_t j = i + 1;
j <
m;
j++) {
296 const MatrixZD& Fj = Fs[
j];
305 -FiT * (Ei_P * E.template block<ZDim, N>(ZDim * j, 0).transpose() * Fj));
316 template<
class ARCHIVE>
325 template<
class CAMERA>
328 template<
class CAMERA>
331 template<
class CAMERA>
335 template<
class CAMERA>
ZVector project2(const POINT &point, boost::optional< FBlocks & > Fs=boost::none, boost::optional< Matrix & > E=boost::none) const
Eigen::Matrix< double, ZDim, D > MatrixZD
Definitions for blocks of F.
friend class boost::serialization::access
Serialization function.
static Matrix PointCov(const Matrix &E, const double lambda=0.0, bool diagonalDamping=false)
Computes Point Covariance P, with lambda parameter, dynamic version.
const MATRIX::ConstRowXpr row(const MATRIX &A, size_t j)
Matrix< RealScalar, Dynamic, Dynamic > M
std::vector< MatrixZD, Eigen::aligned_allocator< MatrixZD > > FBlocks
Concept check for values that can be used in unit tests.
Access to matrices via blocks of pre-defined sizes. Used in GaussianFactor and GaussianConditional.
void setOffDiagonalBlock(DenseIndex I, DenseIndex J, const XprType &xpr)
Set an off-diagonal block. Only the upper triangular portion of xpr is evaluated. ...
Give fixed size dimension of a type, fails at compile time if dynamic.
bool equals(const CameraSet &p, double tol=1e-9) const
equals
static Vector ErrorVector(const ZVector &predicted, const ZVector &measured)
Make a vector of re-projection errors.
A set of cameras, all with their own calibration.
Vector reprojectionError(const POINT &point, const ZVector &measured, boost::optional< FBlocks & > Fs=boost::none, boost::optional< Matrix & > E=boost::none) const
Calculate vector [project2(point)-z] of re-projection errors.
ptrdiff_t DenseIndex
The index type for Eigen objects.
virtual void print(const std::string &s="") const
static const int D
Camera dimension.
FastVector< Key > KeyVector
Define collection type once and for all - also used in wrappers.
void setDiagonalBlock(DenseIndex I, const XprType &xpr)
Set a diagonal block. Only the upper triangular portion of xpr is evaluated.
static SymmetricBlockMatrix SchurComplement(const FBlocks &Fblocks, const Matrix &E, const Vector &b, const double lambda=0.0, bool diagonalDamping=false)
GenericMeasurement< Point2, Point2 > Measurement
Array< double, 1, 3 > e(1./3., 0.5, 2.)
void updateDiagonalBlock(DenseIndex I, const XprType &xpr)
Increment the diagonal block by the values in xpr. Only reads the upper triangular part of xpr...
static const int ZDim
Measurement dimension.
cout<< "The eigenvalues of A are:"<< endl<< ces.eigenvalues()<< endl;cout<< "The matrix of eigenvectors, V, is:"<< endl<< ces.eigenvectors()<< endl<< endl;complex< float > lambda
Calibrated camera for which only pose is unknown.
static const Point3 P2(3.5,-8.2, 4.2)
CAMERA::MeasurementVector ZVector
A thin wrapper around std::map that uses boost's fast_pool_allocator.
static void ComputePointCovariance(Eigen::Matrix< double, N, N > &P, const Matrix &E, double lambda, bool diagonalDamping=false)
Computes Point Covariance P, with lambda parameter.
#define GTSAM_MAKE_ALIGNED_OPERATOR_NEW
void updateOffDiagonalBlock(DenseIndex I, DenseIndex J, const XprType &xpr)
internal::nested_eval< T, 1 >::type eval(const T &xpr)
Eigen::SelfAdjointView< Block, Eigen::Upper > diagonalBlock(DenseIndex J)
Return the J'th diagonal block as a self adjoint view.
void serialize(ARCHIVE &ar, const unsigned int)
The matrix class, also used for vectors and row-vectors.
static void UpdateSchurComplement(const FBlocks &Fs, const Matrix &E, const Eigen::Matrix< double, N, N > &P, const Vector &b, const KeyVector &allKeys, const KeyVector &keys, SymmetricBlockMatrix &augmentedHessian)
DenseIndex rows() const
Row size.
EIGEN_DEVICE_FUNC const InverseReturnType inverse() const
static SymmetricBlockMatrix SchurComplement(const FBlocks &Fs, const Matrix &E, const Eigen::Matrix< double, N, N > &P, const Vector &b)