small_gicp
projection.hpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright 2024 Kenji Koide
2 // SPDX-License-Identifier: MIT
3 #pragma once
4 
5 #include <array>
6 #include <Eigen/Core>
7 #include <Eigen/Eigen>
8 
9 namespace small_gicp {
10 
13  int max_scan_count = 128;
14 };
15 
19 public:
23  double operator()(const Eigen::Vector4d& pt) const { return pt[axis]; }
24 
31  template <typename PointCloud, typename IndexConstIterator>
32  static AxisAlignedProjection find_axis(const PointCloud& points, IndexConstIterator first, IndexConstIterator last, const ProjectionSetting& setting) {
33  const size_t N = std::distance(first, last);
34  Eigen::Vector4d sum_pt = Eigen::Vector4d::Zero();
35  Eigen::Vector4d sum_sq = Eigen::Vector4d::Zero();
36 
37  const size_t step = N < setting.max_scan_count ? 1 : N / setting.max_scan_count;
38  const size_t num_steps = N / step;
39  for (int i = 0; i < num_steps; i++) {
40  const auto itr = first + step * i;
41  const Eigen::Vector4d pt = traits::point(points, *itr);
42  sum_pt += pt;
43  sum_sq += pt.cwiseProduct(pt);
44  }
45 
46  const Eigen::Vector4d mean = sum_pt / sum_pt.w();
47  const Eigen::Vector4d var = (sum_sq - mean.cwiseProduct(sum_pt));
48 
49  return AxisAlignedProjection{var[0] > var[1] ? (var[0] > var[2] ? 0 : 2) : (var[1] > var[2] ? 1 : 2)};
50  }
51 
52 public:
53  int axis;
54 };
55 
59 public:
63  double operator()(const Eigen::Vector4d& pt) const { return Eigen::Map<const Eigen::Vector3d>(normal.data()).dot(pt.head<3>()); }
64 
71  template <typename PointCloud, typename IndexConstIterator>
72  static NormalProjection find_axis(const PointCloud& points, IndexConstIterator first, IndexConstIterator last, const ProjectionSetting& setting) {
73  const size_t N = std::distance(first, last);
74  Eigen::Vector4d sum_pt = Eigen::Vector4d::Zero();
75  Eigen::Matrix4d sum_sq = Eigen::Matrix4d::Zero();
76 
77  const size_t step = N < setting.max_scan_count ? 1 : N / setting.max_scan_count;
78  const size_t num_steps = N / step;
79  for (int i = 0; i < num_steps; i++) {
80  const auto itr = first + step * i;
81  const Eigen::Vector4d pt = traits::point(points, *itr);
82  sum_pt += pt;
83  sum_sq += pt * pt.transpose();
84  }
85 
86  const Eigen::Vector4d mean = sum_pt / sum_pt.w();
87  const Eigen::Matrix4d cov = (sum_sq - mean * sum_pt.transpose()) / sum_pt.w();
88 
89  Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eig;
90  eig.computeDirect(cov.block<3, 3>(0, 0));
91 
93  Eigen::Map<Eigen::Vector3d>(p.normal.data()) = eig.eigenvectors().col(2);
94  return p;
95  }
96 
97 public:
98  std::array<double, 3> normal;
99 };
100 
101 } // namespace small_gicp
auto point(const T &points, size_t i)
Get i-th point. 4D vector is used to take advantage of SIMD intrinsics. The last element must be fill...
Definition: traits.hpp:40
auto cov(const T &points, size_t i)
Get i-th covariance. Only the top-left 3x3 matrix is filled, and the bottom row and the right col mus...
Definition: traits.hpp:52
Definition: flat_container.hpp:12
Conventional axis-aligned projection (i.e., selecting any of XYZ axes with the largest variance).
Definition: projection.hpp:18
int axis
Axis index (0: X, 1: Y, 2: Z)
Definition: projection.hpp:53
static AxisAlignedProjection find_axis(const PointCloud &points, IndexConstIterator first, IndexConstIterator last, const ProjectionSetting &setting)
Find the axis with the largest variance.
Definition: projection.hpp:32
double operator()(const Eigen::Vector4d &pt) const
Project the point to the selected axis.
Definition: projection.hpp:23
Normal projection (i.e., selecting the 3D direction with the largest variance of the points).
Definition: projection.hpp:58
static NormalProjection find_axis(const PointCloud &points, IndexConstIterator first, IndexConstIterator last, const ProjectionSetting &setting)
Find the direction with the largest variance.
Definition: projection.hpp:72
double operator()(const Eigen::Vector4d &pt) const
Project the point to the normal direction.
Definition: projection.hpp:63
std::array< double, 3 > normal
Projection direction.
Definition: projection.hpp:98
Point cloud.
Definition: point_cloud.hpp:15
Parameters to control the projection axis search.
Definition: projection.hpp:12
int max_scan_count
Maximum number of points to use for the axis search.
Definition: projection.hpp:13