34 #include <Eigen/Eigenvalues>
42 Eigen::Matrix3d matrix;
43 matrix << 0, -vector(2), vector(1), vector(2), 0, -vector(0), -vector(1),
49 double* ry,
double* rz) {
50 *rx = std::atan2(R(2, 1), R(2, 2));
51 *ry = std::asin(-R(2, 0));
52 *rz = std::atan2(R(1, 0), R(0, 0));
54 *rx =
IsNaN(*rx) ? 0 : *rx;
55 *ry =
IsNaN(*ry) ? 0 : *ry;
56 *rz =
IsNaN(*rz) ? 0 : *rz;
61 const Eigen::Matrix3d Rx =
62 Eigen::AngleAxisd(rx, Eigen::Vector3d::UnitX()).toRotationMatrix();
63 const Eigen::Matrix3d Ry =
64 Eigen::AngleAxisd(ry, Eigen::Vector3d::UnitY()).toRotationMatrix();
65 const Eigen::Matrix3d Rz =
66 Eigen::AngleAxisd(rz, Eigen::Vector3d::UnitZ()).toRotationMatrix();
71 const Eigen::Quaterniond quat(rot_mat);
72 return Eigen::Vector4d(quat.w(), quat.x(), quat.y(), quat.z());
77 const Eigen::Quaterniond quat(normalized_qvec(0), normalized_qvec(1),
78 normalized_qvec(2), normalized_qvec(3));
79 return quat.toRotationMatrix();
83 const double norm = qvec.norm();
87 return Eigen::Vector4d(1.0, qvec(1), qvec(2), qvec(3));
94 return Eigen::Vector4d(qvec(0), -qvec(1), -qvec(2), -qvec(3));
98 const Eigen::Vector4d& qvec2) {
101 const Eigen::Quaterniond quat1(normalized_qvec1(0), normalized_qvec1(1),
102 normalized_qvec1(2), normalized_qvec1(3));
103 const Eigen::Quaterniond quat2(normalized_qvec2(0), normalized_qvec2(1),
104 normalized_qvec2(2), normalized_qvec2(3));
105 const Eigen::Quaterniond cat_quat = quat2 * quat1;
107 Eigen::Vector4d(cat_quat.w(), cat_quat.x(), cat_quat.y(), cat_quat.z()));
111 const Eigen::Vector3d& point) {
113 const Eigen::Quaterniond quat(normalized_qvec(0), normalized_qvec(1),
114 normalized_qvec(2), normalized_qvec(3));
119 const std::vector<double>& weights) {
120 CHECK_EQ(qvecs.size(), weights.size());
121 CHECK_GT(qvecs.size(), 0);
123 if (qvecs.size() == 1) {
127 Eigen::Matrix4d A = Eigen::Matrix4d::Zero();
128 double weight_sum = 0;
130 for (
size_t i = 0; i < qvecs.size(); ++i) {
131 CHECK_GT(weights[i], 0);
133 A += weights[i] * qvec * qvec.transpose();
134 weight_sum += weights[i];
137 A.array() /= weight_sum;
139 const Eigen::Matrix4d eigenvectors =
140 Eigen::SelfAdjointEigenSolver<Eigen::Matrix4d>(A).eigenvectors();
142 return eigenvectors.col(3);
146 const Eigen::Vector3d& vector2) {
147 const Eigen::Vector3d v1 = vector1.normalized();
148 const Eigen::Vector3d v2 = vector2.normalized();
149 const Eigen::Vector3d v = v1.cross(v2);
151 const double c = v1.dot(v2);
153 return Eigen::Matrix3d::Identity();
155 return Eigen::Matrix3d::Identity() + v_x + 1 / (1 + c) * (v_x * v_x);
161 return -proj_matrix.leftCols<3>().transpose() * proj_matrix.rightCols<1>();
165 const Eigen::Vector3d& tvec) {
168 const Eigen::Quaterniond quat(normalized_qvec(0), -normalized_qvec(1),
169 -normalized_qvec(2), -normalized_qvec(3));
174 const Eigen::Vector3d& tvec1,
175 const Eigen::Vector4d& qvec2,
176 const Eigen::Vector3d& tvec2, Eigen::Vector4d* qvec12,
177 Eigen::Vector3d* tvec12) {
184 const Eigen::Vector3d& tvec1,
185 const Eigen::Vector4d& qvec2,
186 const Eigen::Vector3d& tvec2, Eigen::Vector4d* qvec12,
187 Eigen::Vector3d* tvec12) {
192 void InvertPose(
const Eigen::Vector4d& qvec,
const Eigen::Vector3d& tvec,
193 Eigen::Vector4d* inv_qvec, Eigen::Vector3d* inv_tvec) {
199 const Eigen::Vector4d& qvec2,
const Eigen::Vector3d& tvec2,
200 const double t, Eigen::Vector4d* qveci,
201 Eigen::Vector3d* tveci) {
204 const Eigen::Quaterniond quat1(normalized_qvec1(0), normalized_qvec1(1),
205 normalized_qvec1(2), normalized_qvec1(3));
206 const Eigen::Quaterniond quat2(normalized_qvec2(0), normalized_qvec2(1),
207 normalized_qvec2(2), normalized_qvec2(3));
208 const Eigen::Vector3d tvec12 = tvec2 - tvec1;
210 const Eigen::Quaterniond quati = quat1.slerp(t, quat2);
212 *qveci = Eigen::Vector4d(quati.w(), quati.x(), quati.y(), quati.z());
213 *tveci = tvec1 + tvec12 * t;
217 const Eigen::Vector3d& tvec1,
218 const Eigen::Vector4d& qvec2,
219 const Eigen::Vector3d& tvec2) {
222 return center2 - center1;
226 const std::vector<Eigen::Vector2d>& points1,
227 const std::vector<Eigen::Vector2d>& points2,
228 std::vector<Eigen::Vector3d>* points3D) {
229 CHECK_EQ(points1.size(), points2.size());
232 const double kMinDepth = std::numeric_limits<double>::epsilon();
233 const double max_depth = 1000.0f * (R.transpose() * t).norm();
235 for (
size_t i = 0; i < points1.size(); ++i) {
236 const Eigen::Vector3d point3D =
239 if (depth1 > kMinDepth && depth1 < max_depth) {
241 if (depth2 > kMinDepth && depth2 < max_depth) {
242 points3D->push_back(point3D);
246 return !points3D->empty();
Matrix< double, 3, 4 > Matrix3x4d
Eigen::Vector3d ProjectionCenterFromMatrix(const Eigen::Matrix3x4d &proj_matrix)
Eigen::Matrix3d RotationFromUnitVectors(const Eigen::Vector3d &vector1, const Eigen::Vector3d &vector2)
void ComputeRelativePose(const Eigen::Vector4d &qvec1, const Eigen::Vector3d &tvec1, const Eigen::Vector4d &qvec2, const Eigen::Vector3d &tvec2, Eigen::Vector4d *qvec12, Eigen::Vector3d *tvec12)
Eigen::Matrix3d EulerAnglesToRotationMatrix(const double rx, const double ry, const double rz)
void InvertPose(const Eigen::Vector4d &qvec, const Eigen::Vector3d &tvec, Eigen::Vector4d *inv_qvec, Eigen::Vector3d *inv_tvec)
Eigen::Matrix3d CrossProductMatrix(const Eigen::Vector3d &vector)
Eigen::Vector4d NormalizeQuaternion(const Eigen::Vector4d &qvec)
Eigen::Vector4d AverageQuaternions(const std::vector< Eigen::Vector4d > &qvecs, const std::vector< double > &weights)
void ConcatenatePoses(const Eigen::Vector4d &qvec1, const Eigen::Vector3d &tvec1, const Eigen::Vector4d &qvec2, const Eigen::Vector3d &tvec2, Eigen::Vector4d *qvec12, Eigen::Vector3d *tvec12)
double CalculateDepth(const Eigen::Matrix3x4d &proj_matrix, const Eigen::Vector3d &point3D)
Eigen::Vector3d TriangulatePoint(const Eigen::Matrix3x4d &proj_matrix1, const Eigen::Matrix3x4d &proj_matrix2, const Eigen::Vector2d &point1, const Eigen::Vector2d &point2)
Eigen::Vector4d RotationMatrixToQuaternion(const Eigen::Matrix3d &rot_mat)
Eigen::Vector4d ConcatenateQuaternions(const Eigen::Vector4d &qvec1, const Eigen::Vector4d &qvec2)
Eigen::Vector4d InvertQuaternion(const Eigen::Vector4d &qvec)
Eigen::Vector3d QuaternionRotatePoint(const Eigen::Vector4d &qvec, const Eigen::Vector3d &point)
Eigen::Vector3d ProjectionCenterFromPose(const Eigen::Vector4d &qvec, const Eigen::Vector3d &tvec)
bool IsNaN(const float x)
Eigen::Vector3d CalculateBaseline(const Eigen::Vector4d &qvec1, const Eigen::Vector3d &tvec1, const Eigen::Vector4d &qvec2, const Eigen::Vector3d &tvec2)
void RotationMatrixToEulerAngles(const Eigen::Matrix3d &R, double *rx, double *ry, double *rz)
Eigen::Matrix3x4d ComposeProjectionMatrix(const Eigen::Vector4d &qvec, const Eigen::Vector3d &tvec)
void InterpolatePose(const Eigen::Vector4d &qvec1, const Eigen::Vector3d &tvec1, const Eigen::Vector4d &qvec2, const Eigen::Vector3d &tvec2, const double t, Eigen::Vector4d *qveci, Eigen::Vector3d *tveci)
bool CheckCheirality(const Eigen::Matrix3d &R, const Eigen::Vector3d &t, const std::vector< Eigen::Vector2d > &points1, const std::vector< Eigen::Vector2d > &points2, std::vector< Eigen::Vector3d > *points3D)
Eigen::Matrix3d QuaternionToRotationMatrix(const Eigen::Vector4d &qvec)