FilterByRing.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 
19 
20 using namespace mp2p_icp_filters;
21 
22 void FilterByRing::Parameters::load_from_yaml(const mrpt::containers::yaml& c)
23 {
24  MCP_LOAD_REQ(c, input_pointcloud_layer);
25 
26  MCP_LOAD_OPT(c, output_layer_selected);
27  MCP_LOAD_OPT(c, output_layer_non_selected);
28 
29  selected_ring_ids.clear();
30 
31  auto cfgIn = c["selected_ring_ids"];
32  if (cfgIn.isScalar())
33  {
34  // only one:
35  selected_ring_ids.insert(cfgIn.as<int>());
36  }
37  else
38  {
39  ASSERTMSG_(
40  cfgIn.isSequence(),
41  "YAML configuration must have an entry `selected_ring_ids` "
42  "with a scalar or sequence.");
43 
44  for (const auto& n : cfgIn.asSequenceRange())
45  selected_ring_ids.insert(n.as<int>());
46  }
47  ASSERT_(!selected_ring_ids.empty());
48 }
49 
50 FilterByRing::FilterByRing() = default;
51 
52 void FilterByRing::initialize(const mrpt::containers::yaml& c)
53 {
54  MRPT_LOG_DEBUG_STREAM("Loading these params:\n" << c);
56 }
57 
59 {
60  MRPT_START
61 
62  // In:
63  const auto& pcPtr = inOut.point_layer(params_.input_pointcloud_layer);
64  ASSERTMSG_(
65  pcPtr, mrpt::format(
66  "Input point cloud layer '%s' was not found.",
68 
69  const auto& pc = *pcPtr;
70 
71  // Outputs:
72  // Create if new: Append to existing layer, if already existed.
73  mrpt::maps::CPointsMap::Ptr outSelected = GetOrCreatePointLayer(
74  inOut, params_.output_layer_selected, true /*allow empty for nullptr*/,
75  /* create cloud of the same type */
76  pcPtr->GetRuntimeClass()->className);
77 
78  if (outSelected) outSelected->reserve(outSelected->size() + pc.size() / 10);
79 
80  // Create if new: Append to existing layer, if already existed.
81  mrpt::maps::CPointsMap::Ptr outNonSel = GetOrCreatePointLayer(
83  true /*allow empty for nullptr*/,
84  /* create cloud of the same type */
85  pcPtr->GetRuntimeClass()->className);
86 
87  if (outNonSel) outNonSel->reserve(outNonSel->size() + pc.size() / 10);
88 
89  ASSERTMSG_(
90  outSelected || outNonSel,
91  "At least one of 'output_layer_selected' or "
92  "'output_layer_non_selected' must be provided.");
93 
94  const auto& xs = pc.getPointsBufferRef_x();
95  // const auto& ys = pc.getPointsBufferRef_y();
96  // const auto& zs = pc.getPointsBufferRef_z();
97  const auto* ptrR = pc.getPointsBufferRef_ring();
98  if (!ptrR || ptrR->empty())
99  {
100  THROW_EXCEPTION_FMT(
101  "Error: this filter needs the input layer '%s' to has an "
102  "'ring' point channel.",
104  }
105 
106  const auto& Rs = *ptrR;
107  ASSERT_EQUAL_(Rs.size(), xs.size());
108  const size_t N = xs.size();
109 
110  size_t countSel = 0, countNon = 0;
111 
112  for (size_t i = 0; i < N; i++)
113  {
114  const auto R = Rs[i];
115 
116  mrpt::maps::CPointsMap* trg = nullptr;
117 
118  if (params_.selected_ring_ids.count(R) != 0)
119  {
120  trg = outSelected.get();
121  ++countSel;
122  }
123  else
124  {
125  trg = outNonSel.get();
126  ++countNon;
127  }
128 
129  if (trg) trg->insertPointFrom(pc, i);
130  }
131 
132  MRPT_LOG_DEBUG_STREAM(
133  "[FilterByRing] Input points=" << N << " selected=" << countSel
134  << " non-selected=" << countNon);
135 
136  MRPT_END
137 }
mp2p_icp_filters::FilterByRing::params_
Parameters params_
Definition: FilterByRing.h:56
mp2p_icp_filters::FilterByRing::Parameters::selected_ring_ids
std::set< int > selected_ring_ids
Definition: FilterByRing.h:52
mp2p_icp_filters::FilterByRing::FilterByRing
FilterByRing()
mp2p_icp_filters::FilterByRing::filter
void filter(mp2p_icp::metric_map_t &inOut) const override
Definition: FilterByRing.cpp:58
mp2p_icp_filters::FilterByRing::Parameters::input_pointcloud_layer
std::string input_pointcloud_layer
Definition: FilterByRing.h:42
mp2p_icp_filters::FilterByRing::initialize
void initialize(const mrpt::containers::yaml &c) override
Definition: FilterByRing.cpp:52
FilterByRing.h
Keeps only a given subset of an input cloud by LiDAR "ring_id".
mp2p_icp_filters::FilterBase
Definition: FilterBase.h:46
mp2p_icp::metric_map_t::point_layer
mrpt::maps::CPointsMap::Ptr point_layer(const layer_name_t &name) const
Definition: metricmap.cpp:629
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
IMPLEMENTS_MRPT_OBJECT
IMPLEMENTS_MRPT_OBJECT(FilterByRing, mp2p_icp_filters::FilterBase, mp2p_icp_filters) using namespace mp2p_icp_filters
mp2p_icp_filters::FilterByRing::Parameters::load_from_yaml
void load_from_yaml(const mrpt::containers::yaml &c)
Definition: FilterByRing.cpp:22
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
Definition: FilterAdjustTimestamps.h:19
mp2p_icp_filters::FilterByRing::Parameters::output_layer_selected
std::string output_layer_selected
Definition: FilterByRing.h:46
mp2p_icp_filters::FilterByRing::Parameters::output_layer_non_selected
std::string output_layer_non_selected
Definition: FilterByRing.h:50


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