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++)
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++)
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