28 const std::vector<size_t>& useIndices,
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,
64 std::vector<size_t>& out_inlierIndices)
66 ASSERT_(testModels.size() == 1);
67 out_bestModelIndex = 0;
70 ASSERT_(M.rows() == 1 && M.cols() == 4);
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 = allData.cols();
79 out_inlierIndices.clear();
80 out_inlierIndices.reserve(100);
81 for (
size_t i = 0; i < N; i++)
83 const double d = plane.distance(
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);
96 const std::vector<size_t>& useIndices)
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);
135 std::vector<size_t> this_best_inliers;
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(
202 const std::vector<size_t>& useIndices,
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,
231 std::vector<size_t>& out_inlierIndices)
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())));
245 ASSERT_(M.rows() == 1 && M.cols() == 3);
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 = allData.cols();
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(
267 const std::vector<size_t>& useIndices)
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)
288 out_detected_lines.clear();
290 if (
x.empty())
return;
294 remainingPoints.insertRow(0,
x);
295 remainingPoints.insertRow(1,
y);
300 while (remainingPoints.cols() >= 2)
302 std::vector<size_t> this_best_inliers;
308 remainingPoints, ransac2Dline_fit<NUMTYPE>,
309 ransac2Dline_distance<NUMTYPE>, ransac2Dline_degenerate<NUMTYPE>,
312 this_best_inliers, this_best_model,
317 if (this_best_inliers.size() >= min_inliers_for_valid_line)
320 out_detected_lines.push_back(
322 this_best_inliers.size(),
324 double(this_best_model(0, 0)),
325 double(this_best_model(0, 1)),
326 double(this_best_model(0, 2)))));
328 out_detected_lines.rbegin()->second.unitarize();
332 remainingPoints.removeColumns(this_best_inliers);
344 #define EXPLICIT_INSTANT_ransac_detect_2D_lines(_TYPE_) \ 345 template void mrpt::math::ransac_detect_2D_lines<_TYPE_>( \ 346 const Eigen::Matrix<_TYPE_, Eigen::Dynamic, 1>& x, \ 347 const Eigen::Matrix<_TYPE_, Eigen::Dynamic, 1>& y, \ 348 std::vector<std::pair<size_t, TLine2D>>& out_detected_lines, \ 349 const double threshold, const size_t min_inliers_for_valid_line); 353 #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...
void ransac3Dplane_fit(const CMatrixTemplateNumeric< T > &allData, const std::vector< size_t > &useIndices, vector< CMatrixTemplateNumeric< T >> &fitModels)
#define ASSERT_(f)
Defines an assertion mechanism.
This base provides a set of functions for maths stuff.
#define EXPLICIT_INST_ransac_detect_3D_planes(_TYPE_)
3D Plane, represented by its equation
double coefs[3]
Line coefficients, stored as an array: .
#define ASSERTMSG_(f, __ERROR_MSG)
Defines an assertion mechanism.
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...
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, std::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.
void setVerbosityLevel(const VerbosityLevel level)
alias of setMinLoggingLevel()
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
double coefs[4]
Plane coefficients, stored as an array: .
A matrix of dynamic size.
void ransac3Dplane_distance(const CMatrixTemplateNumeric< T > &allData, const vector< CMatrixTemplateNumeric< T >> &testModels, const T distanceThreshold, unsigned int &out_bestModelIndex, std::vector< size_t > &out_inlierIndices)
#define EXPLICIT_INSTANT_ransac_detect_2D_lines(_TYPE_)
bool ransac3Dplane_degenerate(const CMatrixTemplateNumeric< T > &allData, const std::vector< size_t > &useIndices)
Return "true" if the selected points are a degenerate (invalid) case.
A generic RANSAC implementation with models as matrices.
#define MRPT_UNUSED_PARAM(a)
Determines whether this is an X86 or AMD64 platform.
2D line without bounds, represented by its equation .