Skip to content

Commit 8ca7f1f

Browse files
committed
Adding factor with shared calibration as a variable
1 parent 301f7fe commit 8ca7f1f

File tree

2 files changed

+565
-0
lines changed

2 files changed

+565
-0
lines changed
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
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+
12+
/**
13+
* @file EssentialMatrixWithCalibrationFactor.h
14+
*
15+
* @brief A factor evaluating algebraic epipolar error with essential matrix and calibration as variables.
16+
*
17+
* @author Ayush Baid
18+
* @author Akshay Krishnan
19+
* @date April 23, 2021
20+
*/
21+
22+
#pragma once
23+
24+
#include <gtsam/nonlinear/NonlinearFactor.h>
25+
#include <gtsam/geometry/EssentialMatrix.h>
26+
#include <iostream>
27+
28+
namespace gtsam {
29+
30+
/**
31+
* Factor that evaluates algebraic epipolar error (K^-1 p)'E (K^-1 p) for given essential matrix and calibration shared
32+
* between two images.
33+
*/
34+
template<class CALIBRATION>
35+
class EssentialMatrixWithCalibrationFactor: public NoiseModelFactor2<EssentialMatrix, CALIBRATION > {
36+
37+
Point2 pA_, pB_; ///< points in pixel coordinates
38+
39+
typedef NoiseModelFactor2<EssentialMatrix, CALIBRATION> Base;
40+
typedef EssentialMatrixWithCalibrationFactor This;
41+
42+
public:
43+
44+
/**
45+
* Constructor
46+
* @param essentialMatrixKey Essential Matrix variable key
47+
* @param calibrationKey Calibration variable key
48+
* @param pA point in first camera, in pixel coordinates
49+
* @param pB point in second camera, in pixel coordinates
50+
* @param model noise model is about dot product in ideal, homogeneous coordinates
51+
*/
52+
EssentialMatrixWithCalibrationFactor(Key essentialMatrixKey, Key calibrationKey, const Point2& pA, const Point2& pB,
53+
const SharedNoiseModel& model) :
54+
Base(model, essentialMatrixKey, calibrationKey), pA_(pA), pB_(pB) {}
55+
56+
57+
/// @return a deep copy of this factor
58+
gtsam::NonlinearFactor::shared_ptr clone() const override {
59+
return boost::static_pointer_cast<gtsam::NonlinearFactor>(
60+
gtsam::NonlinearFactor::shared_ptr(new This(*this)));
61+
}
62+
63+
/// print
64+
void print(const std::string& s = "",
65+
const KeyFormatter& keyFormatter = DefaultKeyFormatter) const override {
66+
Base::print(s);
67+
std::cout << " EssentialMatrixWithCalibrationFactor with measurements\n ("
68+
<< pA_.transpose() << ")' and (" << pB_.transpose() << ")'"
69+
<< std::endl;
70+
}
71+
72+
/// vector of errors returns 1D vector
73+
/**
74+
* @brief Calculate the algebraic epipolar error p' (K^-1)' E K p.
75+
*
76+
* @param E essential matrix for key essentialMatrixKey
77+
* @param K calibration (common for both images) for key calibrationKey
78+
* @param H1 optional jacobian in E
79+
* @param H2 optional jacobian in K
80+
* @return * Vector
81+
*/
82+
Vector evaluateError(const EssentialMatrix& E, const CALIBRATION& K,
83+
boost::optional<Matrix&> H1 = boost::none, boost::optional<Matrix&> H2 = boost::none) const override {
84+
Vector error(1);
85+
// converting from pixel coordinates to normalized coordinates cA and cB
86+
Matrix cA_H_K; // dcA/dK
87+
Matrix cB_H_K; // dcB/dK
88+
Point2 cA = K.calibrate(pA_, cA_H_K);
89+
Point2 cB = K.calibrate(pB_, cB_H_K);
90+
91+
// Homogeneous the coordinates
92+
Vector3 vA = EssentialMatrix::Homogeneous(cA);
93+
Vector3 vB = EssentialMatrix::Homogeneous(cB);
94+
95+
if (H2){
96+
// compute the jacobian of error w.r.t K
97+
98+
// dvX / dcX [3x2] = [1, 0], [0, 1], [0, 0]
99+
Matrix v_H_c = (Matrix(3, 2) << 1.0, 0.0, 0.0, 1.0, 0.0, 0.0).finished(); // [3x2]
100+
101+
// computing dvA/dK = dvA/dcA * dcA/dK and dVB/dK = dvB/dcB * dcB/dK
102+
Matrix vA_H_K = v_H_c * cA_H_K;
103+
Matrix vB_H_K = v_H_c * cB_H_K;
104+
105+
// error function f = vB.T * E * vA
106+
// H2 = df/dK = vB.T * E.T * dvA/dK + vA.T * E * dvB/dK
107+
*H2 = vB.transpose() * E.matrix().transpose() * vA_H_K + vA.transpose() * E.matrix() * vB_H_K;
108+
}
109+
110+
error << E.error(vA, vB, H1);
111+
112+
return error;
113+
}
114+
115+
public:
116+
GTSAM_MAKE_ALIGNED_OPERATOR_NEW
117+
};
118+
119+
}// gtsam

0 commit comments

Comments
 (0)