38 #ifndef PCL_SEGMENTATION_IMPL_SAC_SEGMENTATION_H_
39 #define PCL_SEGMENTATION_IMPL_SAC_SEGMENTATION_H_
70 template <
typename Po
intT>
void
74 inliers.
header = model_coefficients.
header = input_->header;
83 if (!initSACModel (model_type_))
85 PCL_ERROR (
"[pcl::%s::segment] Error initializing the SAC model!\n", getClassName ().c_str ());
91 initSAC (method_type_);
93 if (!sac_->computeModel (0))
95 PCL_ERROR (
"[pcl::%s::segment] Error segmenting the model! No solution found.\n", getClassName ().c_str ());
102 sac_->getInliers (inliers.
indices);
105 Eigen::VectorXf coeff;
106 sac_->getModelCoefficients (coeff);
109 if (optimize_coefficients_)
111 Eigen::VectorXf coeff_refined;
112 model_->optimizeModelCoefficients (inliers.
indices, coeff, coeff_refined);
113 model_coefficients.
values.resize (coeff_refined.size ());
114 memcpy (&model_coefficients.
values[0], &coeff_refined[0], coeff_refined.size () *
sizeof (float));
116 model_->selectWithinDistance (coeff_refined, threshold_, inliers.
indices);
120 model_coefficients.
values.resize (coeff.size ());
121 memcpy (&model_coefficients.
values[0], &coeff[0], coeff.size () *
sizeof (float));
128 template <
typename Po
intT>
bool
139 PCL_DEBUG (
"[pcl::%s::initSACModel] Using a model of type: SACMODEL_PLANE\n", getClassName ().c_str ());
145 PCL_DEBUG (
"[pcl::%s::initSACModel] Using a model of type: SACMODEL_LINE\n", getClassName ().c_str ());
146 model_.reset (
new SampleConsensusModelLine<PointT> (input_, *indices_));
151 PCL_DEBUG (
"[pcl::%s::initSACModel] Using a model of type: SACMODEL_STICK\n", getClassName ().c_str ());
152 model_.reset (
new SampleConsensusModelStick<PointT> (input_, *indices_));
153 double min_radius, max_radius;
154 model_->getRadiusLimits (min_radius, max_radius);
155 if (radius_min_ != min_radius && radius_max_ != max_radius)
157 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting radius limits to %f/%f\n", getClassName ().c_str (), radius_min_, radius_max_);
158 model_->setRadiusLimits (radius_min_, radius_max_);
164 PCL_DEBUG (
"[pcl::%s::initSACModel] Using a model of type: SACMODEL_CIRCLE2D\n", getClassName ().c_str ());
165 model_.reset (
new SampleConsensusModelCircle2D<PointT> (input_, *indices_));
166 typename SampleConsensusModelCircle2D<PointT>::Ptr model_circle = boost::static_pointer_cast<SampleConsensusModelCircle2D<PointT> > (model_);
167 double min_radius, max_radius;
168 model_circle->getRadiusLimits (min_radius, max_radius);
169 if (radius_min_ != min_radius && radius_max_ != max_radius)
171 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting radius limits to %f/%f\n", getClassName ().c_str (), radius_min_, radius_max_);
172 model_circle->setRadiusLimits (radius_min_, radius_max_);
178 PCL_DEBUG (
"[pcl::%s::initSACModel] Using a model of type: SACMODEL_SPHERE\n", getClassName ().c_str ());
179 model_.reset (
new SampleConsensusModelSphere<PointT> (input_, *indices_));
180 typename SampleConsensusModelSphere<PointT>::Ptr model_sphere = boost::static_pointer_cast<SampleConsensusModelSphere<PointT> > (model_);
181 double min_radius, max_radius;
182 model_sphere->getRadiusLimits (min_radius, max_radius);
183 if (radius_min_ != min_radius && radius_max_ != max_radius)
185 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting radius limits to %f/%f\n", getClassName ().c_str (), radius_min_, radius_max_);
186 model_sphere->setRadiusLimits (radius_min_, radius_max_);
192 PCL_DEBUG (
"[pcl::%s::initSACModel] Using a model of type: SACMODEL_PARALLEL_LINE\n", getClassName ().c_str ());
193 model_.reset (
new SampleConsensusModelParallelLine<PointT> (input_, *indices_));
194 typename SampleConsensusModelParallelLine<PointT>::Ptr model_parallel = boost::static_pointer_cast<SampleConsensusModelParallelLine<PointT> > (model_);
195 if (axis_ != Eigen::Vector3f::Zero () && model_parallel->getAxis () != axis_)
197 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting the axis to %f, %f, %f\n", getClassName ().c_str (), axis_[0], axis_[1], axis_[2]);
198 model_parallel->setAxis (axis_);
200 if (eps_angle_ != 0.0 && model_parallel->getEpsAngle () != eps_angle_)
202 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting the epsilon angle to %f (%f degrees)\n", getClassName ().c_str (), eps_angle_, eps_angle_ * 180.0 / M_PI);
203 model_parallel->setEpsAngle (eps_angle_);
209 PCL_DEBUG (
"[pcl::%s::initSACModel] Using a model of type: SACMODEL_PERPENDICULAR_PLANE\n", getClassName ().c_str ());
210 model_.reset (
new SampleConsensusModelPerpendicularPlane<PointT> (input_, *indices_));
211 typename SampleConsensusModelPerpendicularPlane<PointT>::Ptr model_perpendicular = boost::static_pointer_cast<SampleConsensusModelPerpendicularPlane<PointT> > (model_);
212 if (axis_ != Eigen::Vector3f::Zero () && model_perpendicular->getAxis () != axis_)
214 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting the axis to %f, %f, %f\n", getClassName ().c_str (), axis_[0], axis_[1], axis_[2]);
215 model_perpendicular->setAxis (axis_);
217 if (eps_angle_ != 0.0 && model_perpendicular->getEpsAngle () != eps_angle_)
219 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting the epsilon angle to %f (%f degrees)\n", getClassName ().c_str (), eps_angle_, eps_angle_ * 180.0 / M_PI);
220 model_perpendicular->setEpsAngle (eps_angle_);
226 PCL_DEBUG (
"[pcl::%s::initSACModel] Using a model of type: SACMODEL_PARALLEL_PLANE\n", getClassName ().c_str ());
227 model_.reset (
new SampleConsensusModelParallelPlane<PointT> (input_, *indices_));
228 typename SampleConsensusModelParallelPlane<PointT>::Ptr model_parallel = boost::static_pointer_cast<SampleConsensusModelParallelPlane<PointT> > (model_);
229 if (axis_ != Eigen::Vector3f::Zero () && model_parallel->getAxis () != axis_)
231 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting the axis to %f, %f, %f\n", getClassName ().c_str (), axis_[0], axis_[1], axis_[2]);
232 model_parallel->setAxis (axis_);
234 if (eps_angle_ != 0.0 && model_parallel->getEpsAngle () != eps_angle_)
236 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting the epsilon angle to %f (%f degrees)\n", getClassName ().c_str (), eps_angle_, eps_angle_ * 180.0 / M_PI);
237 model_parallel->setEpsAngle (eps_angle_);
243 PCL_ERROR (
"[pcl::%s::initSACModel] No valid model given!\n", getClassName ().c_str ());
248 if (samples_radius_ > 0. )
250 PCL_DEBUG (
"[pcl::%s::initSAC] Setting the maximum distance to %f\n", getClassName ().c_str (), samples_radius_);
252 model_->setSamplesMaxDist(samples_radius_, samples_radius_search_);
259 template <
typename Po
intT>
void
270 PCL_DEBUG (
"[pcl::%s::initSAC] Using a method of type: SAC_RANSAC with a model threshold of %f\n", getClassName ().c_str (), threshold_);
271 sac_.reset (
new RandomSampleConsensus<PointT> (model_, threshold_));
276 PCL_DEBUG (
"[pcl::%s::initSAC] Using a method of type: SAC_LMEDS with a model threshold of %f\n", getClassName ().c_str (), threshold_);
277 sac_.reset (
new LeastMedianSquares<PointT> (model_, threshold_));
282 PCL_DEBUG (
"[pcl::%s::initSAC] Using a method of type: SAC_MSAC with a model threshold of %f\n", getClassName ().c_str (), threshold_);
283 sac_.reset (
new MEstimatorSampleConsensus<PointT> (model_, threshold_));
288 PCL_DEBUG (
"[pcl::%s::initSAC] Using a method of type: SAC_RRANSAC with a model threshold of %f\n", getClassName ().c_str (), threshold_);
289 sac_.reset (
new RandomizedRandomSampleConsensus<PointT> (model_, threshold_));
294 PCL_DEBUG (
"[pcl::%s::initSAC] Using a method of type: SAC_RMSAC with a model threshold of %f\n", getClassName ().c_str (), threshold_);
295 sac_.reset (
new RandomizedMEstimatorSampleConsensus<PointT> (model_, threshold_));
300 PCL_DEBUG (
"[pcl::%s::initSAC] Using a method of type: SAC_MLESAC with a model threshold of %f\n", getClassName ().c_str (), threshold_);
301 sac_.reset (
new MaximumLikelihoodSampleConsensus<PointT> (model_, threshold_));
306 PCL_DEBUG (
"[pcl::%s::initSAC] Using a method of type: SAC_PROSAC with a model threshold of %f\n", getClassName ().c_str (), threshold_);
307 sac_.reset (
new ProgressiveSampleConsensus<PointT> (model_, threshold_));
312 if (sac_->getProbability () != probability_)
314 PCL_DEBUG (
"[pcl::%s::initSAC] Setting the desired probability to %f\n", getClassName ().c_str (), probability_);
315 sac_->setProbability (probability_);
317 if (max_iterations_ != -1 && sac_->getMaxIterations () != max_iterations_)
319 PCL_DEBUG (
"[pcl::%s::initSAC] Setting the maximum number of iterations to %d\n", getClassName ().c_str (), max_iterations_);
320 sac_->setMaxIterations (max_iterations_);
325 template <
typename Po
intT,
typename Po
intNT>
bool
328 if (!input_ || !normals_)
330 PCL_ERROR (
"[pcl::%s::initSACModel] Input data (XYZ or normals) not given! Cannot continue.\n", getClassName ().c_str ());
334 if (input_->points.size () != normals_->points.size ())
336 PCL_ERROR (
"[pcl::%s::initSACModel] The number of points inthe input point cloud differs than the number of points in the normals!\n", getClassName ().c_str ());
348 PCL_DEBUG (
"[pcl::%s::initSACModel] Using a model of type: SACMODEL_CYLINDER\n", getClassName ().c_str ());
349 model_.reset (
new SampleConsensusModelCylinder<PointT, PointNT > (input_, *indices_));
350 typename SampleConsensusModelCylinder<PointT, PointNT>::Ptr model_cylinder = boost::static_pointer_cast<SampleConsensusModelCylinder<PointT, PointNT> > (model_);
353 model_cylinder->setInputNormals (normals_);
354 double min_radius, max_radius;
355 model_cylinder->getRadiusLimits (min_radius, max_radius);
356 if (radius_min_ != min_radius && radius_max_ != max_radius)
358 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting radius limits to %f/%f\n", getClassName ().c_str (), radius_min_, radius_max_);
359 model_cylinder->setRadiusLimits (radius_min_, radius_max_);
361 if (distance_weight_ != model_cylinder->getNormalDistanceWeight ())
363 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting normal distance weight to %f\n", getClassName ().c_str (), distance_weight_);
364 model_cylinder->setNormalDistanceWeight (distance_weight_);
366 if (axis_ != Eigen::Vector3f::Zero () && model_cylinder->getAxis () != axis_)
368 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting the axis to %f, %f, %f\n", getClassName ().c_str (), axis_[0], axis_[1], axis_[2]);
369 model_cylinder->setAxis (axis_);
371 if (eps_angle_ != 0.0 && model_cylinder->getEpsAngle () != eps_angle_)
373 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting the epsilon angle to %f (%f degrees)\n", getClassName ().c_str (), eps_angle_, eps_angle_ * 180.0 / M_PI);
374 model_cylinder->setEpsAngle (eps_angle_);
380 PCL_DEBUG (
"[pcl::%s::initSACModel] Using a model of type: SACMODEL_NORMAL_PLANE\n", getClassName ().c_str ());
381 model_.reset (
new SampleConsensusModelNormalPlane<PointT, PointNT> (input_, *indices_));
382 typename SampleConsensusModelNormalPlane<PointT, PointNT>::Ptr model_normals = boost::static_pointer_cast<SampleConsensusModelNormalPlane<PointT, PointNT> > (model_);
384 model_normals->setInputNormals (normals_);
385 if (distance_weight_ != model_normals->getNormalDistanceWeight ())
387 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting normal distance weight to %f\n", getClassName ().c_str (), distance_weight_);
388 model_normals->setNormalDistanceWeight (distance_weight_);
394 PCL_DEBUG (
"[pcl::%s::initSACModel] Using a model of type: SACMODEL_NORMAL_PARALLEL_PLANE\n", getClassName ().c_str ());
395 model_.reset (
new SampleConsensusModelNormalParallelPlane<PointT, PointNT> (input_, *indices_));
396 typename SampleConsensusModelNormalParallelPlane<PointT, PointNT>::Ptr model_normals = boost::static_pointer_cast<SampleConsensusModelNormalParallelPlane<PointT, PointNT> > (model_);
398 model_normals->setInputNormals (normals_);
399 if (distance_weight_ != model_normals->getNormalDistanceWeight ())
401 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting normal distance weight to %f\n", getClassName ().c_str (), distance_weight_);
402 model_normals->setNormalDistanceWeight (distance_weight_);
404 if (distance_from_origin_ != model_normals->getDistanceFromOrigin ())
406 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting the distance to origin to %f\n", getClassName ().c_str (), distance_from_origin_);
407 model_normals->setDistanceFromOrigin (distance_from_origin_);
409 if (axis_ != Eigen::Vector3f::Zero () && model_normals->getAxis () != axis_)
411 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting the axis to %f, %f, %f\n", getClassName ().c_str (), axis_[0], axis_[1], axis_[2]);
412 model_normals->setAxis (axis_);
414 if (eps_angle_ != 0.0 && model_normals->getEpsAngle () != eps_angle_)
416 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting the epsilon angle to %f (%f degrees)\n", getClassName ().c_str (), eps_angle_, eps_angle_ * 180.0 / M_PI);
417 model_normals->setEpsAngle (eps_angle_);
423 PCL_DEBUG (
"[pcl::%s::initSACModel] Using a model of type: SACMODEL_CONE\n", getClassName ().c_str ());
424 model_.reset (
new SampleConsensusModelCone<PointT, PointNT > (input_, *indices_));
425 typename SampleConsensusModelCone<PointT, PointNT>::Ptr model_cone = boost::static_pointer_cast<SampleConsensusModelCone<PointT, PointNT> > (model_);
428 model_cone->setInputNormals (normals_);
429 double min_angle, max_angle;
430 model_cone->getMinMaxOpeningAngle(min_angle, max_angle);
431 if (min_angle_ != min_angle && max_angle_ != max_angle)
433 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting minimum and maximum opening angle to %f and %f \n", getClassName ().c_str (), min_angle_, max_angle_);
434 model_cone->setMinMaxOpeningAngle (min_angle_, max_angle_);
437 if (distance_weight_ != model_cone->getNormalDistanceWeight ())
439 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting normal distance weight to %f\n", getClassName ().c_str (), distance_weight_);
440 model_cone->setNormalDistanceWeight (distance_weight_);
442 if (axis_ != Eigen::Vector3f::Zero () && model_cone->getAxis () != axis_)
444 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting the axis to %f, %f, %f\n", getClassName ().c_str (), axis_[0], axis_[1], axis_[2]);
445 model_cone->setAxis (axis_);
447 if (eps_angle_ != 0.0 && model_cone->getEpsAngle () != eps_angle_)
449 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting the epsilon angle to %f (%f degrees)\n", getClassName ().c_str (), eps_angle_, eps_angle_ * 180.0 / M_PI);
450 model_cone->setEpsAngle (eps_angle_);
456 PCL_DEBUG (
"[pcl::%s::initSACModel] Using a model of type: SACMODEL_NORMAL_SPHERE\n", getClassName ().c_str ());
457 model_.reset (
new SampleConsensusModelNormalSphere<PointT, PointNT> (input_, *indices_));
458 typename SampleConsensusModelNormalSphere<PointT, PointNT>::Ptr model_normals_sphere = boost::static_pointer_cast<SampleConsensusModelNormalSphere<PointT, PointNT> > (model_);
460 model_normals_sphere->setInputNormals (normals_);
461 double min_radius, max_radius;
462 model_normals_sphere->getRadiusLimits (min_radius, max_radius);
463 if (radius_min_ != min_radius && radius_max_ != max_radius)
465 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting radius limits to %f/%f\n", getClassName ().c_str (), radius_min_, radius_max_);
466 model_normals_sphere->setRadiusLimits (radius_min_, radius_max_);
469 if (distance_weight_ != model_normals_sphere->getNormalDistanceWeight ())
471 PCL_DEBUG (
"[pcl::%s::initSACModel] Setting normal distance weight to %f\n", getClassName ().c_str (), distance_weight_);
472 model_normals_sphere->setNormalDistanceWeight (distance_weight_);
483 if (SACSegmentation<PointT>::samples_radius_ > 0. )
485 PCL_DEBUG (
"[pcl::%s::initSAC] Setting the maximum distance to %f\n", getClassName ().c_str (), SACSegmentation<PointT>::samples_radius_);
487 model_->setSamplesMaxDist(SACSegmentation<PointT>::samples_radius_, SACSegmentation<PointT>::samples_radius_search_);
493 #define PCL_INSTANTIATE_SACSegmentation(T) template class PCL_EXPORTS pcl::SACSegmentation<T>;
494 #define PCL_INSTANTIATE_SACSegmentationFromNormals(T,NT) template class PCL_EXPORTS pcl::SACSegmentationFromNormals<T,NT>;
496 #endif // PCL_SEGMENTATION_IMPL_SAC_SEGMENTATION_H_