MRPT  2.0.4
test.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2020, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
11 #include <mrpt/math/ransac.h>
16 #include <mrpt/poses/CPose3D.h>
17 #include <mrpt/random.h>
18 #include <mrpt/system/CTicTac.h>
19 #include <iostream>
20 
21 using namespace mrpt;
22 using namespace mrpt::gui;
23 using namespace mrpt::math;
24 using namespace mrpt::random;
25 using namespace mrpt::poses;
26 using namespace mrpt::system;
27 using namespace std;
28 
30  const CMatrixDouble& allData, const std::vector<size_t>& useIndices,
31  vector<CMatrixDouble>& fitModels)
32 {
33  ASSERT_(useIndices.size() == 3);
34 
35  TPoint3D p1(
36  allData(0, useIndices[0]), allData(1, useIndices[0]),
37  allData(2, useIndices[0]));
38  TPoint3D p2(
39  allData(0, useIndices[1]), allData(1, useIndices[1]),
40  allData(2, useIndices[1]));
41  TPoint3D p3(
42  allData(0, useIndices[2]), allData(1, useIndices[2]),
43  allData(2, useIndices[2]));
44 
45  try
46  {
47  TPlane plane(p1, p2, p3);
48  fitModels.resize(1);
49  CMatrixDouble& M = fitModels[0];
50 
51  M.setSize(1, 4);
52  for (size_t i = 0; i < 4; i++) M(0, i) = plane.coefs[i];
53  }
54  catch (exception&)
55  {
56  fitModels.clear();
57  return;
58  }
59 }
60 
62  const CMatrixDouble& allData, const vector<CMatrixDouble>& testModels,
63  const double distanceThreshold, unsigned int& out_bestModelIndex,
64  std::vector<size_t>& out_inlierIndices)
65 {
66  ASSERT_(testModels.size() == 1);
67  out_bestModelIndex = 0;
68  const CMatrixDouble& M = testModels[0];
69 
70  ASSERT_(M.rows() == 1 && M.cols() == 4);
71 
72  TPlane plane;
73  plane.coefs[0] = M(0, 0);
74  plane.coefs[1] = M(0, 1);
75  plane.coefs[2] = M(0, 2);
76  plane.coefs[3] = M(0, 3);
77 
78  const size_t N = allData.cols();
79  out_inlierIndices.clear();
80  out_inlierIndices.reserve(100);
81  for (size_t i = 0; i < N; i++)
82  {
83  const double d = plane.distance(
84  TPoint3D(allData(0, i), allData(1, i), allData(2, i)));
85  if (d < distanceThreshold) out_inlierIndices.push_back(i);
86  }
87 }
88 
89 /** Return "true" if the selected points are a degenerate (invalid) case.
90  */
92  const CMatrixDouble& allData, const std::vector<size_t>& useIndices)
93 {
94  return false;
95 }
96 
97 // ------------------------------------------------------
98 // TestRANSAC
99 // ------------------------------------------------------
100 void TestRANSAC()
101 {
103 
104  // Generate random points:
105  // ------------------------------------
106  const size_t N_plane = 300;
107  const size_t N_noise = 100;
108 
109  const double PLANE_EQ[4] = {1, -1, 1, -2};
110 
111  CMatrixDouble data(3, N_plane + N_noise);
112  for (size_t i = 0; i < N_plane; i++)
113  {
114  const double xx = getRandomGenerator().drawUniform(-3, 3);
115  const double yy = getRandomGenerator().drawUniform(-3, 3);
116  const double zz =
117  -(PLANE_EQ[3] + PLANE_EQ[0] * xx + PLANE_EQ[1] * yy) / PLANE_EQ[2];
118  data(0, i) = xx;
119  data(1, i) = yy;
120  data(2, i) = zz;
121  }
122 
123  for (size_t i = 0; i < N_noise; i++)
124  {
125  data(0, i + N_plane) = getRandomGenerator().drawUniform(-4, 4);
126  data(1, i + N_plane) = getRandomGenerator().drawUniform(-4, 4);
127  data(2, i + N_plane) = getRandomGenerator().drawUniform(-4, 4);
128  }
129 
130  // Run RANSAC
131  // ------------------------------------
132  CMatrixDouble best_model;
133  std::vector<size_t> best_inliers;
134  const double DIST_THRESHOLD = 0.05;
135 
136  CTicTac tictac;
137  const size_t TIMES = 100;
138 
139  math::RANSAC myransac;
140  for (size_t iters = 0; iters < TIMES; iters++)
141  {
142  myransac.setVerbosityLevel(
144 
145  myransac.execute(
147  ransac3Dplane_degenerate, DIST_THRESHOLD,
148  3, // Minimum set of points
149  best_inliers, best_model);
150  }
151 
152  cout << "Computation time: " << tictac.Tac() * 1000.0 / TIMES << " ms"
153  << endl;
154 
155  ASSERT_(best_model.rows() == 1 && best_model.cols() == 4);
156 
157  cout << "RANSAC finished: Best model: " << best_model << endl;
158  // cout << "Best inliers: " << best_inliers << endl;
159 
160  TPlane plane(
161  best_model(0, 0), best_model(0, 1), best_model(0, 2), best_model(0, 3));
162 
163  // Show GUI
164  // --------------------------
165  mrpt::gui::CDisplayWindow3D win("Set of points", 500, 500);
167 
168  scene->insert(opengl::CGridPlaneXY::Create(-20, 20, -20, 20, 0, 1));
169  scene->insert(opengl::stock_objects::CornerXYZ());
170 
172  points->setColor(0, 0, 1);
173  points->setPointSize(3);
174  points->enableColorFromZ();
175 
176  {
177  std::vector<double> xs, ys, zs;
178 
179  data.extractRow(0, xs);
180  data.extractRow(1, ys);
181  data.extractRow(2, zs);
182  points->setAllPoints(xs, ys, zs);
183  }
184 
185  scene->insert(points);
186 
188  opengl::CTexturedPlane::Create(-4, 4, -4, 4);
189 
190  glPlane->setColor_u8(mrpt::img::TColor(0xff, 0x00, 0x00, 0x80)); // RGBA
191 
192  TPose3D glPlanePose;
193  plane.getAsPose3D(glPlanePose);
194  glPlane->setPose(glPlanePose);
195 
196  scene->insert(glPlane);
197 
198  win.get3DSceneAndLock() = scene;
199  win.unlockAccess3DScene();
200  win.forceRepaint();
201 
202  win.waitForKey();
203 }
204 
205 // ------------------------------------------------------
206 // MAIN
207 // ------------------------------------------------------
208 int main()
209 {
210  try
211  {
212  TestRANSAC();
213  return 0;
214  }
215  catch (const std::exception& e)
216  {
217  std::cerr << "MRPT error: " << mrpt::exception_to_str(e) << std::endl;
218  return -1;
219  }
220  catch (...)
221  {
222  printf("Untyped exception!!");
223  return -1;
224  }
225 }
A namespace of pseudo-random numbers generators of diferent distributions.
double Tac() noexcept
Stops the stopwatch.
Definition: CTicTac.cpp:87
static Ptr Create(Args &&... args)
bool ransac3Dplane_degenerate([[maybe_unused]] const CMatrixDynamic< T > &allData, [[maybe_unused]] const std::vector< size_t > &useIndices)
Return "true" if the selected points are a degenerate (invalid) case.
void randomize(const uint32_t seed)
Initialize the PRNG from the given random seed.
A high-performance stopwatch, with typical resolution of nanoseconds.
STL namespace.
static Ptr Create(Args &&... args)
Definition: CPointCloud.h:49
void ransac3Dplane_fit(const CMatrixDynamic< T > &allData, const std::vector< size_t > &useIndices, vector< CMatrixDynamic< T >> &fitModels)
#define ASSERT_(f)
Defines an assertion mechanism.
Definition: exceptions.h:120
return_t drawUniform(const double Min, const double Max)
Generate a uniformly distributed pseudo-random number using the MT19937 algorithm, scaled to the selected range.
This base provides a set of functions for maths stuff.
void TestRANSAC()
3D Plane, represented by its equation
Definition: TPlane.h:22
TPoint3D_< double > TPoint3D
Lightweight 3D point.
Definition: TPoint3D.h:268
mrpt::gui::CDisplayWindow3D::Ptr win
size_type rows() const
Number of rows in the matrix.
size_type cols() const
Number of columns in the matrix.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
void setVerbosityLevel(const VerbosityLevel level)
alias of setMinLoggingLevel()
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
CSetOfObjects::Ptr CornerXYZ(float scale=1.0)
Returns three arrows representing a X,Y,Z 3D corner.
void setSize(size_t row, size_t col, bool zeroNewElements=false)
Changes the size of matrix, maintaining the previous contents.
Lightweight 3D pose (three spatial coordinates, plus three angular coordinates).
Definition: TPose3D.h:24
std::string exception_to_str(const std::exception &e)
Builds a nice textual representation of a nested exception, which if generated using MRPT macros (THR...
Definition: exceptions.cpp:59
bool execute(const DATASET &data, const TRansacFitFunctor &fit_func, const TRansacDistanceFunctor &dist_func, const TRansacDegenerateFunctor &degen_func, const double distanceThreshold, const unsigned int minimumSizeSamplesToFit, std::vector< size_t > &out_best_inliers, MODEL &out_best_model, const double prob_good_sample=0.999, const size_t maxIter=2000) const
An implementation of the RANSAC algorithm for robust fitting of models to data.
Definition: ransac_impl.h:21
void ransac3Dplane_distance(const CMatrixDynamic< T > &allData, const vector< CMatrixDynamic< T >> &testModels, const T distanceThreshold, unsigned int &out_bestModelIndex, std::vector< size_t > &out_inlierIndices)
static Ptr Create(Args &&... args)
Definition: COpenGLScene.h:58
Classes for creating GUI windows for 2D and 3D visualization.
Definition: about_box.h:14
A RGB color - 8bit.
Definition: TColor.h:25
A generic RANSAC implementation.
Definition: ransac.h:47
CRandomGenerator & getRandomGenerator()
A static instance of a CRandomGenerator class, for use in single-thread applications.
std::array< double, 4 > coefs
Plane coefficients, stored as an array: .
Definition: TPlane.h:26
static Ptr Create(Args &&... args)
Definition: CGridPlaneXY.h:31
A graphical user interface (GUI) for efficiently rendering 3D scenes in real-time.
static struct FontData data
Definition: gltext.cpp:144



Page generated by Doxygen 1.8.14 for MRPT 2.0.4 Git: 33de1d0ad Sat Jun 20 11:02:42 2020 +0200 at sáb jun 20 17:35:17 CEST 2020