GeneratorEdgesFromCurvature.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/containers/yaml.h>
15 #include <mrpt/maps/CSimplePointsMap.h>
16 #include <mrpt/math/utils.h> // absDiff()
17 #include <mrpt/obs/CObservationRotatingScan.h>
18 #include <mrpt/version.h>
19 
20 #include <utility> // std::pair
21 
23 
24 using namespace mp2p_icp_filters;
25 
27  const mrpt::containers::yaml& c, GeneratorEdgesFromCurvature& parent)
28 {
31 }
32 
33 void GeneratorEdgesFromCurvature::initialize(const mrpt::containers::yaml& c)
34 {
35  // parent base method:
37 
38  paramsEdges_.load_from_yaml(c, *this);
39 }
40 
42  const mrpt::obs::CObservation& o, mp2p_icp::metric_map_t& out,
43  const std::optional<mrpt::poses::CPose3D>& robotPose) const
44 {
45  MRPT_START
46  using namespace mrpt::obs;
47 
48  ASSERTMSG_(
50  "initialize() must be called once before using process().");
51 
53 
54  const auto obsClassName = o.GetRuntimeClass()->className;
55 
56  // default: use point clouds:
57  ASSERT_(params_.metric_map_definition_ini_file.empty());
58 
59  bool processed = false;
60 
61  // user-given filters: Done *AFTER* creating the map, if needed.
62  if (!std::regex_match(obsClassName, process_class_names_regex_))
63  return false;
64  if (!std::regex_match(o.sensorLabel, process_sensor_labels_regex_))
65  return false;
66 
67  if (auto oRS = dynamic_cast<const CObservationRotatingScan*>(&o); oRS)
68  processed = filterRotatingScan(*oRS, out, robotPose);
69 
70  // done?
71  if (processed) return true; // we are done.
72 
73  // Create if new: Append to existing layer, if already existed.
74  mrpt::maps::CPointsMap::Ptr outPc;
75  if (auto itLy = out.layers.find(params_.target_layer);
76  itLy != out.layers.end())
77  {
78  outPc = std::dynamic_pointer_cast<mrpt::maps::CPointsMap>(itLy->second);
79  if (!outPc)
80  THROW_EXCEPTION_FMT(
81  "Layer '%s' must be of point cloud type.",
82  params_.target_layer.c_str());
83  }
84  else
85  {
86  outPc = mrpt::maps::CSimplePointsMap::Create();
87  out.layers[params_.target_layer] = outPc;
88  }
89 
90  if (!outPc) outPc = mrpt::maps::CSimplePointsMap::Create();
91 
92  // Leave output point cloud empty, since it was not handled by the
93  // rotating scan handler above.
94 
95  return false;
96 
97  MRPT_END
98 }
99 
101  const mrpt::obs::CObservationRotatingScan& pc, mp2p_icp::metric_map_t& out,
102  const std::optional<mrpt::poses::CPose3D>& robotPose) const
103 {
104 #if MRPT_VERSION >= 0x020b04
105  auto outPc = mrpt::maps::CSimplePointsMap::Create();
106 
107  ASSERT_(!pc.organizedPoints.empty());
108 
109  const auto nRows = pc.rowCount;
110  const auto nCols = pc.columnCount;
111 
112  ASSERT_EQUAL_(nRows, pc.organizedPoints.rows());
113  ASSERT_EQUAL_(nCols, pc.organizedPoints.cols());
114 
115  ASSERT_EQUAL_(nRows, pc.rangeImage.rows());
116  ASSERT_EQUAL_(nCols, pc.rangeImage.cols());
117 
118  // for each row:
119  for (size_t r = 0; r < nRows; r++)
120  {
121  // compute range diff:
122  for (size_t i = 1; i + 1 < nCols; i++)
123  {
124  // we need at least 3 consecutive valid points:
125  if (!pc.rangeImage(r, i - 1) || !pc.rangeImage(r, i) ||
126  !pc.rangeImage(r, i + 1))
127  continue;
128 
129  const auto& pt_im1 = pc.organizedPoints(r, i - 1);
130  const auto& pt_i = pc.organizedPoints(r, i);
131  const auto& pt_ip1 = pc.organizedPoints(r, i + 1);
132 
133  const auto v1 = (pt_i - pt_im1);
134  const auto v2 = (pt_ip1 - pt_i);
135  const auto v1n = v1.norm();
136  const auto v2n = v2.norm();
137 
138  if (v1n < paramsEdges_.min_point_clearance ||
140  continue;
141 
142  const float score = v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
143 
144  if (std::abs(score) < paramsEdges_.max_cosine * v1n * v2n)
145  {
146  // this point passes:
147  if (robotPose)
148  outPc->insertPoint(
149  robotPose->composePoint(pc.organizedPoints(r, i)));
150  else
151  outPc->insertPoint(pc.organizedPoints(r, i));
152  // TODO(jlbc) Output intensity?
153  }
154  }
155 
156  } // end for each row
157 
158  out.layers[params_.target_layer] = outPc;
159  return true; // Yes, it's implemented
160 #else
161  THROW_EXCEPTION("This class requires MRPT >=v2.11.4");
162 #endif
163 }
mp2p_icp_filters::GeneratorEdgesFromCurvature::filterRotatingScan
bool filterRotatingScan(const mrpt::obs::CObservationRotatingScan &pc, mp2p_icp::metric_map_t &out, const std::optional< mrpt::poses::CPose3D > &robotPose=std::nullopt) const override
Definition: GeneratorEdgesFromCurvature.cpp:100
mp2p_icp_filters::Generator::Parameters::metric_map_definition_ini_file
std::string metric_map_definition_ini_file
Definition: Generator.h:124
mp2p_icp::Parameterizable::checkAllParametersAreRealized
void checkAllParametersAreRealized() const
Definition: Parameterizable.cpp:138
mp2p_icp_filters::GeneratorEdgesFromCurvature::process
bool process(const mrpt::obs::CObservation &input_raw, mp2p_icp::metric_map_t &inOut, const std::optional< mrpt::poses::CPose3D > &robotPose=std::nullopt) const override
Definition: GeneratorEdgesFromCurvature.cpp:41
mp2p_icp_filters::Generator::initialize
virtual void initialize(const mrpt::containers::yaml &cfg_block)
Definition: Generator.cpp:123
mp2p_icp_filters::Generator
Definition: Generator.h:71
mp2p_icp_filters::GeneratorEdgesFromCurvature::paramsEdges_
ParametersEdges paramsEdges_
Definition: GeneratorEdgesFromCurvature.h:48
mp2p_icp_filters::Generator::initialized_
bool initialized_
Definition: Generator.h:179
mp2p_icp_filters::GeneratorEdgesFromCurvature::ParametersEdges::max_cosine
float max_cosine
Definition: GeneratorEdgesFromCurvature.h:44
mp2p_icp_filters::GeneratorEdgesFromCurvature
Definition: GeneratorEdgesFromCurvature.h:25
mp2p_icp_filters::Generator::process_class_names_regex_
std::regex process_class_names_regex_
Definition: Generator.h:180
mp2p_icp_filters::Generator::params_
Parameters params_
Definition: Generator.h:147
kitti-batch-convert.out
string out
Definition: kitti-batch-convert.py:7
DECLARE_PARAMETER_IN_REQ
#define DECLARE_PARAMETER_IN_REQ(__yaml, __variable, __object)
Definition: Parameterizable.h:167
mp2p_icp_filters::Generator::Parameters::target_layer
std::string target_layer
Definition: Generator.h:105
IMPLEMENTS_MRPT_OBJECT
IMPLEMENTS_MRPT_OBJECT(QualityEvaluator_RangeImageSimilarity, QualityEvaluator, mp2p_icp) using namespace mp2p_icp
mp2p_icp_filters::GeneratorEdgesFromCurvature::ParametersEdges::load_from_yaml
void load_from_yaml(const mrpt::containers::yaml &c, GeneratorEdgesFromCurvature &parent)
Definition: GeneratorEdgesFromCurvature.cpp:26
mp2p_icp_filters::GeneratorEdgesFromCurvature::initialize
void initialize(const mrpt::containers::yaml &cfg_block) override
Definition: GeneratorEdgesFromCurvature.cpp:33
GeneratorEdgesFromCurvature.h
Generator of edge points from organized point clouds.
mp2p_icp_filters::GeneratorEdgesFromCurvature::ParametersEdges::min_point_clearance
float min_point_clearance
Definition: GeneratorEdgesFromCurvature.h:45
mp2p_icp::metric_map_t
Generic container of pointcloud(s), extracted features and other maps.
Definition: metricmap.h:49
mp2p_icp_filters::Generator::process_sensor_labels_regex_
std::regex process_sensor_labels_regex_
Definition: Generator.h:181
DECLARE_PARAMETER_IN_OPT
#define DECLARE_PARAMETER_IN_OPT(__yaml, __variable, __object)
Definition: Parameterizable.h:159
mp2p_icp_filters
Definition: FilterAdjustTimestamps.h:19


mp2p_icp
Author(s):
autogenerated on Wed Oct 2 2024 02:45:23