Matcher_Points_InlierRatio.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  * ------------------------------------------------------------------------- */
14 #include <mrpt/core/exceptions.h>
15 #include <mrpt/core/round.h>
16 #include <mrpt/version.h>
17 
19 
20 using namespace mp2p_icp;
21 
23 {
24  mrpt::system::COutputLogger::setLoggerName("Matcher_Points_InlierRatio");
25 }
26 
28  const mrpt::containers::yaml& params)
29 {
31 
32  MCP_LOAD_REQ(params, inliersRatio);
33 }
34 
36  const mrpt::maps::CMetricMap& pcGlobalMap,
37  const mrpt::maps::CPointsMap& pcLocal,
38  const mrpt::poses::CPose3D& localPose, MatchState& ms,
39  [[maybe_unused]] const layer_name_t& globalName,
40  const layer_name_t& localName, Pairings& out) const
41 {
42  MRPT_START
43 
44  ASSERT_GT_(inliersRatio, 0.0);
45  ASSERT_LT_(inliersRatio, 1.0);
46 
47  const auto* pcGlobalPtr =
48  dynamic_cast<const mrpt::maps::CPointsMap*>(&pcGlobalMap);
49  if (!pcGlobalPtr)
50  THROW_EXCEPTION_FMT(
51  "This class only supports global maps of point cloud types, but "
52  "found type '%s'",
53  pcGlobalMap.GetRuntimeClass()->className);
54  const auto& pcGlobal = *pcGlobalPtr;
55 
56  // Empty maps? Nothing to do
57  if (pcGlobal.empty() || pcLocal.empty()) return;
58 
60  pcLocal, localPose, maxLocalPointsPerLayer_, localPointsSampleSeed_);
61 
62  // Try to do matching only if the bounding boxes have some overlap:
63  if (!pcGlobal.boundingBox().intersection({tl.localMin, tl.localMax}))
64  return;
65 
66  // Loop for each point in local map:
67  // --------------------------------------------------
68  const auto& gxs = pcGlobal.getPointsBufferRef_x();
69  const auto& gys = pcGlobal.getPointsBufferRef_y();
70  const auto& gzs = pcGlobal.getPointsBufferRef_z();
71 
72  const auto& lxs = pcLocal.getPointsBufferRef_x();
73  const auto& lys = pcLocal.getPointsBufferRef_y();
74  const auto& lzs = pcLocal.getPointsBufferRef_z();
75 
76  std::multimap<double, mrpt::tfest::TMatchingPair> sortedPairings;
77 
78  for (size_t i = 0; i < tl.x_locals.size(); i++)
79  {
80  size_t localIdx = tl.idxs.has_value() ? (*tl.idxs)[i] : i;
81 
83  ms.localPairedBitField.point_layers.at(localName).at(localIdx))
84  continue; // skip, already paired.
85 
86  // For speed-up:
87  const float lx = tl.x_locals[i], ly = tl.y_locals[i],
88  lz = tl.z_locals[i];
89 
90  {
91  // Use a KD-tree to look for the nearnest neighbor of:
92  // (x_local, y_local, z_local)
93  // In "this" (global/reference) points map.
94 
95  float tentativeErrSqr;
96  const size_t tentativeGlobalIdx = pcGlobal.kdTreeClosestPoint3D(
97  lx, ly, lz, // Look closest to this guy
98  tentativeErrSqr // save here the min. distance squared
99  );
100 
101  mrpt::tfest::TMatchingPair p;
102  p.globalIdx = tentativeGlobalIdx;
103  p.localIdx = localIdx;
104  p.global = {
105  gxs[tentativeGlobalIdx], gys[tentativeGlobalIdx],
106  gzs[tentativeGlobalIdx]};
107  p.local = {lxs[localIdx], lys[localIdx], lzs[localIdx]};
108 
109  p.errorSquareAfterTransformation = tentativeErrSqr;
110 
111  // Sort by distance:
112  sortedPairings.emplace_hint(
113  sortedPairings.begin(), tentativeErrSqr, p);
114  } // End of test_match
115  } // For each local point
116 
117  // Now, keep the fraction of potential pairings according to the parameter
118  // "ratio":
119  const size_t nTotal = sortedPairings.size();
120  ASSERT_(nTotal > 0);
121 
122  const auto nKeep = mrpt::round(double(nTotal) * inliersRatio);
123 
124  // Prepare output: no correspondences initially:
125  auto itEnd = sortedPairings.begin();
126  std::advance(itEnd, nKeep);
127 
128  for (auto it = sortedPairings.begin(); it != itEnd; ++it)
129  {
130  const auto localIdx = it->second.localIdx;
131  const auto globalIdx = it->second.globalIdx;
132 
133  // Filter out if global alread assigned:
135  ms.globalPairedBitField.point_layers.at(globalName).at(globalIdx))
136  continue; // skip, global point already paired.
137 
138  out.paired_pt2pt.push_back(it->second);
139 
140  // Mark local & global points as already paired:
141  ms.localPairedBitField.point_layers[localName].at(localIdx) = true;
142 
143  ms.globalPairedBitField.point_layers[globalName].at(globalIdx) = true;
144  }
145 
146  MRPT_END
147 }
mp2p_icp
Definition: covariance.h:17
mp2p_icp::Matcher_Points_Base::TransformedLocalPointCloud
Definition: Matcher_Points_Base.h:82
mp2p_icp::Matcher
Definition: Matcher.h:70
mp2p_icp::Matcher_Points_InlierRatio::initialize
void initialize(const mrpt::containers::yaml &params) override
Definition: Matcher_Points_InlierRatio.cpp:27
mp2p_icp::Matcher_Points_Base::TransformedLocalPointCloud::y_locals
mrpt::aligned_std_vector< float > y_locals
Definition: Matcher_Points_Base.h:92
mp2p_icp::Matcher_Points_Base::allowMatchAlreadyMatchedGlobalPoints_
bool allowMatchAlreadyMatchedGlobalPoints_
Definition: Matcher_Points_Base.h:56
mp2p_icp::Matcher_Points_InlierRatio::inliersRatio
double inliersRatio
Definition: Matcher_Points_InlierRatio.h:49
mp2p_icp::Pairings
Definition: Pairings.h:94
mp2p_icp::Matcher_Points_Base::allowMatchAlreadyMatchedPoints_
bool allowMatchAlreadyMatchedPoints_
Definition: Matcher_Points_Base.h:52
mp2p_icp::layer_name_t
std::string layer_name_t
Definition: layer_name_t.h:22
mp2p_icp::Matcher_Points_InlierRatio::Matcher_Points_InlierRatio
Matcher_Points_InlierRatio()
Definition: Matcher_Points_InlierRatio.cpp:22
mp2p_icp::Matcher_Points_Base::TransformedLocalPointCloud::idxs
std::optional< std::vector< std::size_t > > idxs
Definition: Matcher_Points_Base.h:89
mp2p_icp::Matcher_Points_InlierRatio
Definition: Matcher_Points_InlierRatio.h:30
mp2p_icp::Matcher_Points_Base::initialize
void initialize(const mrpt::containers::yaml &params) override
Definition: Matcher_Points_Base.cpp:123
mp2p_icp::Matcher_Points_Base::TransformedLocalPointCloud::z_locals
mrpt::aligned_std_vector< float > z_locals
Definition: Matcher_Points_Base.h:92
mp2p_icp::MatchState
Definition: Matcher.h:34
kitti-batch-convert.out
string out
Definition: kitti-batch-convert.py:7
mp2p_icp::pointcloud_bitfield_t::point_layers
std::map< layer_name_t, std::vector< bool > > point_layers
Definition: metricmap.h:223
mp2p_icp::Matcher_Points_Base::localPointsSampleSeed_
uint64_t localPointsSampleSeed_
Definition: Matcher_Points_Base.h:48
mp2p_icp::MatchState::globalPairedBitField
pointcloud_bitfield_t globalPairedBitField
Like localPairedBitField for the global map.
Definition: Matcher.h:47
mp2p_icp::Matcher_Points_Base::maxLocalPointsPerLayer_
uint64_t maxLocalPointsPerLayer_
Definition: Matcher_Points_Base.h:47
mp2p_icp::MatchState::localPairedBitField
pointcloud_bitfield_t localPairedBitField
Definition: Matcher.h:44
IMPLEMENTS_MRPT_OBJECT
IMPLEMENTS_MRPT_OBJECT(metric_map_t, mrpt::serialization::CSerializable, mp2p_icp) using namespace mp2p_icp
mp2p_icp::Matcher_Points_Base::TransformedLocalPointCloud::x_locals
mrpt::aligned_std_vector< float > x_locals
Definition: Matcher_Points_Base.h:92
mp2p_icp::Matcher_Points_Base::transform_local_to_global
static TransformedLocalPointCloud transform_local_to_global(const mrpt::maps::CPointsMap &pcLocal, const mrpt::poses::CPose3D &localPose, const std::size_t maxLocalPoints=0, const uint64_t localPointsSampleSeed=0)
Definition: Matcher_Points_Base.cpp:173
mp2p_icp::Matcher_Points_InlierRatio::implMatchOneLayer
void implMatchOneLayer(const mrpt::maps::CMetricMap &pcGlobal, const mrpt::maps::CPointsMap &pcLocal, const mrpt::poses::CPose3D &localPose, MatchState &ms, const layer_name_t &globalName, const layer_name_t &localName, Pairings &out) const override
Definition: Matcher_Points_InlierRatio.cpp:35
Matcher_Points_InlierRatio.h
Pointcloud matcher: fixed ratio of inliers/outliers by distance.


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