estimate_points_eigen.cpp
Go to the documentation of this file.
1 /* -------------------------------------------------------------------------
2  * A repertory of multi primitive-to-primitive (MP2P) ICP algorithms in C++
3  * Copyright (C) 2018-2024 Jose Luis Blanco, University of Almeria
4  * See LICENSE for license information.
5  * ------------------------------------------------------------------------- */
6 
15 #include <mrpt/core/exceptions.h>
16 
17 #include <stdexcept>
18 
20  const float* xs, const float* ys, const float* zs,
21  mrpt::optional_ref<const std::vector<size_t>> indices, std::optional<size_t> totalCount)
22 {
23  MRPT_START
24 
25  mrpt::math::TPoint3Df mean{0, 0, 0};
26  mrpt::math::CMatrixFixed<double, 3, 3> mat_a;
27  mat_a.setZero();
28 
29  // sanity checks:
30  if (totalCount)
31  {
32  if (*totalCount < 3)
33  {
34  THROW_EXCEPTION("totalCount: at least 3 points required.");
35  }
36 
37  const float inv_n = 1.0f / static_cast<float>(*totalCount);
38  for (size_t i = 0; i < *totalCount; i++)
39  {
40  mean.x += xs[i];
41  mean.y += ys[i];
42  mean.z += zs[i];
43  }
44  mean *= inv_n;
45  for (size_t i = 0; i < *totalCount; i++)
46  {
47  const auto a = mrpt::math::TPoint3Df(xs[i], ys[i], zs[i]) - mean;
48  mat_a(0, 0) += a.x * a.x;
49  mat_a(1, 0) += a.x * a.y;
50  mat_a(2, 0) += a.x * a.z;
51  mat_a(1, 1) += a.y * a.y;
52  mat_a(2, 1) += a.y * a.z;
53  mat_a(2, 2) += a.z * a.z;
54  }
55  mat_a *= inv_n;
56  }
57  else
58  {
59  ASSERTMSG_(indices, "Provide either optional<> indices or totalCount.");
60  const auto& idxs = indices->get();
61 
62  if (idxs.size() < 3)
63  {
64  THROW_EXCEPTION("indices: at least 3 points required.");
65  }
66 
67  const float inv_n = 1.0f / static_cast<float>(idxs.size());
68  for (size_t i = 0; i < idxs.size(); i++)
69  {
70  const auto pt_idx = idxs[i];
71  mean.x += xs[pt_idx];
72  mean.y += ys[pt_idx];
73  mean.z += zs[pt_idx];
74  }
75  mean *= inv_n;
76  for (size_t i = 0; i < idxs.size(); i++)
77  {
78  const auto pt_idx = idxs[i];
79  const auto a = mrpt::math::TPoint3Df(xs[pt_idx], ys[pt_idx], zs[pt_idx]) - mean;
80  mat_a(0, 0) += a.x * a.x;
81  mat_a(1, 0) += a.x * a.y;
82  mat_a(2, 0) += a.x * a.z;
83  mat_a(1, 1) += a.y * a.y;
84  mat_a(2, 1) += a.y * a.z;
85  mat_a(2, 2) += a.z * a.z;
86  }
87  mat_a *= inv_n;
88  }
89 
90  // Complete the upper-half symmetric part of the matrix:
91  mat_a(0, 1) = mat_a(1, 0);
92  mat_a(0, 2) = mat_a(2, 0);
93  mat_a(1, 2) = mat_a(2, 1);
94 
96  ret.meanCov = {mrpt::poses::CPoint3D(mean), mat_a};
97 
98  // Find eigenvalues & eigenvectors:
99  // This only looks at the lower-triangular part of the cov matrix.
100  mrpt::math::CMatrixFixed<double, 3, 3> eigVectors;
101  std::vector<double> eigVals;
102 
103  mat_a.eig_symmetric(eigVectors, eigVals);
104 
105  for (int i = 0; i < 3; i++)
106  {
107  ret.eigVals[i] = eigVals[i];
108  const auto ev = eigVectors.extractColumn<mrpt::math::TVector3D>(i);
109  ret.eigVectors[i] = {ev.x, ev.y, ev.z};
110  }
111 
112  return ret;
113 
114  MRPT_END
115 }
116 
118  const std::vector<mrpt::math::TPoint3Df>& pts, std::vector<float>& xs, std::vector<float>& ys,
119  std::vector<float>& zs)
120 {
121  const auto N = pts.size();
122  xs.resize(N);
123  ys.resize(N);
124  zs.resize(N);
125  for (size_t i = 0; i < N; i++)
126  {
127  xs[i] = pts[i].x;
128  ys[i] = pts[i].y;
129  zs[i] = pts[i].z;
130  }
131 }
mp2p_icp::estimate_points_eigen
PointCloudEigen estimate_points_eigen(const float *xs, const float *ys, const float *zs, mrpt::optional_ref< const std::vector< size_t >> indices, std::optional< size_t > totalCount=std::nullopt)
Definition: estimate_points_eigen.cpp:19
mp2p_icp::PointCloudEigen::eigVectors
std::array< mrpt::math::TVector3D, 3 > eigVectors
Definition: estimate_points_eigen.h:35
mp2p_icp::vector_of_points_to_xyz
void vector_of_points_to_xyz(const std::vector< mrpt::math::TPoint3Df > &pts, std::vector< float > &xs, std::vector< float > &ys, std::vector< float > &zs)
Definition: estimate_points_eigen.cpp:117
mp2p_icp::PointCloudEigen
Output of estimate_points_eigen()
Definition: estimate_points_eigen.h:32
mp2p_icp::PointCloudEigen::meanCov
mrpt::poses::CPointPDFGaussian meanCov
Definition: estimate_points_eigen.h:34
mp2p_icp::PointCloudEigen::eigVals
std::array< double, 3 > eigVals
sorted in ascending order
Definition: estimate_points_eigen.h:36
estimate_points_eigen.h
Calculate eigenvectors and eigenvalues from a set of points.


mp2p_icp
Author(s):
autogenerated on Mon May 26 2025 02:45:48