31 ASSERT_(useIndices.size() == 3);
34 allData(0, useIndices[0]), allData(1, useIndices[0]),
35 allData(2, useIndices[0]));
37 allData(0, useIndices[1]), allData(1, useIndices[1]),
38 allData(2, useIndices[1]));
40 allData(0, useIndices[2]), allData(1, useIndices[2]),
41 allData(2, useIndices[2]));
50 for (
size_t i = 0; i < 4; i++) M(0, i) = T(plane.
coefs[i]);
63 const T distanceThreshold,
unsigned int& out_bestModelIndex,
67 out_bestModelIndex = 0;
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);
78 const size_t N =
size(allData, 2);
79 out_inlierIndices.clear();
80 out_inlierIndices.reserve(100);
81 for (
size_t i = 0; i < N; i++)
85 allData.get_unsafe(0, i), allData.get_unsafe(1, i),
86 allData.get_unsafe(2, i)));
87 if (d < distanceThreshold) out_inlierIndices.push_back(i);
108 template <
typename NUMTYPE>
110 const Eigen::Matrix<NUMTYPE, Eigen::Dynamic, 1>&
x,
111 const Eigen::Matrix<NUMTYPE, Eigen::Dynamic, 1>&
y,
112 const Eigen::Matrix<NUMTYPE, Eigen::Dynamic, 1>&
z,
113 vector<pair<size_t, TPlane>>& out_detected_planes,
const double threshold,
114 const size_t min_inliers_for_valid_plane)
118 ASSERT_(
x.size() ==
y.size() &&
x.size() ==
z.size())
120 out_detected_planes.clear();
122 if (
x.empty())
return;
126 remainingPoints.insertRow(0,
x);
127 remainingPoints.insertRow(1,
y);
128 remainingPoints.insertRow(2,
z);
139 ransac.setVerbosityLevel(mrpt::utils::LVL_INFO);
141 remainingPoints, mrpt::math::ransac3Dplane_fit<NUMTYPE>,
142 mrpt::math::ransac3Dplane_distance<NUMTYPE>,
143 mrpt::math::ransac3Dplane_degenerate<NUMTYPE>, threshold,
145 this_best_inliers, this_best_model,
150 if (this_best_inliers.size() >= min_inliers_for_valid_plane)
153 out_detected_planes.push_back(
155 this_best_inliers.size(),
157 double(this_best_model(0, 0)),
158 double(this_best_model(0, 1)),
159 double(this_best_model(0, 2)),
160 double(this_best_model(0, 3)))));
162 out_detected_planes.rbegin()->second.unitarize();
166 remainingPoints.removeColumns(this_best_inliers);
178 #define EXPLICIT_INST_ransac_detect_3D_planes(_TYPE_) \ 179 template void mrpt::math::ransac_detect_3D_planes<_TYPE_>( \ 180 const Eigen::Matrix<_TYPE_, Eigen::Dynamic, 1>& x, \ 181 const Eigen::Matrix<_TYPE_, Eigen::Dynamic, 1>& y, \ 182 const Eigen::Matrix<_TYPE_, Eigen::Dynamic, 1>& z, \ 183 vector<pair<size_t, TPlane>>& out_detected_planes, \ 184 const double threshold, const size_t min_inliers_for_valid_plane); 188 #ifdef HAVE_LONG_DOUBLE 199 template <
typename T>
200 void ransac2Dline_fit(
205 ASSERT_(useIndices.size() == 2);
207 TPoint2D p1(allData(0, useIndices[0]), allData(1, useIndices[0]));
208 TPoint2D p2(allData(0, useIndices[1]), allData(1, useIndices[1]));
217 for (
size_t i = 0; i < 3; i++) M(0, i) = line.
coefs[i];
226 template <
typename T>
227 void ransac2Dline_distance(
230 const T distanceThreshold,
unsigned int& out_bestModelIndex,
233 out_inlierIndices.clear();
234 out_bestModelIndex = 0;
236 if (testModels.empty())
return;
239 testModels.size() == 1,
241 "Expected testModels.size()=1, but it's = %u",
242 static_cast<unsigned int>(testModels.size())))
248 line.
coefs[0] = M(0, 0);
249 line.coefs[1] = M(0, 1);
250 line.coefs[2] = M(0, 2);
252 const size_t N =
size(allData, 2);
253 out_inlierIndices.reserve(100);
254 for (
size_t i = 0; i < N; i++)
256 const double d = line.distance(
257 TPoint2D(allData.get_unsafe(0, i), allData.get_unsafe(1, i)));
258 if (d < distanceThreshold) out_inlierIndices.push_back(i);
264 template <
typename T>
265 bool ransac2Dline_degenerate(
279 template <
typename NUMTYPE>
281 const Eigen::Matrix<NUMTYPE, Eigen::Dynamic, 1>&
x,
282 const Eigen::Matrix<NUMTYPE, Eigen::Dynamic, 1>&
y,
283 std::vector<std::pair<size_t, TLine2D>>& out_detected_lines,
284 const double threshold,
const size_t min_inliers_for_valid_line)
290 out_detected_lines.clear();
292 if (
x.empty())
return;
296 remainingPoints.insertRow(0,
x);
297 remainingPoints.insertRow(1,
y);
302 while (
size(remainingPoints, 2) >= 2)
308 ransac.setVerbosityLevel(mrpt::utils::LVL_INFO);
310 remainingPoints, ransac2Dline_fit<NUMTYPE>,
311 ransac2Dline_distance<NUMTYPE>, ransac2Dline_degenerate<NUMTYPE>,
314 this_best_inliers, this_best_model,
319 if (this_best_inliers.size() >= min_inliers_for_valid_line)
322 out_detected_lines.push_back(
324 this_best_inliers.size(),
326 double(this_best_model(0, 0)),
327 double(this_best_model(0, 1)),
328 double(this_best_model(0, 2)))));
330 out_detected_lines.rbegin()->second.unitarize();
334 remainingPoints.removeColumns(this_best_inliers);
346 #define EXPLICIT_INSTANT_ransac_detect_2D_lines(_TYPE_) \ 347 template void mrpt::math::ransac_detect_2D_lines<_TYPE_>( \ 348 const Eigen::Matrix<_TYPE_, Eigen::Dynamic, 1>& x, \ 349 const Eigen::Matrix<_TYPE_, Eigen::Dynamic, 1>& y, \ 350 std::vector<std::pair<size_t, TLine2D>>& out_detected_lines, \ 351 const double threshold, const size_t min_inliers_for_valid_line); 355 #ifdef HAVE_LONG_DOUBLE void ransac_detect_3D_planes(const Eigen::Matrix< NUMTYPE, Eigen::Dynamic, 1 > &x, const Eigen::Matrix< NUMTYPE, Eigen::Dynamic, 1 > &y, const Eigen::Matrix< NUMTYPE, Eigen::Dynamic, 1 > &z, std::vector< std::pair< size_t, TPlane >> &out_detected_planes, const double threshold, const size_t min_inliers_for_valid_plane=10)
Fit a number of 3-D planes to a given point cloud, automatically determining the number of existing p...
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
void ransac_detect_2D_lines(const Eigen::Matrix< NUMTYPE, Eigen::Dynamic, 1 > &x, const Eigen::Matrix< NUMTYPE, Eigen::Dynamic, 1 > &y, std::vector< std::pair< size_t, TLine2D >> &out_detected_lines, const double threshold, const size_t min_inliers_for_valid_line=5)
Fit a number of 2-D lines to a given point cloud, automatically determining the number of existing li...
double distance(const TPoint3D &point) const
Distance to 3D point.
bool execute(const CMatrixTemplateNumeric< NUMTYPE > &data, const TRansacFitFunctor &fit_func, const TRansacDistanceFunctor &dist_func, const TRansacDegenerateFunctor °en_func, const double distanceThreshold, const unsigned int minimumSizeSamplesToFit, mrpt::vector_size_t &out_best_inliers, CMatrixTemplateNumeric< NUMTYPE > &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.
This base provides a set of functions for maths stuff.
bool ransac3Dplane_degenerate(const CMatrixDouble &planeCorresp, const mrpt::vector_size_t &useIndices)
Return "true" if the selected points are a degenerate (invalid) case.
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
void ransac3Dplane_fit(const CMatrixTemplateNumeric< T > &allData, const vector_size_t &useIndices, vector< CMatrixTemplateNumeric< T >> &fitModels)
#define EXPLICIT_INST_ransac_detect_3D_planes(_TYPE_)
3D Plane, represented by its equation
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
double coefs[3]
Line coefficients, stored as an array: .
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
double coefs[4]
Plane coefficients, stored as an array: .
A matrix of dynamic size.
std::vector< size_t > vector_size_t
void ransac3Dplane_distance(const CMatrixDouble &planeCorresp, const vector< CMatrixDouble > &testModels, const double distanceThreshold, unsigned int &out_bestModelIndex, mrpt::vector_size_t &out_inlierIndices)
#define EXPLICIT_INSTANT_ransac_detect_2D_lines(_TYPE_)
A generic RANSAC implementation with models as matrices.
#define ASSERTMSG_(f, __ERROR_MSG)
2D line without bounds, represented by its equation .
std::vector< size_t > vector_size_t