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 unsigned int& out_bestModelIndex, std::vector<size_t>& out_inlierIndices)
65 ASSERT_(testModels.size() == 1);
66 out_bestModelIndex = 0;
72 plane.
coefs[0] = M(0, 0);
73 plane.coefs[1] = M(0, 1);
74 plane.coefs[2] = M(0, 2);
75 plane.coefs[3] = M(0, 3);
77 const size_t N = allData.
cols();
78 out_inlierIndices.clear();
79 out_inlierIndices.reserve(100);
80 for (
size_t i = 0; i < N; i++)
82 const double d = plane.distance(
83 TPoint3D(allData(0, i), allData(1, i), allData(2, i)));
84 if (d < distanceThreshold) out_inlierIndices.push_back(i);
104 template <
typename NUMTYPE>
108 vector<pair<size_t, TPlane>>& out_detected_planes,
const double threshold,
109 const size_t min_inliers_for_valid_plane)
113 ASSERT_(
x.size() ==
y.size() &&
x.size() ==
z.size());
115 out_detected_planes.clear();
117 if (
x.empty())
return;
122 remainingPoints.setRow(1,
y);
123 remainingPoints.setRow(2,
z);
130 std::vector<size_t> this_best_inliers;
136 remainingPoints, mrpt::math::ransac3Dplane_fit<NUMTYPE>,
137 mrpt::math::ransac3Dplane_distance<NUMTYPE>,
138 mrpt::math::ransac3Dplane_degenerate<NUMTYPE>, threshold,
140 this_best_inliers, this_best_model,
145 if (this_best_inliers.size() >= min_inliers_for_valid_plane)
148 out_detected_planes.emplace_back(
149 this_best_inliers.size(),
TPlane(
150 double(this_best_model(0, 0)),
151 double(this_best_model(0, 1)),
152 double(this_best_model(0, 2)),
153 double(this_best_model(0, 3))));
155 out_detected_planes.rbegin()->second.unitarize();
159 remainingPoints.removeColumns(this_best_inliers);
171 #define EXPLICIT_INST_ransac_detect_3D_planes(_TYPE_) \ 172 template void mrpt::math::ransac_detect_3D_planes<_TYPE_>( \ 173 const CVectorDynamic<_TYPE_>& x, const CVectorDynamic<_TYPE_>& y, \ 174 const CVectorDynamic<_TYPE_>& z, \ 175 vector<pair<size_t, TPlane>>& out_detected_planes, \ 176 const double threshold, const size_t min_inliers_for_valid_plane) 188 template <
typename T>
193 ASSERT_(useIndices.size() == 2);
195 TPoint2D p1(allData(0, useIndices[0]), allData(1, useIndices[0]));
196 TPoint2D p2(allData(0, useIndices[1]), allData(1, useIndices[1]));
205 for (
size_t i = 0; i < 3; i++) M(0, i) = line.
coefs[i];
214 template <
typename T>
218 unsigned int& out_bestModelIndex, std::vector<size_t>& out_inlierIndices)
220 out_inlierIndices.clear();
221 out_bestModelIndex = 0;
223 if (testModels.empty())
return;
226 testModels.size() == 1,
228 "Expected testModels.size()=1, but it's = %u",
229 static_cast<unsigned int>(testModels.size())));
232 ASSERT_(M.rows() == 1 && M.cols() == 3);
235 line.
coefs[0] = M(0, 0);
236 line.coefs[1] = M(0, 1);
237 line.coefs[2] = M(0, 2);
239 const size_t N = allData.
cols();
240 out_inlierIndices.reserve(100);
241 for (
size_t i = 0; i < N; i++)
243 const double d = line.distance(
TPoint2D(allData(0, i), allData(1, i)));
244 if (d < distanceThreshold) out_inlierIndices.push_back(i);
250 template <
typename T>
264 template <
typename NUMTYPE>
267 std::vector<std::pair<size_t, TLine2D>>& out_detected_lines,
268 const double threshold,
const size_t min_inliers_for_valid_line)
272 out_detected_lines.clear();
274 if (
x.empty())
return;
279 remainingPoints.setRow(1,
y);
284 while (remainingPoints.cols() >= 2)
286 std::vector<size_t> this_best_inliers;
292 remainingPoints, ransac2Dline_fit<NUMTYPE>,
293 ransac2Dline_distance<NUMTYPE>, ransac2Dline_degenerate<NUMTYPE>,
296 this_best_inliers, this_best_model,
301 if (this_best_inliers.size() >= min_inliers_for_valid_line)
304 out_detected_lines.emplace_back(
305 this_best_inliers.size(),
TLine2D(
306 double(this_best_model(0, 0)),
307 double(this_best_model(0, 1)),
308 double(this_best_model(0, 2))));
310 out_detected_lines.rbegin()->second.unitarize();
314 remainingPoints.removeColumns(this_best_inliers);
326 #define EXPLICIT_INSTANT_ransac_detect_2D_lines(_TYPE_) \ 327 template void mrpt::math::ransac_detect_2D_lines<_TYPE_>( \ 328 const CVectorDynamic<_TYPE_>& x, const CVectorDynamic<_TYPE_>& y, \ 329 std::vector<std::pair<size_t, TLine2D>>& out_detected_lines, \ 330 const double threshold, const size_t min_inliers_for_valid_line)
Template for column vectors of dynamic size, compatible with Eigen.
void ransac2Dline_distance(const CMatrixDynamic< T > &allData, const vector< CMatrixDynamic< T >> &testModels, const T distanceThreshold, unsigned int &out_bestModelIndex, std::vector< size_t > &out_inlierIndices)
void setRow(const Index row, const VECTOR &v)
void ransac3Dplane_fit(const CMatrixDynamic< T > &allData, const std::vector< size_t > &useIndices, vector< CMatrixDynamic< T >> &fitModels)
#define ASSERT_(f)
Defines an assertion mechanism.
void ransac_detect_3D_planes(const CVectorDynamic< NUMTYPE > &x, const CVectorDynamic< NUMTYPE > &y, const CVectorDynamic< NUMTYPE > &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...
This base provides a set of functions for maths stuff.
void ransac2Dline_fit(const CMatrixDynamic< T > &allData, const std::vector< size_t > &useIndices, vector< CMatrixDynamic< T >> &fitModels)
#define EXPLICIT_INST_ransac_detect_3D_planes(_TYPE_)
3D Plane, represented by its equation
#define ASSERTMSG_(f, __ERROR_MSG)
Defines an assertion mechanism.
size_type rows() const
Number of rows in the matrix.
size_type cols() const
Number of columns in the matrix.
void ransac_detect_2D_lines(const CVectorDynamic< NUMTYPE > &x, const CVectorDynamic< NUMTYPE > &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...
void setVerbosityLevel(const VerbosityLevel level)
alias of setMinLoggingLevel()
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
std::array< double, 3 > coefs
Line coefficients, stored as an array: .
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
bool ransac2Dline_degenerate(const CMatrixDynamic< T > &allData, const std::vector< size_t > &useIndices)
Return "true" if the selected points are a degenerate (invalid) case.
void setSize(size_t row, size_t col, bool zeroNewElements=false)
Changes the size of matrix, maintaining the previous contents.
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)
#define EXPLICIT_INSTANT_ransac_detect_2D_lines(_TYPE_)
A generic RANSAC implementation with models as matrices.
bool execute(const CMatrixDynamic< NUMTYPE > &data, const TRansacFitFunctor &fit_func, const TRansacDistanceFunctor &dist_func, const TRansacDegenerateFunctor °en_func, const double distanceThreshold, const unsigned int minimumSizeSamplesToFit, std::vector< size_t > &out_best_inliers, CMatrixDynamic< 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 template class provides the basic functionality for a general 2D any-size, resizable container o...
std::array< double, 4 > coefs
Plane coefficients, stored as an array: .
bool ransac3Dplane_degenerate(const CMatrixDynamic< T > &allData, const std::vector< size_t > &useIndices)
Return "true" if the selected points are a degenerate (invalid) case.
#define MRPT_UNUSED_PARAM(a)
Determines whether this is an X86 or AMD64 platform.
2D line without bounds, represented by its equation .