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 
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 mrpt::maps::NearestNeighborsCapable& nnGlobal =
48  *mp2p_icp::MapToNN(pcGlobalMap, true /*throw if cannot convert*/);
49 
50  out.potential_pairings += pcLocal.size();
51 
52  // Empty maps? Nothing to do
53  if (pcGlobalMap.isEmpty() || pcLocal.empty()) return;
54 
56  pcLocal, localPose, maxLocalPointsPerLayer_, localPointsSampleSeed_);
57 
58  // Try to do matching only if the bounding boxes have some overlap:
59  if (!pcGlobalMap.boundingBox().intersection(
60  {tl.localMin, tl.localMax},
62  return;
63 
64  // Loop for each point in local map:
65  // --------------------------------------------------
66  const auto& lxs = pcLocal.getPointsBufferRef_x();
67  const auto& lys = pcLocal.getPointsBufferRef_y();
68  const auto& lzs = pcLocal.getPointsBufferRef_z();
69 
70  std::multimap<double, mrpt::tfest::TMatchingPair> sortedPairings;
71 
72  for (size_t i = 0; i < tl.x_locals.size(); i++)
73  {
74  size_t localIdx = tl.idxs.has_value() ? (*tl.idxs)[i] : i;
75 
77  ms.localPairedBitField.point_layers.at(localName)[localIdx])
78  continue; // skip, already paired.
79 
80  // For speed-up:
81  const float lx = tl.x_locals[i], ly = tl.y_locals[i],
82  lz = tl.z_locals[i];
83 
84  // Use a KD-tree to look for the nearnest neighbor of:
85  // (x_local, y_local, z_local)
86  // In "this" (global/reference) points map.
87  uint64_t tentativeGlobalIdx = 0;
88  float tentativeErrSqr = 0;
89  mrpt::math::TPoint3Df neighborPt;
90 
91  const bool searchOk = nnGlobal.nn_single_search(
92  {lx, ly, lz}, // Look closest to this guy
93  neighborPt, tentativeErrSqr, tentativeGlobalIdx);
94 
95  if (searchOk)
96  {
97  mrpt::tfest::TMatchingPair p;
98  p.globalIdx = tentativeGlobalIdx;
99  p.localIdx = localIdx;
100  p.global = neighborPt;
101  p.local = {lxs[localIdx], lys[localIdx], lzs[localIdx]};
102 
103  p.errorSquareAfterTransformation = tentativeErrSqr;
104 
105  // Sort by distance:
106  sortedPairings.emplace_hint(
107  sortedPairings.begin(), tentativeErrSqr, p);
108  }
109  } // For each local point
110 
111  // Now, keep the fraction of potential pairings according to the parameter
112  // "ratio":
113  const size_t nTotal = sortedPairings.size();
114  ASSERT_(nTotal > 0);
115 
116  const auto nKeep = mrpt::round(double(nTotal) * inliersRatio);
117 
118  // Prepare output: no correspondences initially:
119  auto itEnd = sortedPairings.begin();
120  std::advance(itEnd, nKeep);
121 
122  for (auto it = sortedPairings.begin(); it != itEnd; ++it)
123  {
124  const auto localIdx = it->second.localIdx;
125  const auto globalIdx = it->second.globalIdx;
126 
127  // Filter out if global alread assigned:
129  ms.globalPairedBitField.point_layers.at(globalName)[globalIdx])
130  continue; // skip, global point already paired.
131 
132  out.paired_pt2pt.push_back(it->second);
133 
134  // Mark local & global points as already paired:
135  ms.localPairedBitField.point_layers[localName].mark_as_set(localIdx);
136  ms.globalPairedBitField.point_layers[globalName].mark_as_set(globalIdx);
137  }
138 
139  MRPT_END
140 }
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:49
mp2p_icp::Pairings
Definition: Pairings.h:78
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
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:120
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
IMPLEMENTS_MRPT_OBJECT
IMPLEMENTS_MRPT_OBJECT(QualityEvaluator_RangeImageSimilarity, QualityEvaluator, mp2p_icp) using namespace mp2p_icp
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:686
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:174
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.


mp2p_icp
Author(s):
autogenerated on Wed Oct 23 2024 02:45:40