FilterDecimateVoxels.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-2021 Jose Luis Blanco, University of Almeria
4  * See LICENSE for license information.
5  * ------------------------------------------------------------------------- */
14 #include <mrpt/containers/yaml.h>
15 #include <mrpt/maps/CSimplePointsMap.h>
16 #include <mrpt/math/ops_containers.h> // dotProduct
17 #include <mrpt/obs/CObservation2DRangeScan.h>
18 #include <mrpt/random/RandomGenerators.h>
19 
21  FilterDecimateVoxels, mp2p_icp_filters::FilterBase, mp2p_icp_filters)
22 
23 using namespace mp2p_icp_filters;
24 
26  const mrpt::containers::yaml& c)
27 {
28  MCP_LOAD_OPT(c, input_pointcloud_layer);
29  MCP_LOAD_OPT(c, error_on_missing_input_layer);
30 
31  MCP_LOAD_REQ(c, output_pointcloud_layer);
32 
33  MCP_LOAD_REQ(c, voxel_filter_resolution);
34  MCP_LOAD_REQ(c, use_voxel_average);
35 
36  ASSERT_(
37  c.has("bounding_box_min") && c["bounding_box_min"].isSequence() &&
38  c["bounding_box_min"].asSequence().size() == 3);
39  ASSERT_(
40  c.has("bounding_box_max") && c["bounding_box_max"].isSequence() &&
41  c["bounding_box_max"].asSequence().size() == 3);
42 
43  const auto bboxMin = c["bounding_box_min"].toStdVector<double>();
44  const auto bboxMax = c["bounding_box_max"].toStdVector<double>();
45 
46  for (int i = 0; i < 3; i++)
47  {
48  bounding_box.min[i] = bboxMin.at(i);
49  bounding_box.max[i] = bboxMax.at(i);
50  }
51 }
52 
54 
55 void FilterDecimateVoxels::initialize(const mrpt::containers::yaml& c)
56 {
57  MRPT_START
58 
59  MRPT_LOG_DEBUG_STREAM("Loading these params:\n" << c);
61 
65 
66  MRPT_END
67 }
68 
70 {
71  MRPT_START
72 
73  // Out:
74  ASSERT_(!params_.output_pointcloud_layer.empty());
75 
76  // Create if new: Append to existing layer, if already existed.
77  mrpt::maps::CPointsMap::Ptr outPc;
78  if (auto itLy = inOut.layers.find(params_.output_pointcloud_layer);
79  itLy != inOut.layers.end())
80  {
81  outPc = std::dynamic_pointer_cast<mrpt::maps::CPointsMap>(itLy->second);
82  if (!outPc)
83  THROW_EXCEPTION_FMT(
84  "Layer '%s' must be of point cloud type.",
86  }
87  else
88  {
89  outPc = mrpt::maps::CSimplePointsMap::Create();
90  inOut.layers[params_.output_pointcloud_layer] = outPc;
91  }
92 
93  // In:
94  mrpt::maps::CPointsMap::Ptr pcPtr;
95  if (auto itLy = inOut.layers.find(params_.input_pointcloud_layer);
96  itLy != inOut.layers.end())
97  {
98  pcPtr = std::dynamic_pointer_cast<mrpt::maps::CPointsMap>(itLy->second);
99  if (!pcPtr)
100  THROW_EXCEPTION_FMT(
101  "Layer '%s' must be of point cloud type.",
103  }
104  else
105  {
106  // Input layer doesn't exist:
108  {
109  THROW_EXCEPTION_FMT(
110  "Input layer '%s' not found on input map.",
112  }
113  else
114  {
115  // Silently return with an unmodified output layer "outPc"
116  return;
117  }
118  }
119 
120  const auto& pc = *pcPtr;
121 
122  // Do filter:
123  outPc->reserve(outPc->size() + pc.size() / 10);
124 
127 
128  const auto& xs = pc.getPointsBufferRef_x();
129  const auto& ys = pc.getPointsBufferRef_y();
130  const auto& zs = pc.getPointsBufferRef_z();
131 
132  auto rng = mrpt::random::CRandomGenerator();
133  // TODO?: rng.randomize(seed);
134 
135  size_t nonEmptyVoxels = 0;
136  for (const auto& vxl_pts : filter_grid_.pts_voxels)
137  {
138  if (vxl_pts.indices.empty()) continue;
139 
140  nonEmptyVoxels++;
141 
143  {
144  // Analyze the voxel contents:
145  auto mean = mrpt::math::TPoint3Df(0, 0, 0);
146  const float inv_n = (1.0f / vxl_pts.indices.size());
147  for (size_t i = 0; i < vxl_pts.indices.size(); i++)
148  {
149  const auto pt_idx = vxl_pts.indices[i];
150  mean.x += xs[pt_idx];
151  mean.y += ys[pt_idx];
152  mean.z += zs[pt_idx];
153  }
154  mean *= inv_n;
155 
156  // Insert the mean:
157  outPc->insertPointFast(mean.x, mean.y, mean.z);
158  }
159  else
160  {
161  // Insert a randomly-picked point:
162  const auto idxInVoxel =
163  rng.drawUniform64bit() % vxl_pts.indices.size();
164 
165  const auto pt_idx = vxl_pts.indices.at(idxInVoxel);
166  outPc->insertPointFast(xs[pt_idx], ys[pt_idx], zs[pt_idx]);
167  }
168  }
169  MRPT_LOG_DEBUG_STREAM("Voxel counts: total=" << nonEmptyVoxels);
170 
171  MRPT_END
172 }
mp2p_icp_filters::FilterDecimateVoxels::Parameters::output_pointcloud_layer
std::string output_pointcloud_layer
Definition: FilterDecimateVoxels.h:62
mp2p_icp_filters::FilterDecimateVoxels::filter
void filter(mp2p_icp::metric_map_t &inOut) const override
Definition: FilterDecimateVoxels.cpp:69
IMPLEMENTS_MRPT_OBJECT
IMPLEMENTS_MRPT_OBJECT(FilterDecimateVoxels, mp2p_icp_filters::FilterBase, mp2p_icp_filters) using namespace mp2p_icp_filters
mp2p_icp_filters::FilterDecimateVoxels::Parameters::bounding_box
mrpt::math::TBoundingBoxf bounding_box
Definition: FilterDecimateVoxels.h:78
mp2p_icp_filters::FilterDecimateVoxels::filter_grid_
PointCloudToVoxelGrid filter_grid_
Definition: FilterDecimateVoxels.h:86
mp2p_icp_filters::FilterDecimateVoxels::initialize
void initialize(const mrpt::containers::yaml &c) override
Definition: FilterDecimateVoxels.cpp:55
mp2p_icp_filters::FilterDecimateVoxels::Parameters::load_from_yaml
void load_from_yaml(const mrpt::containers::yaml &c)
Definition: FilterDecimateVoxels.cpp:25
mp2p_icp_filters::FilterDecimateVoxels::Parameters::use_voxel_average
bool use_voxel_average
Definition: FilterDecimateVoxels.h:69
mp2p_icp_filters::FilterBase
Definition: FilterBase.h:37
mp2p_icp_filters::PointCloudToVoxelGrid::resize
void resize(const mrpt::math::TPoint3D &min_corner, const mrpt::math::TPoint3D &max_corner, const float voxel_size)
Definition: PointCloudToVoxelGrid.cpp:22
mp2p_icp_filters::FilterDecimateVoxels::Parameters::voxel_filter_resolution
double voxel_filter_resolution
Definition: FilterDecimateVoxels.h:65
mp2p_icp_filters::FilterDecimateVoxels::FilterDecimateVoxels
FilterDecimateVoxels()
mp2p_icp_filters::FilterDecimateVoxels::Parameters::error_on_missing_input_layer
bool error_on_missing_input_layer
Definition: FilterDecimateVoxels.h:59
mp2p_icp_filters::PointCloudToVoxelGrid::clear
void clear()
Definition: PointCloudToVoxelGrid.cpp:84
mp2p_icp_filters::FilterDecimateVoxels::params_
Parameters params_
Definition: FilterDecimateVoxels.h:83
mp2p_icp_filters::PointCloudToVoxelGrid::processPointCloud
void processPointCloud(const mrpt::maps::CPointsMap &p)
Definition: PointCloudToVoxelGrid.cpp:39
mp2p_icp::metric_map_t
Generic container of pointcloud(s), extracted features and other maps.
Definition: metricmap.h:47
mp2p_icp_filters::FilterDecimateVoxels::Parameters::input_pointcloud_layer
std::string input_pointcloud_layer
Definition: FilterDecimateVoxels.h:53
mp2p_icp_filters::PointCloudToVoxelGrid::pts_voxels
grid_t pts_voxels
Definition: PointCloudToVoxelGrid.h:64
mp2p_icp::metric_map_t::layers
std::map< layer_name_t, mrpt::maps::CMetricMap::Ptr > layers
Definition: metricmap.h:74
mp2p_icp_filters
Definition: FilterBase.h:25
FilterDecimateVoxels.h
Builds a new layer with a decimated version of an input layer.


mrpt_local_obstacles
Author(s): Jose-Luis Blanco-Claraco
autogenerated on Mon Aug 14 2023 02:09:02