QualityEvaluator_RangeImageSimilarity.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/gui/CDisplayWindow.h>
15 #include <mrpt/img/TPixelCoord.h>
16 #include <mrpt/io/vector_loadsave.h>
17 
19  QualityEvaluator_RangeImageSimilarity, QualityEvaluator, mp2p_icp)
20 
21 using namespace mp2p_icp;
22 
24  const mrpt::containers::yaml& params)
25 {
26  rangeCamera.ncols = params["ncols"].as<uint32_t>();
27  rangeCamera.nrows = params["nrows"].as<uint32_t>();
28 
29  rangeCamera.cx(params["cx"].as<double>());
30  rangeCamera.cy(params["cy"].as<double>());
31  rangeCamera.fx(params["fx"].as<double>());
32  rangeCamera.fy(params["fy"].as<double>());
33 
34  MCP_LOAD_OPT(params, sigma);
35  MCP_LOAD_OPT(params, penalty_not_visible);
36 
37  MCP_LOAD_OPT(params, debug_show_all_in_window);
38  MCP_LOAD_OPT(params, debug_save_all_matrices);
39 }
40 
42  const metric_map_t& pcGlobal, const metric_map_t& pcLocal,
43  const mrpt::poses::CPose3D& localPose,
44  [[maybe_unused]] const Pairings& pairingsFromICP) const
45 {
46  // See Figure 3 of IROS2017 paper:
47  // "Analyzing the Quality of Matched 3D Point Clouds of Objects"
48  // Igor Bogoslavskyi, Cyrill Stachniss
49 
50  const auto& p1 = *pcGlobal.point_layer(metric_map_t::PT_LAYER_RAW);
51  const auto& p2 = *pcLocal.point_layer(metric_map_t::PT_LAYER_RAW);
52 
53  const auto I11 = projectPoints(p1);
54  const auto I12 = projectPoints(p1, localPose);
55  const auto I22 = projectPoints(p2);
56  const auto I21 = projectPoints(p2, -localPose);
57 
58  auto s1 = scores(I11, I21);
59  auto s2 = scores(I12, I22);
60 
61  const size_t nScores = s1.size() + s2.size();
62 
63  double sum = .0;
64  for (double v : s1) sum += v;
65  for (double v : s2) sum += v;
66 
67  const double finalScore = nScores > 0 ? sum / nScores : .0;
68 
69  // ----- Debug ----------
71  {
72  mrpt::gui::CDisplayWindow win_11("I11", 400, 300);
73  mrpt::gui::CDisplayWindow win_12("I12", 400, 300);
74  mrpt::gui::CDisplayWindow win_21("I21", 400, 300);
75  mrpt::gui::CDisplayWindow win_22("I22", 400, 300);
76  win_11.setPos(5, 5);
77  win_12.setPos(410 + 5, 5);
78  win_21.setPos(5, 310 + 5);
79  win_22.setPos(410 + 5, 310 + 5);
80  mrpt::img::CImage im11, im12, im21, im22;
81  im11.setFromMatrix(I11, false);
82  win_11.showImage(im11);
83  im12.setFromMatrix(I12, false);
84  win_12.showImage(im12);
85  im21.setFromMatrix(I21, false);
86  win_21.showImage(im21);
87  im22.setFromMatrix(I22, false);
88  win_22.showImage(im22);
89  win_11.waitForKey();
90  }
92  {
93  static std::atomic_int iv = 0;
94  const int i = iv++;
95  I11.saveToTextFile(mrpt::format("I11_%05i.txt", i));
96  I22.saveToTextFile(mrpt::format("I22_%05i.txt", i));
97  I12.saveToTextFile(mrpt::format("I12_%05i.txt", i));
98  I21.saveToTextFile(mrpt::format("I21_%05i.txt", i));
99 
100  mrpt::io::vectorToTextFile(s1, mrpt::format("I1_scores_%05i.txt", i));
101  mrpt::io::vectorToTextFile(s2, mrpt::format("I2_scores_%05i.txt", i));
102  }
103 
104  return finalScore;
105 }
106 
107 // Adapted from mrpt::vision::pinhole::projectPoint_with_distortion()
108 // 3-claused BSD
109 static void projectPoint(
110  const mrpt::math::TPoint3D& P, const mrpt::img::TCamera& params,
111  double& pixel_x, double& pixel_y)
112 {
113  /* Pinhole model.
114  *
115  * Point reference Pixel/camera reference
116  *
117  * +Z ^ / +Z
118  * | / /
119  * | / +X /
120  * +Y |/ /
121  * <-----+ +-----------> +X
122  * |
123  * |
124  * V +Y
125  *
126  */
127  const double x = -P.y / P.x;
128  const double y = -P.z / P.x;
129 
130  pixel_x = params.cx() + params.fx() * x;
131  pixel_y = params.cy() + params.fy() * y;
132 }
133 
135  const mrpt::maps::CPointsMap& pts,
136  const std::optional<mrpt::poses::CPose3D>& relativePose) const
137 {
138  const auto& rc = rangeCamera;
139 
140  mrpt::math::CMatrixDouble I(rc.nrows, rc.ncols);
141  I.setZero(); // range=0 means "invalid"
142 
143  const auto& xs = pts.getPointsBufferRef_x();
144  const auto& ys = pts.getPointsBufferRef_y();
145  const auto& zs = pts.getPointsBufferRef_z();
146 
147  const auto nPoints = xs.size();
148  size_t nValidPoints = 0;
149  for (size_t i = 0; i < nPoints; i++)
150  {
151  mrpt::math::TPoint3D p(xs[i], ys[i], zs[i]);
152  if (relativePose) p = relativePose->composePoint(p);
153 
154  double px, py;
155  projectPoint(p, rc, px, py);
156  int pixx = static_cast<int>(px);
157  int pixy = static_cast<int>(py);
158 
159  // Out of range
160  if (pixx < 0 || pixy < 0 || pixx >= int(rc.ncols) ||
161  pixy >= int(rc.nrows))
162  continue;
163 
164  const double newRange = p.norm();
165  double& storedRange = I(pixy, pixx);
166 
167  if (storedRange == 0 || newRange < storedRange) storedRange = newRange;
168 
169  nValidPoints++;
170  }
171 
172  // std::cout << "Points: " << nValidPoints << "/" << nPoints << "\n";
173 
174  return I;
175 }
176 
177 static double phi(double x) { return std::erf(x / std::sqrt(2)); }
178 static double errorForMismatch(const double x) { return 1.0 - phi(x); }
179 static double errorForMismatch(const double DeltaRange, const double sigma)
180 {
181  const double x = std::abs(DeltaRange / sigma);
182  return errorForMismatch(x);
183 }
184 
186  const mrpt::math::CMatrixDouble& m1,
187  const mrpt::math::CMatrixDouble& m2) const
188 {
189  ASSERT_EQUAL_(m1.rows(), m2.rows());
190  ASSERT_EQUAL_(m1.cols(), m2.cols());
191 
192  std::vector<double> scores;
193  scores.reserve(m1.rows() * m1.cols() / 4);
194 
195  const size_t N = m1.rows() * m1.cols();
196  for (size_t i = 0; i < N; i++)
197  {
198  const double r1 = m1.data()[i];
199  const double r2 = m2.data()[i];
200 
201  if (r1 == 0 && r2 == 0) continue;
202 
203  double val;
204  if (r1 == 0 || r2 == 0)
205  {
206  // Maximum error:
208  }
209  else
210  {
211  // Maximum error:
212  val = errorForMismatch(r1 - r2, sigma);
213  }
214  // printf("r1=%f r2=%f -> val=%f\n", r1, r2, val);
215  scores.push_back(val);
216  }
217 
218  return scores;
219 }
mp2p_icp
Definition: covariance.h:17
mp2p_icp::QualityEvaluator_RangeImageSimilarity::initialize
void initialize(const mrpt::containers::yaml &params) override
Definition: QualityEvaluator_RangeImageSimilarity.cpp:23
mp2p_icp::Pairings
Definition: Pairings.h:94
test.x
x
Definition: test.py:4
mp2p_icp::QualityEvaluator_RangeImageSimilarity::sigma
double sigma
Definition: QualityEvaluator_RangeImageSimilarity.h:66
mp2p_icp::metric_map_t::PT_LAYER_RAW
constexpr static const char * PT_LAYER_RAW
Definition: metricmap.h:56
mp2p_icp::QualityEvaluator_RangeImageSimilarity::projectPoints
mrpt::math::CMatrixDouble projectPoints(const mrpt::maps::CPointsMap &pts, const std::optional< mrpt::poses::CPose3D > &relativePose=std::nullopt) const
Definition: QualityEvaluator_RangeImageSimilarity.cpp:134
mp2p_icp::QualityEvaluator_RangeImageSimilarity::debug_show_all_in_window
bool debug_show_all_in_window
Definition: QualityEvaluator_RangeImageSimilarity.h:71
mp2p_icp::QualityEvaluator_RangeImageSimilarity::evaluate
double evaluate(const metric_map_t &pcGlobal, const metric_map_t &pcLocal, const mrpt::poses::CPose3D &localPose, const Pairings &pairingsFromICP) const override
Definition: QualityEvaluator_RangeImageSimilarity.cpp:41
mp2p_icp::QualityEvaluator_RangeImageSimilarity::rangeCamera
mrpt::img::TCamera rangeCamera
Definition: QualityEvaluator_RangeImageSimilarity.h:64
phi
static double phi(double x)
Definition: QualityEvaluator_RangeImageSimilarity.cpp:177
mp2p_icp::QualityEvaluator_RangeImageSimilarity::debug_save_all_matrices
bool debug_save_all_matrices
Definition: QualityEvaluator_RangeImageSimilarity.h:72
projectPoint
static void projectPoint(const mrpt::math::TPoint3D &P, const mrpt::img::TCamera &params, double &pixel_x, double &pixel_y)
Definition: QualityEvaluator_RangeImageSimilarity.cpp:109
mp2p_icp::metric_map_t::point_layer
mrpt::maps::CPointsMap::Ptr point_layer(const layer_name_t &name) const
Definition: metricmap.cpp:483
errorForMismatch
static double errorForMismatch(const double x)
Definition: QualityEvaluator_RangeImageSimilarity.cpp:178
IMPLEMENTS_MRPT_OBJECT
IMPLEMENTS_MRPT_OBJECT(QualityEvaluator_RangeImageSimilarity, QualityEvaluator, mp2p_icp) using namespace mp2p_icp
PointMatcherSupport::Parametrizable
The superclass of classes that are constructed using generic parameters. This class provides the para...
Definition: Parametrizable.h:98
mp2p_icp::QualityEvaluator_RangeImageSimilarity::penalty_not_visible
double penalty_not_visible
!< Uncertainty of depth ranges [meters]
Definition: QualityEvaluator_RangeImageSimilarity.h:69
mp2p_icp::metric_map_t
Generic container of pointcloud(s), extracted features and other maps.
Definition: metricmap.h:47
mp2p_icp::QualityEvaluator_RangeImageSimilarity::scores
std::vector< double > scores(const mrpt::math::CMatrixDouble &m1, const mrpt::math::CMatrixDouble &m2) const
Definition: QualityEvaluator_RangeImageSimilarity.cpp:185
QualityEvaluator_RangeImageSimilarity.h
Matching quality evaluator from paper [Bogoslavskyi,IROS2017].


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