258 const Eigen::Vector3f c(model_coefficients[0], model_coefficients[1], model_coefficients[2]);
260 const Eigen::Vector3f n_axis(model_coefficients[5], model_coefficients[6], model_coefficients[7]);
262 const Eigen::Vector3f x_axis(model_coefficients[8], model_coefficients[9], model_coefficients[10]);
264 const Eigen::Vector3f y_axis = n_axis.cross(x_axis).normalized();
266 const float par_a(model_coefficients[3]);
268 const float par_b(model_coefficients[4]);
271 const Eigen::Matrix3f Rot = (Eigen::Matrix3f(3,3)
272 << x_axis(0), y_axis(0), n_axis(0),
273 x_axis(1), y_axis(1), n_axis(1),
274 x_axis(2), y_axis(2), n_axis(2))
276 const Eigen::Matrix3f Rot_T = Rot.transpose();
279 const Eigen::VectorXf params = (Eigen::VectorXf(5) << par_a, par_b, 0.0, 0.0, 0.0).finished();
283 for (std::size_t i = 0; i <
indices_->size (); ++i)
295 const Eigen::Vector3f p_ = Rot_T * (p - c);
301 const Eigen::Vector2f distanceVector = dvec2ellipse(params, p_(0), p_(1), th_opt);
310 const Eigen::VectorXf &model_coefficients,
const double threshold,
320 inliers.reserve (
indices_->size ());
324 const Eigen::Vector3f c(model_coefficients[0], model_coefficients[1], model_coefficients[2]);
326 const Eigen::Vector3f n_axis(model_coefficients[5], model_coefficients[6], model_coefficients[7]);
328 const Eigen::Vector3f x_axis(model_coefficients[8], model_coefficients[9], model_coefficients[10]);
330 const Eigen::Vector3f y_axis = n_axis.cross(x_axis).normalized();
332 const float par_a(model_coefficients[3]);
334 const float par_b(model_coefficients[4]);
337 const Eigen::Matrix3f Rot = (Eigen::Matrix3f(3,3)
338 << x_axis(0), y_axis(0), n_axis(0),
339 x_axis(1), y_axis(1), n_axis(1),
340 x_axis(2), y_axis(2), n_axis(2))
342 const Eigen::Matrix3f Rot_T = Rot.transpose();
344 const auto squared_threshold = threshold * threshold;
346 for (std::size_t i = 0; i <
indices_->size (); ++i)
352 const Eigen::Vector3f p_ = Rot_T * (p - c);
358 const Eigen::VectorXf params = (Eigen::VectorXf(5) << par_a, par_b, 0.0, 0.0, 0.0).finished();
360 const Eigen::Vector2f distanceVector = dvec2ellipse(params, p_(0), p_(1), th_opt);
362 const double sqr_dist = distanceVector.squaredNorm();
363 if (sqr_dist < squared_threshold)
375 const Eigen::VectorXf &model_coefficients,
const double threshold)
const
380 std::size_t nr_p = 0;
383 const Eigen::Vector3f c(model_coefficients[0], model_coefficients[1], model_coefficients[2]);
385 const Eigen::Vector3f n_axis(model_coefficients[5], model_coefficients[6], model_coefficients[7]);
387 const Eigen::Vector3f x_axis(model_coefficients[8], model_coefficients[9], model_coefficients[10]);
389 const Eigen::Vector3f y_axis = n_axis.cross(x_axis).normalized();
391 const float par_a(model_coefficients[3]);
393 const float par_b(model_coefficients[4]);
396 const Eigen::Matrix3f Rot = (Eigen::Matrix3f(3,3)
397 << x_axis(0), y_axis(0), n_axis(0),
398 x_axis(1), y_axis(1), n_axis(1),
399 x_axis(2), y_axis(2), n_axis(2))
401 const Eigen::Matrix3f Rot_T = Rot.transpose();
403 const auto squared_threshold = threshold * threshold;
405 for (std::size_t i = 0; i <
indices_->size (); ++i)
411 const Eigen::Vector3f p_ = Rot_T * (p - c);
417 const Eigen::VectorXf params = (Eigen::VectorXf(5) << par_a, par_b, 0.0, 0.0, 0.0).finished();
419 const Eigen::Vector2f distanceVector = dvec2ellipse(params, p_(0), p_(1), th_opt);
421 if (distanceVector.squaredNorm() < squared_threshold)
431 const Eigen::VectorXf &model_coefficients,
432 Eigen::VectorXf &optimized_coefficients)
const
434 optimized_coefficients = model_coefficients;
439 PCL_ERROR (
"[pcl::SampleConsensusModelEllipse3D::optimizeModelCoefficients] Given model is invalid!\n");
446 PCL_ERROR (
"[pcl::SampleConsensusModelEllipse3D::optimizeModelCoefficients] Not enough inliers to refine/optimize the model's coefficients (%lu)! Returning the same coefficients.\n", inliers.size ());
450 OptimizationFunctor functor(
this, inliers);
451 Eigen::NumericalDiff<OptimizationFunctor> num_diff(functor);
452 Eigen::LevenbergMarquardt<Eigen::NumericalDiff<OptimizationFunctor>,
double> lm(num_diff);
453 Eigen::VectorXd coeff = model_coefficients.cast<
double>();
454 int info = lm.minimize(coeff);
455 optimized_coefficients = coeff.cast<
float>();
458 PCL_DEBUG (
"[pcl::SampleConsensusModelEllipse3D::optimizeModelCoefficients] LM solver finished with exit code %i, having a residual norm of %g. \nInitial solution: %g %g %g %g %g %g %g %g %g %g %g\nFinal solution: %g %g %g %g %g %g %g %g %g %g %g\n",
459 info, lm.fvec.norm (),
461 model_coefficients[0],
462 model_coefficients[1],
463 model_coefficients[2],
464 model_coefficients[3],
465 model_coefficients[4],
466 model_coefficients[5],
467 model_coefficients[6],
468 model_coefficients[7],
469 model_coefficients[8],
470 model_coefficients[9],
471 model_coefficients[10],
473 optimized_coefficients[0],
474 optimized_coefficients[1],
475 optimized_coefficients[2],
476 optimized_coefficients[3],
477 optimized_coefficients[4],
478 optimized_coefficients[5],
479 optimized_coefficients[6],
480 optimized_coefficients[7],
481 optimized_coefficients[8],
482 optimized_coefficients[9],
483 optimized_coefficients[10]);
489 const Indices &inliers,
const Eigen::VectorXf &model_coefficients,
490 PointCloud &projected_points,
bool copy_data_fields)
const
495 PCL_ERROR (
"[pcl::SampleConsensusModelEllipse3D::projectPoints] Given model is invalid!\n");
499 projected_points.header =
input_->header;
500 projected_points.is_dense =
input_->is_dense;
503 if (copy_data_fields)
506 projected_points.resize (
input_->size ());
507 projected_points.width =
input_->width;
508 projected_points.height =
input_->height;
510 using FieldList =
typename pcl::traits::fieldList<PointT>::type;
512 for (std::size_t i = 0; i < projected_points.size(); ++i)
519 const Eigen::Vector3f c(model_coefficients[0], model_coefficients[1], model_coefficients[2]);
521 const Eigen::Vector3f n_axis(model_coefficients[5], model_coefficients[6], model_coefficients[7]);
523 const Eigen::Vector3f x_axis(model_coefficients[8], model_coefficients[9], model_coefficients[10]);
525 const Eigen::Vector3f y_axis = n_axis.cross(x_axis).normalized();
527 const float par_a(model_coefficients[3]);
529 const float par_b(model_coefficients[4]);
532 const Eigen::Matrix3f Rot = (Eigen::Matrix3f(3,3)
533 << x_axis(0), y_axis(0), n_axis(0),
534 x_axis(1), y_axis(1), n_axis(1),
535 x_axis(2), y_axis(2), n_axis(2))
537 const Eigen::Matrix3f Rot_T = Rot.transpose();
540 for (std::size_t i = 0; i < inliers.size (); ++i)
546 const Eigen::Vector3f p_ = Rot_T * (p - c);
552 const Eigen::VectorXf params = (Eigen::VectorXf(5) << par_a, par_b, 0.0, 0.0, 0.0).finished();
554 dvec2ellipse(params, p_(0), p_(1), th_opt);
557 Eigen::Vector3f k_(0.0, 0.0, 0.0);
558 get_ellipse_point(params, th_opt, k_[0], k_[1]);
560 const Eigen::Vector3f k = c + Rot * k_;
562 projected_points[i].x =
static_cast<float> (k[0]);
563 projected_points[i].y =
static_cast<float> (k[1]);
564 projected_points[i].z =
static_cast<float> (k[2]);
570 projected_points.resize (inliers.size ());
571 projected_points.width = inliers.size ();
572 projected_points.height = 1;
574 using FieldList =
typename pcl::traits::fieldList<PointT>::type;
576 for (std::size_t i = 0; i < inliers.size (); ++i)
581 const Eigen::Vector3f c(model_coefficients[0], model_coefficients[1], model_coefficients[2]);
583 const Eigen::Vector3f n_axis(model_coefficients[5], model_coefficients[6], model_coefficients[7]);
585 const Eigen::Vector3f x_axis(model_coefficients[8], model_coefficients[9], model_coefficients[10]);
587 const Eigen::Vector3f y_axis = n_axis.cross(x_axis).normalized();
589 const float par_a(model_coefficients[3]);
591 const float par_b(model_coefficients[4]);
594 const Eigen::Matrix3f Rot = (Eigen::Matrix3f(3,3)
595 << x_axis(0), y_axis(0), n_axis(0),
596 x_axis(1), y_axis(1), n_axis(1),
597 x_axis(2), y_axis(2), n_axis(2))
599 const Eigen::Matrix3f Rot_T = Rot.transpose();
602 for (std::size_t i = 0; i < inliers.size (); ++i)
608 const Eigen::Vector3f p_ = Rot_T * (p - c);
614 const Eigen::VectorXf params = (Eigen::VectorXf(5) << par_a, par_b, 0.0, 0.0, 0.0).finished();
616 dvec2ellipse(params, p_(0), p_(1), th_opt);
620 Eigen::Vector3f k_(0.0, 0.0, 0.0);
621 get_ellipse_point(params, th_opt, k_[0], k_[1]);
623 const Eigen::Vector3f k = c + Rot * k_;
625 projected_points[i].x =
static_cast<float> (k[0]);
626 projected_points[i].y =
static_cast<float> (k[1]);
627 projected_points[i].z =
static_cast<float> (k[2]);
635 const std::set<index_t> &indices,
636 const Eigen::VectorXf &model_coefficients,
637 const double threshold)
const
642 PCL_ERROR (
"[pcl::SampleConsensusModelEllipse3D::doSamplesVerifyModel] Given model is invalid!\n");
647 const Eigen::Vector3f c(model_coefficients[0], model_coefficients[1], model_coefficients[2]);
649 const Eigen::Vector3f n_axis(model_coefficients[5], model_coefficients[6], model_coefficients[7]);
651 const Eigen::Vector3f x_axis(model_coefficients[8], model_coefficients[9], model_coefficients[10]);
653 const Eigen::Vector3f y_axis = n_axis.cross(x_axis).normalized();
655 const float par_a(model_coefficients[3]);
657 const float par_b(model_coefficients[4]);
660 const Eigen::Matrix3f Rot = (Eigen::Matrix3f(3,3)
661 << x_axis(0), y_axis(0), n_axis(0),
662 x_axis(1), y_axis(1), n_axis(1),
663 x_axis(2), y_axis(2), n_axis(2))
665 const Eigen::Matrix3f Rot_T = Rot.transpose();
667 const auto squared_threshold = threshold * threshold;
668 for (
const auto &index : indices)
674 const Eigen::Vector3f p_ = Rot_T * (p - c);
680 const Eigen::VectorXf params = (Eigen::VectorXf(5) << par_a, par_b, 0.0, 0.0, 0.0).finished();
682 const Eigen::Vector2f distanceVector = dvec2ellipse(params, p_(0), p_(1), th_opt);
684 if (distanceVector.squaredNorm() > squared_threshold)