gtsam_points
Loading...
Searching...
No Matches
balm_feature.hpp
1// SPDX-License-Identifier: MIT
2// Copyright (c) 2021 Kenji Koide (k.koide@aist.go.jp)
3
4#pragma once
5
6#include <Eigen/Core>
7
8namespace gtsam_points {
9
15public:
16 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
17
22 BALMFeature(const std::vector<Eigen::Vector3d>& points) {
23 Eigen::Vector3d sum_pts = Eigen::Vector3d::Zero();
24 Eigen::Matrix3d sum_cross = Eigen::Matrix3d::Zero();
25 for (const auto& pt : points) {
26 sum_pts += pt;
27 sum_cross += pt * pt.transpose();
28 }
29
30 num_points = points.size();
31 mean = sum_pts / points.size();
32 cov = (sum_cross - mean * sum_pts.transpose()) / points.size();
33
34 // TODO: Should use computeDirect()?
35 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eig(cov);
36 eigenvalues = eig.eigenvalues();
37 eigenvectors = eig.eigenvectors();
38 }
39
44 template <int k>
45 Eigen::Matrix<double, 1, 3> Ji(const Eigen::Vector3d& p_i) const {
46 Eigen::Vector3d u = eigenvectors.col(k);
47 return 2.0 / num_points * (p_i - mean).transpose() * u * u.transpose();
48 }
49
54 template <int k>
55 Eigen::Matrix3d Hij(const Eigen::Vector3d& p_i, const Eigen::Vector3d& p_j, bool i_equals_j) const {
56 const int N = num_points;
57 Eigen::Matrix3d F_k;
58 F_k.row(0) = Fmn<0, k>(p_j);
59 F_k.row(1) = Fmn<1, k>(p_j);
60 F_k.row(2) = Fmn<2, k>(p_j);
61
62 const auto& u_k = eigenvectors.col(k);
63 const auto& U = eigenvectors;
64
65 // TODO: Remove redundant computations (e.g., p_i - mean, U * F_k)
66 if (i_equals_j) {
67 const auto t1 = (N - 1) / static_cast<double>(N) * u_k * u_k.transpose();
68 const auto t2 = u_k * (p_i - mean).transpose() * U * F_k;
69 const auto t3 = U * F_k * (u_k.transpose() * (p_i - mean));
70 Eigen::Matrix3d H = 2.0 / N * (t1 + t2 + t3);
71 return H;
72 } else {
73 const auto t1 = -1.0 / N * u_k * u_k.transpose();
74 const auto t2 = u_k * (p_i - mean).transpose() * U * F_k;
75 const auto t3 = U * F_k * (u_k.transpose() * (p_i - mean));
76 Eigen::Matrix3d H = 2.0 / N * (t1 + t2 + t3);
77
78 return H;
79 }
80 }
81
85 template <int m, int n>
86 Eigen::Matrix<double, 1, 3> Fmn(const Eigen::Vector3d& pt) const {
87 if constexpr (m == n) {
88 return Eigen::Matrix<double, 1, 3>::Zero();
89 } else {
90 const double l_m = eigenvalues[m];
91 const double l_n = eigenvalues[n];
92 const auto& u_m = eigenvectors.col(m);
93 const auto& u_n = eigenvectors.col(n);
94
95 const auto lhs = (pt - mean).transpose() / (num_points * (l_n - l_m));
96 const auto rhs = u_m * u_n.transpose() + u_n * u_m.transpose();
97 return lhs * rhs;
98 }
99 }
100
101 int num_points;
102 Eigen::Vector3d mean;
103 Eigen::Matrix3d cov;
104
105 Eigen::Vector3d eigenvalues; // The smaller the first
106 Eigen::Matrix3d eigenvectors; //
107};
108
109} // namespace gtsam_points
Utility class to calculate eigenvalues and derivatives of those Liu and Zhang, "BALM: Bundle Adjustme...
Definition balm_feature.hpp:14
Eigen::Matrix< double, 1, 3 > Fmn(const Eigen::Vector3d &pt) const
F^{p_j}_{m, n}.
Definition balm_feature.hpp:86
EIGEN_MAKE_ALIGNED_OPERATOR_NEW BALMFeature(const std::vector< Eigen::Vector3d > &points)
Constructor.
Definition balm_feature.hpp:22
Eigen::Matrix3d Hij(const Eigen::Vector3d &p_i, const Eigen::Vector3d &p_j, bool i_equals_j) const
Second order derivatives.
Definition balm_feature.hpp:55
Eigen::Matrix< double, 1, 3 > Ji(const Eigen::Vector3d &p_i) const
First order derivatives.
Definition balm_feature.hpp:45