QualityEvaluator_Voxels.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/maps/CVoxelMap.h>
15 
17 
18 using namespace mp2p_icp;
19 
21 {
22  mrpt::system::COutputLogger::setLoggerName("QualityEvaluator_Voxels");
23 }
24 
26  const mrpt::containers::yaml& params)
27 {
28  MCP_LOAD_REQ(params, voxel_layer_name);
29  MCP_LOAD_OPT(params, dist2quality_scale);
30 }
31 
32 namespace
33 {
34 double loss(double x, double y)
35 {
36  /*
37 
38  D=[0 0 +1;0 0.5 0; 0 1 -10;...
39  0.5 0 0; 0.5 0.5 0; 0.5 1 0;...
40  1 0 -10; 1 0.5 0; 1 1 +1];
41  x=D(:,1); y=D(:,2); z=D(:,3);
42 
43  sf = fit([x, y],z,'poly22')
44  plot(sf,[x,y],z)
45 
46  */
47 
48  // return 1.0 - 2 * x - 2 * y + 4 * x * y;
49  return 1.5 + x + y - 12 * x * x + 22 * x * y - 12 * y * y;
50 }
51 } // namespace
52 
54  const metric_map_t& pcGlobal, const metric_map_t& pcLocal,
55  const mrpt::poses::CPose3D& localPose,
56  [[maybe_unused]] const Pairings& pairingsFromICP) const
57 {
58  // Take both voxel maps from each map:
59  // ------------------------------------
60  if (pcGlobal.layers.count(voxel_layer_name) == 0)
61  THROW_EXCEPTION_FMT(
62  "Input global map was expected to contain a layer named '%s'",
63  voxel_layer_name.c_str());
64 
65  if (pcLocal.layers.count(voxel_layer_name) == 0)
66  THROW_EXCEPTION_FMT(
67  "Input local map was expected to contain a layer named '%s'",
68  voxel_layer_name.c_str());
69 
70  const mrpt::maps::CVoxelMap::Ptr globalVoxels =
71  std::dynamic_pointer_cast<mrpt::maps::CVoxelMap>(
72  pcGlobal.layers.at(voxel_layer_name));
73  if (!globalVoxels)
74  THROW_EXCEPTION_FMT(
75  "Input global map was expected to contain a layer named '%s' of "
76  "type 'CVoxelMap'",
77  voxel_layer_name.c_str());
78 
79  const mrpt::maps::CVoxelMap::Ptr localVoxels =
80  std::dynamic_pointer_cast<mrpt::maps::CVoxelMap>(
81  pcLocal.layers.at(voxel_layer_name));
82 
83  if (!localVoxels)
84  THROW_EXCEPTION_FMT(
85  "Input local map was expected to contain a layer named '%s' of "
86  "type 'CVoxelMap'",
87  voxel_layer_name.c_str());
88 
89  // Compare them:
90  // ----------------------------------
91 
92  // TODO(jlbc): Contribute upstream to Bonxai a "forEachCell() const":
93 
94  // get Bonxai grids:
95  auto& g = const_cast<Bonxai::VoxelGrid<mrpt::maps::VoxelNodeOccupancy>&>(
96  globalVoxels->grid());
97  auto& l = const_cast<Bonxai::VoxelGrid<mrpt::maps::VoxelNodeOccupancy>&>(
98  localVoxels->grid());
99 
100  auto gAccessor = g.createAccessor();
101  auto lAccessor = l.createAccessor();
102 
103  // Kullback-Leibler distance:
104  double dist = 0;
105  size_t dist_cells = 0;
106 
107  auto lmbdPerLocalVoxel = [&](mrpt::maps::CVoxelMap::voxel_node_t& data,
108  const Bonxai::CoordT& coord)
109  {
110  // get the corresponding cell in the global map:
111  const auto ptLocal = Bonxai::CoordToPos(coord, l.resolution);
112  const auto ptGlobal =
113  localPose.composePoint({ptLocal.x, ptLocal.y, ptLocal.z});
114 
115  auto* cell = gAccessor.value(Bonxai::PosToCoord(
116  {ptGlobal.x, ptGlobal.y, ptGlobal.z}, g.inv_resolution));
117  if (!cell) return; // cell not observed in global grid
118 
119  const float localOcc = localVoxels->l2p(data.occupancy);
120  const float globalOcc = globalVoxels->l2p(cell->occupancy);
121 
122  // barely observed cells?
123  if (std::abs(globalOcc - 0.5f) < 0.01f ||
124  std::abs(localOcc - 0.5f) < 0.01f)
125  return;
126 
127  const double d = loss(localOcc, globalOcc);
128  dist += d;
129  dist_cells++;
130  }; // end lambda for each voxel
131 
132  // run it:
133  l.forEachCell(lmbdPerLocalVoxel);
134 
135  auto lmbdPerGlobalVoxel = [&](mrpt::maps::CVoxelMap::voxel_node_t& data,
136  const Bonxai::CoordT& coord)
137  {
138  // get the corresponding cell in the local map:
139  const auto ptGlobal = Bonxai::CoordToPos(coord, l.resolution);
140  const auto ptLocal =
141  (-localPose).composePoint({ptGlobal.x, ptGlobal.y, ptGlobal.z});
142 
143  auto* cell = lAccessor.value(Bonxai::PosToCoord(
144  {ptLocal.x, ptLocal.y, ptLocal.z}, l.inv_resolution));
145  if (!cell) return; // cell not observed in global grid
146 
147  const float localOcc = localVoxels->l2p(cell->occupancy);
148  const float globalOcc = globalVoxels->l2p(data.occupancy);
149 
150  // barely observed cells?
151  if (std::abs(globalOcc - 0.5f) < 0.01f ||
152  std::abs(localOcc - 0.5f) < 0.01f)
153  return;
154 
155  const double d = loss(localOcc, globalOcc);
156  dist += d;
157  dist_cells++;
158  }; // end lambda for each voxel
159 
160  g.forEachCell(lmbdPerGlobalVoxel);
161 
162  // const auto nTotalLocalCells = l.activeCellsCount();
163  Result r;
164  r.quality = 0;
165  if (dist_cells)
166  {
167  dist /= dist_cells;
168  r.quality = 1.0 / (1.0 + std::exp(-dist2quality_scale * dist));
169  }
170  MRPT_LOG_DEBUG_STREAM(
171  "dist: " << dist << " dist_cells: " << dist_cells
172  << " quality: " << r.quality);
173 
174  return r;
175 }
mp2p_icp
Definition: covariance.h:17
mp2p_icp::QualityEvaluator::Result
Definition: QualityEvaluator.h:34
mp2p_icp::QualityEvaluator_Voxels
Definition: QualityEvaluator_Voxels.h:22
kitti-run-seq.f
string f
Definition: kitti-run-seq.py:12
mp2p_icp::Pairings
Definition: Pairings.h:94
QualityEvaluator_Voxels.h
Matching quality evaluator: comparison via voxel occupancy.
mp2p_icp::QualityEvaluator_Voxels::initialize
void initialize(const mrpt::containers::yaml &params) override
Definition: QualityEvaluator_Voxels.cpp:25
test.x
x
Definition: test.py:4
mp2p_icp::QualityEvaluator_Voxels::voxel_layer_name
std::string voxel_layer_name
Definition: QualityEvaluator_Voxels.h:37
mp2p_icp::QualityEvaluator::Result::quality
double quality
The resulting quality measure, in the range [0,1].
Definition: QualityEvaluator.h:37
d
d
mp2p_icp::QualityEvaluator_Voxels::dist2quality_scale
double dist2quality_scale
Definition: QualityEvaluator_Voxels.h:38
mp2p_icp::QualityEvaluator_Voxels::evaluate
Result evaluate(const metric_map_t &pcGlobal, const metric_map_t &pcLocal, const mrpt::poses::CPose3D &localPose, const Pairings &pairingsFromICP) const override
Definition: QualityEvaluator_Voxels.cpp:53
IMPLEMENTS_MRPT_OBJECT
IMPLEMENTS_MRPT_OBJECT(QualityEvaluator_RangeImageSimilarity, QualityEvaluator, mp2p_icp) using namespace mp2p_icp
mp2p_icp::metric_map_t
Generic container of pointcloud(s), extracted features and other maps.
Definition: metricmap.h:48
mp2p_icp::metric_map_t::layers
std::map< layer_name_t, mrpt::maps::CMetricMap::Ptr > layers
Definition: metricmap.h:75
mp2p_icp::QualityEvaluator_Voxels::QualityEvaluator_Voxels
QualityEvaluator_Voxels()
Definition: QualityEvaluator_Voxels.cpp:20
mp2p_icp::QualityEvaluator
Definition: QualityEvaluator.h:27


mp2p_icp
Author(s): Jose-Luis Blanco-Claraco
autogenerated on Tue Jul 2 2024 02:47:25