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-2021 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,
22  std::optional<size_t> totalCount)
23 {
24  MRPT_START
25 
26  mrpt::math::TPoint3Df mean{0, 0, 0};
27  mrpt::math::CMatrixFixed<double, 3, 3> mat_a;
28  mat_a.setZero();
29 
30  // sanity checks:
31  if (totalCount)
32  {
33  if (*totalCount < 3)
34  THROW_EXCEPTION("totalCount: at least 3 points required.");
35 
36  const float inv_n = (1.0f / *totalCount);
37  for (size_t i = 0; i < *totalCount; i++)
38  {
39  mean.x += xs[i];
40  mean.y += ys[i];
41  mean.z += zs[i];
42  }
43  mean *= inv_n;
44  for (size_t i = 0; i < *totalCount; i++)
45  {
46  const auto a = mrpt::math::TPoint3Df(xs[i], ys[i], zs[i]) - mean;
47  mat_a(0, 0) += a.x * a.x;
48  mat_a(1, 0) += a.x * a.y;
49  mat_a(2, 0) += a.x * a.z;
50  mat_a(1, 1) += a.y * a.y;
51  mat_a(2, 1) += a.y * a.z;
52  mat_a(2, 2) += a.z * a.z;
53  }
54  mat_a *= inv_n;
55  }
56  else
57  {
58  ASSERTMSG_(indices, "Provide either optional<> indices or totalCount.");
59  const auto& idxs = indices->get();
60 
61  if (idxs.size() < 3)
62  THROW_EXCEPTION("indices: at least 3 points required.");
63 
64  const float inv_n = (1.0f / idxs.size());
65  for (size_t i = 0; i < idxs.size(); i++)
66  {
67  const auto pt_idx = idxs[i];
68  mean.x += xs[pt_idx];
69  mean.y += ys[pt_idx];
70  mean.z += zs[pt_idx];
71  }
72  mean *= inv_n;
73  for (size_t i = 0; i < idxs.size(); i++)
74  {
75  const auto pt_idx = idxs[i];
76  const auto a =
77  mrpt::math::TPoint3Df(xs[pt_idx], ys[pt_idx], zs[pt_idx]) -
78  mean;
79  mat_a(0, 0) += a.x * a.x;
80  mat_a(1, 0) += a.x * a.y;
81  mat_a(2, 0) += a.x * a.z;
82  mat_a(1, 1) += a.y * a.y;
83  mat_a(2, 1) += a.y * a.z;
84  mat_a(2, 2) += a.z * a.z;
85  }
86  mat_a *= inv_n;
87  }
88 
89  // Complete the upper-half symmetric part of the matrix:
90  mat_a(0, 1) = mat_a(1, 0);
91  mat_a(0, 2) = mat_a(2, 0);
92  mat_a(1, 2) = mat_a(2, 1);
93 
95  ret.meanCov = {mrpt::poses::CPoint3D(mean), mat_a};
96 
97  // Find eigenvalues & eigenvectors:
98  // This only looks at the lower-triangular part of the cov matrix.
99  mrpt::math::CMatrixFixed<double, 3, 3> eigVectors;
100  std::vector<double> eigVals;
101 
102  mat_a.eig_symmetric(eigVectors, eigVals);
103 
104  for (int i = 0; i < 3; i++)
105  {
106  ret.eigVals[i] = eigVals[i];
107  const auto ev = eigVectors.extractColumn<mrpt::math::TVector3D>(i);
108  ret.eigVectors[i] = {ev.x, ev.y, ev.z};
109  }
110 
111  return ret;
112 
113  MRPT_END
114 }
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:33
mp2p_icp::PointCloudEigen
Output of estimate_points_eigen()
Definition: estimate_points_eigen.h:30
mp2p_icp::PointCloudEigen::meanCov
mrpt::poses::CPointPDFGaussian meanCov
Definition: estimate_points_eigen.h:32
mp2p_icp::PointCloudEigen::eigVals
std::array< double, 3 > eigVals
Definition: estimate_points_eigen.h:35
estimate_points_eigen.h
Calculate eigenvectors and eigenvalues from a set of points.


mrpt_local_obstacles
Author(s): Jose-Luis Blanco-Claraco
autogenerated on Mon Aug 14 2023 02:09:02