// SPDX-License-Identifier: LGPL-2.1-or-later /*************************************************************************** * Copyright (c) 2016 Werner Mayer * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ***************************************************************************/ #include #include #include #include "SampleConsensus.h" #if defined(HAVE_PCL_SAMPLE_CONSENSUS) # include # include # include # include # include # include # include using namespace std; using namespace Reen; using pcl::PointCloud; using pcl::PointNormal; using pcl::PointXYZ; SampleConsensus::SampleConsensus( SacModel sac, const Points::PointKernel& pts, const std::vector& nor ) : mySac(sac) , myPoints(pts) , myNormals(nor) {} double SampleConsensus::perform(std::vector& parameters, std::vector& model) { pcl::PointCloud::Ptr cloud(new pcl::PointCloud); cloud->reserve(myPoints.size()); for (Points::PointKernel::const_iterator it = myPoints.begin(); it != myPoints.end(); ++it) { if (!boost::math::isnan(it->x) && !boost::math::isnan(it->y) && !boost::math::isnan(it->z)) { cloud->push_back(pcl::PointXYZ(it->x, it->y, it->z)); } } cloud->width = int(cloud->points.size()); cloud->height = 1; cloud->is_dense = true; pcl::PointCloud::Ptr normals(new pcl::PointCloud()); if (mySac == SACMODEL_CONE || mySac == SACMODEL_CYLINDER) { # if 0 // Create search tree pcl::search::KdTree::Ptr tree; tree.reset (new pcl::search::KdTree (false)); tree->setInputCloud (cloud); // Normal estimation int ksearch = 10; pcl::NormalEstimation n; n.setInputCloud (cloud); n.setSearchMethod (tree); n.setKSearch (ksearch); n.compute (*normals); # else normals->reserve(myNormals.size()); for (std::vector::const_iterator it = myNormals.begin(); it != myNormals.end(); ++it) { if (!boost::math::isnan(it->x) && !boost::math::isnan(it->y) && !boost::math::isnan(it->z)) { normals->push_back(pcl::Normal(it->x, it->y, it->z)); } } # endif } // created RandomSampleConsensus object and compute the appropriated model pcl::SampleConsensusModel::Ptr model_p; switch (mySac) { case SACMODEL_PLANE: { model_p.reset(new pcl::SampleConsensusModelPlane(cloud)); break; } case SACMODEL_SPHERE: { model_p.reset(new pcl::SampleConsensusModelSphere(cloud)); break; } case SACMODEL_CONE: { pcl::SampleConsensusModelCone::Ptr model_c( new pcl::SampleConsensusModelCone(cloud) ); model_c->setInputNormals(normals); model_p = model_c; break; } case SACMODEL_CYLINDER: { pcl::SampleConsensusModelCylinder::Ptr model_c( new pcl::SampleConsensusModelCylinder(cloud) ); model_c->setInputNormals(normals); model_p = model_c; break; } default: throw Base::RuntimeError("Unsupported SAC model"); } pcl::RandomSampleConsensus ransac(model_p); ransac.setDistanceThreshold(.01); ransac.computeModel(); ransac.getInliers(model); // ransac.getModel (model); Eigen::VectorXf model_p_coefficients; ransac.getModelCoefficients(model_p_coefficients); for (int i = 0; i < model_p_coefficients.size(); i++) { parameters.push_back(model_p_coefficients[i]); } return ransac.getProbability(); } #endif // HAVE_PCL_SAMPLE_CONSENSUS