FilterDecimateVoxelsQuadratic.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  * ------------------------------------------------------------------------- */
15 #include <mrpt/containers/yaml.h>
16 #include <mrpt/maps/CSimplePointsMap.h>
17 #include <mrpt/math/ops_containers.h> // dotProduct
18 #include <mrpt/random/RandomGenerators.h>
19 
21  FilterDecimateVoxelsQuadratic, mp2p_icp_filters::FilterBase,
23 
24 using namespace mp2p_icp_filters;
25 
27  const mrpt::containers::yaml& c)
28 {
29  MCP_LOAD_OPT(c, input_pointcloud_layer);
30  MCP_LOAD_OPT(c, error_on_missing_input_layer);
31  MCP_LOAD_OPT(c, use_random_point_within_voxel);
32 
33  MCP_LOAD_REQ(c, output_pointcloud_layer);
34 
35  MCP_LOAD_REQ(c, voxel_filter_resolution);
36  MCP_LOAD_REQ(c, quadratic_reference_radius);
37  MCP_LOAD_REQ(c, use_voxel_average);
38  MCP_LOAD_REQ(c, use_closest_to_voxel_average);
39 }
40 
42 
43 void FilterDecimateVoxelsQuadratic::initialize(const mrpt::containers::yaml& c)
44 {
45  MRPT_START
46 
47  MRPT_LOG_DEBUG_STREAM("Loading these params:\n" << c);
49 
52 
53  MRPT_END
54 }
55 
57 {
58  MRPT_START
59 
60  // Out:
61  ASSERT_(!params_.output_pointcloud_layer.empty());
62 
63  // Create if new: Append to existing layer, if already existed.
64  mrpt::maps::CPointsMap::Ptr outPc =
66 
67  // In:
68  mrpt::maps::CPointsMap* pcPtr = nullptr;
69  if (auto itLy = inOut.layers.find(params_.input_pointcloud_layer);
70  itLy != inOut.layers.end())
71  {
72  pcPtr = mp2p_icp::MapToPointsMap(*itLy->second);
73  if (!pcPtr)
74  THROW_EXCEPTION_FMT(
75  "Layer '%s' must be of point cloud type.",
77  }
78  else
79  {
80  // Input layer doesn't exist:
82  {
83  THROW_EXCEPTION_FMT(
84  "Input layer '%s' not found on input map.",
86  }
87  else
88  {
89  // Silently return with an unmodified output layer "outPc"
90  return;
91  }
92  }
93 
94  // Non-linear transform input cloud:
95  const auto& rawPc = *pcPtr;
96 
97  mrpt::maps::CSimplePointsMap pc;
98  pc.reserve(rawPc.size());
99 
100  const auto& xs = rawPc.getPointsBufferRef_x();
101  const auto& ys = rawPc.getPointsBufferRef_y();
102  const auto& zs = rawPc.getPointsBufferRef_z();
103  for (size_t i = 0; i < xs.size(); i++)
104  {
105  pc.insertPointFast(
106  real2grid(xs[i]), real2grid(ys[i]), real2grid(zs[i]));
107  }
108  pc.mark_as_modified();
109 
110  // Do filter:
111  outPc->reserve(outPc->size() + pc.size() / 10);
112 
115 
116  // const auto& xs = pc.getPointsBufferRef_x();
117  // const auto& ys = pc.getPointsBufferRef_y();
118  // const auto& zs = pc.getPointsBufferRef_z();
119 
120  auto rng = mrpt::random::CRandomGenerator();
121  // TODO?: rng.randomize(seed);
122 
123  // Inverse nonlinear transformation:
124  auto lambdaInsertPt = [&outPc](float x, float y, float z)
125  { outPc->insertPointFast(x, y, z); };
126 
127  size_t nonEmptyVoxels = 0;
128 
132  {
133  if (vxl.indices.empty()) return;
134 
135  nonEmptyVoxels++;
136 
139  {
140  // Analyze the voxel contents:
141  auto mean = mrpt::math::TPoint3Df(0, 0, 0);
142  const float inv_n = (1.0f / vxl.indices.size());
143  for (size_t i = 0; i < vxl.indices.size(); i++)
144  {
145  const auto pt_idx = vxl.indices[i];
146  mean.x += xs[pt_idx];
147  mean.y += ys[pt_idx];
148  mean.z += zs[pt_idx];
149  }
150  mean *= inv_n;
151 
153  {
154  std::optional<float> minSqrErr;
155  std::optional<size_t> bestIdx;
156 
157  for (size_t i = 0; i < vxl.indices.size(); i++)
158  {
159  const auto pt_idx = vxl.indices[i];
160  const float sqrErr = mrpt::square(xs[pt_idx] - mean.x) +
161  mrpt::square(ys[pt_idx] - mean.y) +
162  mrpt::square(zs[pt_idx] - mean.z);
163 
164  if (!minSqrErr.has_value() || sqrErr < *minSqrErr)
165  {
166  minSqrErr = sqrErr;
167  bestIdx = pt_idx;
168  }
169  }
170  // Insert the closest to the mean:
171  lambdaInsertPt(xs[*bestIdx], ys[*bestIdx], zs[*bestIdx]);
172  }
173  else
174  {
175  // Insert the mean:
176  lambdaInsertPt(mean.x, mean.y, mean.z);
177  }
178  }
179  else
180  {
181  // Insert a randomly-picked point:
182  const auto idxInVoxel =
184  ? (rng.drawUniform64bit() % vxl.indices.size())
185  : 0UL;
186 
187  const auto pt_idx = vxl.indices.at(idxInVoxel);
188  lambdaInsertPt(xs[pt_idx], ys[pt_idx], zs[pt_idx]);
189  }
190  });
191 
192  outPc->mark_as_modified();
193 
194  MRPT_LOG_DEBUG_STREAM("Voxel counts: total=" << nonEmptyVoxels);
195 
196  MRPT_END
197 }
mp2p_icp_filters::FilterDecimateVoxelsQuadratic::Parameters::error_on_missing_input_layer
bool error_on_missing_input_layer
Definition: FilterDecimateVoxelsQuadratic.h:60
mp2p_icp_filters::FilterDecimateVoxelsQuadratic::Parameters::voxel_filter_resolution
double voxel_filter_resolution
Definition: FilterDecimateVoxelsQuadratic.h:66
mp2p_icp_filters::FilterDecimateVoxelsQuadratic::filter_grid_
PointCloudToVoxelGrid filter_grid_
Definition: FilterDecimateVoxelsQuadratic.h:105
mp2p_icp_filters::FilterDecimateVoxelsQuadratic::Parameters::input_pointcloud_layer
std::string input_pointcloud_layer
Definition: FilterDecimateVoxelsQuadratic.h:54
FilterDecimateVoxelsQuadratic.h
Builds a new layer with a decimated version of an input layer.
mp2p_icp_filters::FilterDecimateVoxelsQuadratic::Parameters::quadratic_reference_radius
double quadratic_reference_radius
Definition: FilterDecimateVoxelsQuadratic.h:69
mp2p_icp_filters::FilterDecimateVoxelsQuadratic::real2grid
float real2grid(float x) const
Definition: FilterDecimateVoxelsQuadratic.h:87
test.x
x
Definition: test.py:4
mp2p_icp_filters::FilterDecimateVoxelsQuadratic::quadratic_reference_radius_inv_
float quadratic_reference_radius_inv_
Definition: FilterDecimateVoxelsQuadratic.h:107
mp2p_icp_filters::FilterDecimateVoxelsQuadratic::Parameters::use_closest_to_voxel_average
bool use_closest_to_voxel_average
Definition: FilterDecimateVoxelsQuadratic.h:77
IMPLEMENTS_MRPT_OBJECT
IMPLEMENTS_MRPT_OBJECT(FilterDecimateVoxelsQuadratic, mp2p_icp_filters::FilterBase, mp2p_icp_filters) using namespace mp2p_icp_filters
mp2p_icp_filters::FilterDecimateVoxelsQuadratic::filter
void filter(mp2p_icp::metric_map_t &inOut) const override
Definition: FilterDecimateVoxelsQuadratic.cpp:56
mp2p_icp_filters::PointCloudToVoxelGrid::voxel_t::indices
std::vector< std::size_t > indices
Definition: PointCloudToVoxelGrid.h:59
mp2p_icp_filters::PointCloudToVoxelGrid::indices_t
Definition: PointCloudToVoxelGrid.h:62
mp2p_icp::MapToPointsMap
const mrpt::maps::CPointsMap * MapToPointsMap(const mrpt::maps::CMetricMap &map)
Definition: metricmap.cpp:648
mp2p_icp_filters::FilterBase
Definition: FilterBase.h:46
mp2p_icp_filters::GetOrCreatePointLayer
mrpt::maps::CPointsMap::Ptr GetOrCreatePointLayer(mp2p_icp::metric_map_t &m, const std::string &layerName, bool allowEmptyName=true, const std::string &classForLayerCreation="mrpt::maps::CSimplePointsMap")
Definition: GetOrCreatePointLayer.cpp:15
mp2p_icp_filters::FilterDecimateVoxelsQuadratic::Parameters::use_random_point_within_voxel
bool use_random_point_within_voxel
Definition: FilterDecimateVoxelsQuadratic.h:81
mp2p_icp_filters::PointCloudToVoxelGrid::voxel_t
Definition: PointCloudToVoxelGrid.h:57
mp2p_icp_filters::PointCloudToVoxelGrid::clear
void clear()
Definition: PointCloudToVoxelGrid.cpp:77
mp2p_icp_filters::PointCloudToVoxelGrid::processPointCloud
void processPointCloud(const mrpt::maps::CPointsMap &p)
Definition: PointCloudToVoxelGrid.cpp:39
mp2p_icp_filters::FilterDecimateVoxelsQuadratic::Parameters::load_from_yaml
void load_from_yaml(const mrpt::containers::yaml &c)
Definition: FilterDecimateVoxelsQuadratic.cpp:26
mp2p_icp_filters::PointCloudToVoxelGrid::setResolution
void setResolution(const float voxel_size)
Definition: PointCloudToVoxelGrid.cpp:29
mp2p_icp_filters::FilterDecimateVoxelsQuadratic::Parameters::output_pointcloud_layer
std::string output_pointcloud_layer
Definition: FilterDecimateVoxelsQuadratic.h:63
mp2p_icp_filters::FilterDecimateVoxelsQuadratic::initialize
void initialize(const mrpt::containers::yaml &c) override
Definition: FilterDecimateVoxelsQuadratic.cpp:43
GetOrCreatePointLayer.h
Auxiliary function GetOrCreatePointLayer.
mp2p_icp::metric_map_t
Generic container of pointcloud(s), extracted features and other maps.
Definition: metricmap.h:49
mp2p_icp_filters::PointCloudToVoxelGrid::visit_voxels
void visit_voxels(const std::function< void(const indices_t idx, const voxel_t &vxl)> &userCode) const
Definition: PointCloudToVoxelGrid.cpp:83
mp2p_icp_filters::FilterDecimateVoxelsQuadratic::params_
Parameters params_
Definition: FilterDecimateVoxelsQuadratic.h:85
mp2p_icp_filters::FilterDecimateVoxelsQuadratic::Parameters::use_voxel_average
bool use_voxel_average
Definition: FilterDecimateVoxelsQuadratic.h:73
mp2p_icp::metric_map_t::layers
std::map< layer_name_t, mrpt::maps::CMetricMap::Ptr > layers
Definition: metricmap.h:76
mp2p_icp_filters
Definition: FilterAdjustTimestamps.h:19
mp2p_icp_filters::FilterDecimateVoxelsQuadratic::FilterDecimateVoxelsQuadratic
FilterDecimateVoxelsQuadratic()


mp2p_icp
Author(s):
autogenerated on Thu Oct 17 2024 02:45:33