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-2024 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 
27 void Matcher_Points_InlierRatio::initialize(const mrpt::containers::yaml& params)
28 {
30 
31  MCP_LOAD_REQ(params, inliersRatio);
32 }
33 
35  const mrpt::maps::CMetricMap& pcGlobalMap, const mrpt::maps::CPointsMap& pcLocal,
36  const mrpt::poses::CPose3D& localPose, MatchState& ms,
37  [[maybe_unused]] const layer_name_t& globalName, const layer_name_t& localName,
38  Pairings& out) const
39 {
40  MRPT_START
41 
42  ASSERT_GT_(inliersRatio, 0.0);
43  ASSERT_LT_(inliersRatio, 1.0);
44 
45  const mrpt::maps::NearestNeighborsCapable& nnGlobal =
46  *mp2p_icp::MapToNN(pcGlobalMap, true /*throw if cannot convert*/);
47 
48  out.potential_pairings += pcLocal.size();
49 
50  // Empty maps? Nothing to do
51  if (pcGlobalMap.isEmpty() || pcLocal.empty()) return;
52 
54  pcLocal, localPose, maxLocalPointsPerLayer_, localPointsSampleSeed_);
55 
56  // Try to do matching only if the bounding boxes have some overlap:
57  if (!pcGlobalMap.boundingBox().intersection(
58  {tl.localMin, tl.localMax},
60  return;
61 
62  // Loop for each point in local map:
63  // --------------------------------------------------
64  const auto& lxs = pcLocal.getPointsBufferRef_x();
65  const auto& lys = pcLocal.getPointsBufferRef_y();
66  const auto& lzs = pcLocal.getPointsBufferRef_z();
67 
68  std::multimap<double, mrpt::tfest::TMatchingPair> sortedPairings;
69 
70  for (size_t i = 0; i < tl.x_locals.size(); i++)
71  {
72  size_t localIdx = tl.idxs.has_value() ? (*tl.idxs)[i] : i;
73 
75  ms.localPairedBitField.point_layers.at(localName)[localIdx])
76  continue; // skip, already paired.
77 
78  // For speed-up:
79  const float lx = tl.x_locals[i], ly = tl.y_locals[i], lz = tl.z_locals[i];
80 
81  // Use a KD-tree to look for the nearnest neighbor of:
82  // (x_local, y_local, z_local)
83  // In "this" (global/reference) points map.
84  uint64_t tentativeGlobalIdx = 0;
85  float tentativeErrSqr = 0;
86  mrpt::math::TPoint3Df neighborPt;
87 
88  const bool searchOk = nnGlobal.nn_single_search(
89  {lx, ly, lz}, // Look closest to this guy
90  neighborPt, tentativeErrSqr, tentativeGlobalIdx);
91 
92  if (searchOk)
93  {
94  mrpt::tfest::TMatchingPair p;
95  p.globalIdx = tentativeGlobalIdx;
96  p.localIdx = localIdx;
97  p.global = neighborPt;
98  p.local = {lxs[localIdx], lys[localIdx], lzs[localIdx]};
99 
100  p.errorSquareAfterTransformation = tentativeErrSqr;
101 
102  // Sort by distance:
103  sortedPairings.emplace_hint(sortedPairings.begin(), tentativeErrSqr, p);
104  }
105  } // For each local point
106 
107  // Now, keep the fraction of potential pairings according to the parameter
108  // "ratio":
109  const size_t nTotal = sortedPairings.size();
110  ASSERT_(nTotal > 0);
111 
112  const auto nKeep = mrpt::round(double(nTotal) * inliersRatio);
113 
114  // Prepare output: no correspondences initially:
115  auto itEnd = sortedPairings.begin();
116  std::advance(itEnd, nKeep);
117 
118  for (auto it = sortedPairings.begin(); it != itEnd; ++it)
119  {
120  const auto localIdx = it->second.localIdx;
121  const auto globalIdx = it->second.globalIdx;
122 
123  // Filter out if global alread assigned:
125  ms.globalPairedBitField.point_layers.at(globalName)[globalIdx])
126  continue; // skip, global point already paired.
127 
128  out.paired_pt2pt.push_back(it->second);
129 
130  // Mark local & global points as already paired:
131  ms.localPairedBitField.point_layers[localName].mark_as_set(localIdx);
132  ms.globalPairedBitField.point_layers[globalName].mark_as_set(globalIdx);
133  }
134 
135  MRPT_END
136 }
mp2p_icp
Definition: covariance.h:17
mp2p_icp::Matcher_Points_Base::bounding_box_intersection_check_epsilon_
double bounding_box_intersection_check_epsilon_
Definition: Matcher_Points_Base.h:63
mp2p_icp::Matcher_Points_Base::TransformedLocalPointCloud
Definition: Matcher_Points_Base.h:90
mp2p_icp::Matcher
Definition: Matcher.h:73
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:100
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:48
mp2p_icp::Pairings
Definition: Pairings.h:76
mp2p_icp::layer_name_t
std::string layer_name_t
Definition: layer_name_t.h:22
mp2p_icp::Matcher_Points_Base::allowMatchAlreadyMatchedPoints_
bool allowMatchAlreadyMatchedPoints_
Definition: Matcher_Points_Base.h:52
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:97
IMPLEMENTS_MRPT_OBJECT
IMPLEMENTS_MRPT_OBJECT(FilterDecimateVoxelsQuadratic, mp2p_icp_filters::FilterBase, mp2p_icp_filters) using namespace mp2p_icp_filters
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:114
mp2p_icp::Matcher_Points_Base::TransformedLocalPointCloud::z_locals
mrpt::aligned_std_vector< float > z_locals
Definition: Matcher_Points_Base.h:100
mp2p_icp::MatchState
Definition: Matcher.h:37
kitti-batch-convert.out
string out
Definition: kitti-batch-convert.py:7
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:50
mp2p_icp::pointcloud_bitfield_t::point_layers
std::map< layer_name_t, DenseOrSparseBitField > point_layers
Definition: pointcloud_bitfield.h:82
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:47
mp2p_icp::MapToNN
const mrpt::maps::NearestNeighborsCapable * MapToNN(const mrpt::maps::CMetricMap &map, bool throwIfNotImplemented)
Definition: metricmap.cpp:658
mp2p_icp::Matcher_Points_Base::TransformedLocalPointCloud::x_locals
mrpt::aligned_std_vector< float > x_locals
Definition: Matcher_Points_Base.h:100
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:163
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:34
Matcher_Points_InlierRatio.h
Pointcloud matcher: fixed ratio of inliers/outliers by distance.


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