FilterDecimateAdaptive.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/core/round.h>
17 
19 
20 using namespace mp2p_icp_filters;
21 
22 void FilterDecimateAdaptive::Parameters::load_from_yaml(const mrpt::containers::yaml& c)
23 {
24  MCP_LOAD_OPT(c, enabled);
25 
26  MCP_LOAD_OPT(c, input_pointcloud_layer);
27  MCP_LOAD_REQ(c, output_pointcloud_layer);
28 
29  MCP_LOAD_REQ(c, desired_output_point_count);
30 
31  MCP_LOAD_OPT(c, assumed_minimum_pointcloud_bbox);
32  MCP_LOAD_OPT(c, maximum_voxel_count_per_dimension);
33  MCP_LOAD_OPT(c, minimum_input_points_per_voxel);
34 }
35 
37 {
38  mrpt::system::COutputLogger::setLoggerName("FilterDecimateAdaptive");
39 }
40 
41 void FilterDecimateAdaptive::initialize(const mrpt::containers::yaml& c)
42 {
43  MRPT_START
44 
45  MRPT_LOG_DEBUG_STREAM("Loading these params:\n" << c);
47 
48  MRPT_END
49 }
50 
52 {
53  MRPT_START
54 
55  if (!params_.enabled) return;
56 
57  // In:
58  const auto& pcPtr = inOut.point_layer(params_.input_pointcloud_layer);
59  ASSERTMSG_(
60  pcPtr,
61  mrpt::format(
62  "Input point cloud layer '%s' was not found.", params_.input_pointcloud_layer.c_str()));
63 
64  const auto& pc = *pcPtr;
65 
66  // Create if new: Append to existing layer, if already existed.
67  mrpt::maps::CPointsMap::Ptr outPc =
69 
70  const auto& _ = params_; // shortcut
71 
72  outPc->reserve(outPc->size() + _.desired_output_point_count);
73 
74  // Estimate voxel size dynamically from the input cloud:
76 
77  auto inputBbox = pc.boundingBox();
78  auto bboxSize = mrpt::math::TVector3Df(inputBbox.max - inputBbox.min);
79  mrpt::keep_max(bboxSize.x, _.assumed_minimum_pointcloud_bbox);
80  mrpt::keep_max(bboxSize.y, _.assumed_minimum_pointcloud_bbox);
81  mrpt::keep_max(bboxSize.z, _.assumed_minimum_pointcloud_bbox);
82 
83  const float largest_dim = bboxSize.norm(); // diagonal
84 
85  const float voxel_size = largest_dim / _.maximum_voxel_count_per_dimension;
86 
87  // Parse input cloud thru voxelization:
88  filter_grid_.setResolution(voxel_size);
90 
91  struct DataPerVoxel
92  {
93  const PointCloudToVoxelGrid::voxel_t* voxel = nullptr;
94  uint32_t nextIdx = 0;
95  bool exhausted = false;
96  };
97 
98  // A list of all "valid" voxels:
99  std::vector<DataPerVoxel> voxels;
100  voxels.reserve(filter_grid_.size());
101 
102  std::size_t nTotalVoxels = 0;
105  {
106  if (!data.indices.empty()) nTotalVoxels++;
107  if (data.indices.size() < _.minimum_input_points_per_voxel) return;
108 
109  voxels.emplace_back().voxel = &data;
110  });
111 
112  // Perform resampling:
113  // -------------------
114  const size_t nVoxels = voxels.size();
115  size_t voxelIdxIncrement = 1;
116  if (params_.desired_output_point_count < nVoxels)
117  {
118  voxelIdxIncrement = std::max<size_t>(
119  1, mrpt::round(nVoxels / static_cast<float>(params_.desired_output_point_count)));
120  }
121 
122  bool anyInsertInTheRound = false;
123 
124  for (size_t i = 0; outPc->size() < params_.desired_output_point_count;)
125  {
126  auto& ith = voxels[i];
127  if (!ith.exhausted)
128  {
129  auto ptIdx = ith.voxel->indices[ith.nextIdx++];
130  outPc->insertPointFrom(pc, ptIdx);
131  anyInsertInTheRound = true;
132 
133  if (ith.nextIdx >= ith.voxel->indices.size()) ith.exhausted = true;
134  }
135 
136  i += voxelIdxIncrement;
137  if (i >= nVoxels)
138  {
139  // one round done.
140  i = (i + 123653 /*a large arbitrary prime*/) % nVoxels;
141 
142  if (!anyInsertInTheRound)
143  {
144  // This means there is no more points and we must end
145  // despite we didn't reached the user's desired number of
146  // points:
147  break;
148  }
149 
150  anyInsertInTheRound = false;
151  }
152  }
153 
154  MRPT_LOG_DEBUG_STREAM(
155  "voxel_size=" << voxel_size << //
156  ", used voxels=" << nTotalVoxels);
157 
158  MRPT_END
159 }
mp2p_icp_filters::FilterDecimateAdaptive
Definition: FilterDecimateAdaptive.h:31
mp2p_icp_filters::FilterDecimateAdaptive::Parameters::desired_output_point_count
unsigned int desired_output_point_count
Definition: FilterDecimateAdaptive.h:53
mp2p_icp_filters::FilterDecimateAdaptive::Parameters::input_pointcloud_layer
std::string input_pointcloud_layer
Definition: FilterDecimateAdaptive.h:49
mp2p_icp_filters::FilterDecimateAdaptive::Parameters::enabled
bool enabled
Definition: FilterDecimateAdaptive.h:47
mp2p_icp_filters::FilterDecimateAdaptive::filter
void filter(mp2p_icp::metric_map_t &inOut) const override
Definition: FilterDecimateAdaptive.cpp:51
mp2p_icp_filters::FilterDecimateAdaptive::params_
Parameters params_
Definition: FilterDecimateAdaptive.h:65
mp2p_icp_filters::FilterDecimateAdaptive::Parameters::load_from_yaml
void load_from_yaml(const mrpt::containers::yaml &c)
Definition: FilterDecimateAdaptive.cpp:22
mp2p_icp_filters::FilterDecimateAdaptive::Parameters::maximum_voxel_count_per_dimension
unsigned int maximum_voxel_count_per_dimension
Definition: FilterDecimateAdaptive.h:61
IMPLEMENTS_MRPT_OBJECT
IMPLEMENTS_MRPT_OBJECT(FilterDecimateVoxelsQuadratic, mp2p_icp_filters::FilterBase, mp2p_icp_filters) using namespace mp2p_icp_filters
mp2p_icp_filters::PointCloudToVoxelGrid::voxel_t::indices
std::vector< std::size_t > indices
Definition: PointCloudToVoxelGrid.h:59
mp2p_icp_filters::FilterDecimateAdaptive::Parameters::output_pointcloud_layer
std::string output_pointcloud_layer
Definition: FilterDecimateAdaptive.h:51
mp2p_icp_filters::PointCloudToVoxelGrid::indices_t
Definition: PointCloudToVoxelGrid.h:62
mp2p_icp_filters::FilterBase
Definition: FilterBase.h:46
mp2p_icp_filters::FilterDecimateAdaptive::Parameters::assumed_minimum_pointcloud_bbox
double assumed_minimum_pointcloud_bbox
Definition: FilterDecimateAdaptive.h:60
mp2p_icp::metric_map_t::point_layer
mrpt::maps::CPointsMap::Ptr point_layer(const layer_name_t &name) const
Definition: metricmap.cpp:607
mp2p_icp_filters::FilterDecimateAdaptive::FilterDecimateAdaptive
FilterDecimateAdaptive()
Definition: FilterDecimateAdaptive.cpp:36
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::PointCloudToVoxelGrid::voxel_t
Definition: PointCloudToVoxelGrid.h:57
mp2p_icp_filters::PointCloudToVoxelGrid::clear
void clear()
Definition: PointCloudToVoxelGrid.cpp:75
mp2p_icp_filters::PointCloudToVoxelGrid::processPointCloud
void processPointCloud(const mrpt::maps::CPointsMap &p)
Definition: PointCloudToVoxelGrid.cpp:37
FilterDecimateAdaptive.h
An adaptive sampler of pointclouds.
mp2p_icp_filters::FilterDecimateAdaptive::filter_grid_
PointCloudToVoxelGrid filter_grid_
Definition: FilterDecimateAdaptive.h:68
mp2p_icp_filters::PointCloudToVoxelGrid::setResolution
void setResolution(const float voxel_size)
Definition: PointCloudToVoxelGrid.cpp:27
GetOrCreatePointLayer.h
Auxiliary function GetOrCreatePointLayer.
mp2p_icp::metric_map_t
Generic container of pointcloud(s), extracted features and other maps.
Definition: metricmap.h:55
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:81
mp2p_icp_filters::PointCloudToVoxelGrid::size
size_t size() const
Returns the number of occupied voxels.
Definition: PointCloudToVoxelGrid.cpp:87
mp2p_icp_filters
Definition: FilterAdjustTimestamps.h:19
mp2p_icp_filters::FilterDecimateAdaptive::initialize
void initialize(const mrpt::containers::yaml &c) override
Definition: FilterDecimateAdaptive.cpp:41
mp2p_icp_filters::FilterDecimateAdaptive::Parameters::minimum_input_points_per_voxel
unsigned int minimum_input_points_per_voxel
Definition: FilterDecimateAdaptive.h:57


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