Point Cloud Library (PCL)  1.6.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sac_segmentation.hpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2009, Willow Garage, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of Willow Garage, Inc. nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * $Id: sac_segmentation.hpp 6155 2012-07-04 23:10:00Z aichim $
35  *
36  */
37 
38 #ifndef PCL_SEGMENTATION_IMPL_SAC_SEGMENTATION_H_
39 #define PCL_SEGMENTATION_IMPL_SAC_SEGMENTATION_H_
40 
42 
43 // Sample Consensus methods
52 
53 // Sample Consensus models
68 
70 template <typename PointT> void
72 {
73  // Copy the header information
74  inliers.header = model_coefficients.header = input_->header;
75 
76  if (!initCompute ())
77  {
78  inliers.indices.clear (); model_coefficients.values.clear ();
79  return;
80  }
81 
82  // Initialize the Sample Consensus model and set its parameters
83  if (!initSACModel (model_type_))
84  {
85  PCL_ERROR ("[pcl::%s::segment] Error initializing the SAC model!\n", getClassName ().c_str ());
86  deinitCompute ();
87  inliers.indices.clear (); model_coefficients.values.clear ();
88  return;
89  }
90  // Initialize the Sample Consensus method and set its parameters
91  initSAC (method_type_);
92 
93  if (!sac_->computeModel (0))
94  {
95  PCL_ERROR ("[pcl::%s::segment] Error segmenting the model! No solution found.\n", getClassName ().c_str ());
96  deinitCompute ();
97  inliers.indices.clear (); model_coefficients.values.clear ();
98  return;
99  }
100 
101  // Get the model inliers
102  sac_->getInliers (inliers.indices);
103 
104  // Get the model coefficients
105  Eigen::VectorXf coeff;
106  sac_->getModelCoefficients (coeff);
107 
108  // If the user needs optimized coefficients
109  if (optimize_coefficients_)
110  {
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));
115  // Refine inliers
116  model_->selectWithinDistance (coeff_refined, threshold_, inliers.indices);
117  }
118  else
119  {
120  model_coefficients.values.resize (coeff.size ());
121  memcpy (&model_coefficients.values[0], &coeff[0], coeff.size () * sizeof (float));
122  }
123 
124  deinitCompute ();
125 }
126 
128 template <typename PointT> bool
129 pcl::SACSegmentation<PointT>::initSACModel (const int model_type)
130 {
131  if (model_)
132  model_.reset ();
133 
134  // Build the model
135  switch (model_type)
136  {
137  case SACMODEL_PLANE:
138  {
139  PCL_DEBUG ("[pcl::%s::initSACModel] Using a model of type: SACMODEL_PLANE\n", getClassName ().c_str ());
140  model_.reset (new SampleConsensusModelPlane<PointT> (input_, *indices_));
141  break;
142  }
143  case SACMODEL_LINE:
144  {
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_));
147  break;
148  }
149  case SACMODEL_STICK:
150  {
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)
156  {
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_);
159  }
160  break;
161  }
162  case SACMODEL_CIRCLE2D:
163  {
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)
170  {
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_);
173  }
174  break;
175  }
176  case SACMODEL_SPHERE:
177  {
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)
184  {
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_);
187  }
188  break;
189  }
191  {
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_)
196  {
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_);
199  }
200  if (eps_angle_ != 0.0 && model_parallel->getEpsAngle () != eps_angle_)
201  {
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_);
204  }
205  break;
206  }
208  {
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_)
213  {
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_);
216  }
217  if (eps_angle_ != 0.0 && model_perpendicular->getEpsAngle () != eps_angle_)
218  {
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_);
221  }
222  break;
223  }
225  {
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_)
230  {
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_);
233  }
234  if (eps_angle_ != 0.0 && model_parallel->getEpsAngle () != eps_angle_)
235  {
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_);
238  }
239  break;
240  }
241  default:
242  {
243  PCL_ERROR ("[pcl::%s::initSACModel] No valid model given!\n", getClassName ().c_str ());
244  return (false);
245  }
246  }
247 
248  if (samples_radius_ > 0. )
249  {
250  PCL_DEBUG ("[pcl::%s::initSAC] Setting the maximum distance to %f\n", getClassName ().c_str (), samples_radius_);
251  // Set maximum distance for radius search during random sampling
252  model_->setSamplesMaxDist(samples_radius_, samples_radius_search_);
253  }
254 
255  return (true);
256 }
257 
259 template <typename PointT> void
260 pcl::SACSegmentation<PointT>::initSAC (const int method_type)
261 {
262  if (sac_)
263  sac_.reset ();
264  // Build the sample consensus method
265  switch (method_type)
266  {
267  case SAC_RANSAC:
268  default:
269  {
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_));
272  break;
273  }
274  case SAC_LMEDS:
275  {
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_));
278  break;
279  }
280  case SAC_MSAC:
281  {
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_));
284  break;
285  }
286  case SAC_RRANSAC:
287  {
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_));
290  break;
291  }
292  case SAC_RMSAC:
293  {
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_));
296  break;
297  }
298  case SAC_MLESAC:
299  {
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_));
302  break;
303  }
304  case SAC_PROSAC:
305  {
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_));
308  break;
309  }
310  }
311  // Set the Sample Consensus parameters if they are given/changed
312  if (sac_->getProbability () != probability_)
313  {
314  PCL_DEBUG ("[pcl::%s::initSAC] Setting the desired probability to %f\n", getClassName ().c_str (), probability_);
315  sac_->setProbability (probability_);
316  }
317  if (max_iterations_ != -1 && sac_->getMaxIterations () != max_iterations_)
318  {
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_);
321  }
322 }
323 
325 template <typename PointT, typename PointNT> bool
327 {
328  if (!input_ || !normals_)
329  {
330  PCL_ERROR ("[pcl::%s::initSACModel] Input data (XYZ or normals) not given! Cannot continue.\n", getClassName ().c_str ());
331  return (false);
332  }
333  // Check if input is synced with the normals
334  if (input_->points.size () != normals_->points.size ())
335  {
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 ());
337  return (false);
338  }
339 
340  if (model_)
341  model_.reset ();
342 
343  // Build the model
344  switch (model_type)
345  {
346  case SACMODEL_CYLINDER:
347  {
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_);
351 
352  // Set the input normals
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)
357  {
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_);
360  }
361  if (distance_weight_ != model_cylinder->getNormalDistanceWeight ())
362  {
363  PCL_DEBUG ("[pcl::%s::initSACModel] Setting normal distance weight to %f\n", getClassName ().c_str (), distance_weight_);
364  model_cylinder->setNormalDistanceWeight (distance_weight_);
365  }
366  if (axis_ != Eigen::Vector3f::Zero () && model_cylinder->getAxis () != axis_)
367  {
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_);
370  }
371  if (eps_angle_ != 0.0 && model_cylinder->getEpsAngle () != eps_angle_)
372  {
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_);
375  }
376  break;
377  }
379  {
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_);
383  // Set the input normals
384  model_normals->setInputNormals (normals_);
385  if (distance_weight_ != model_normals->getNormalDistanceWeight ())
386  {
387  PCL_DEBUG ("[pcl::%s::initSACModel] Setting normal distance weight to %f\n", getClassName ().c_str (), distance_weight_);
388  model_normals->setNormalDistanceWeight (distance_weight_);
389  }
390  break;
391  }
393  {
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_);
397  // Set the input normals
398  model_normals->setInputNormals (normals_);
399  if (distance_weight_ != model_normals->getNormalDistanceWeight ())
400  {
401  PCL_DEBUG ("[pcl::%s::initSACModel] Setting normal distance weight to %f\n", getClassName ().c_str (), distance_weight_);
402  model_normals->setNormalDistanceWeight (distance_weight_);
403  }
404  if (distance_from_origin_ != model_normals->getDistanceFromOrigin ())
405  {
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_);
408  }
409  if (axis_ != Eigen::Vector3f::Zero () && model_normals->getAxis () != axis_)
410  {
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_);
413  }
414  if (eps_angle_ != 0.0 && model_normals->getEpsAngle () != eps_angle_)
415  {
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_);
418  }
419  break;
420  }
421  case SACMODEL_CONE:
422  {
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_);
426 
427  // Set the input normals
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)
432  {
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_);
435  }
436 
437  if (distance_weight_ != model_cone->getNormalDistanceWeight ())
438  {
439  PCL_DEBUG ("[pcl::%s::initSACModel] Setting normal distance weight to %f\n", getClassName ().c_str (), distance_weight_);
440  model_cone->setNormalDistanceWeight (distance_weight_);
441  }
442  if (axis_ != Eigen::Vector3f::Zero () && model_cone->getAxis () != axis_)
443  {
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_);
446  }
447  if (eps_angle_ != 0.0 && model_cone->getEpsAngle () != eps_angle_)
448  {
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_);
451  }
452  break;
453  }
455  {
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_);
459  // Set the input normals
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)
464  {
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_);
467  }
468 
469  if (distance_weight_ != model_normals_sphere->getNormalDistanceWeight ())
470  {
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_);
473  }
474  break;
475  }
476  // If nothing else, try SACSegmentation
477  default:
478  {
479  return (pcl::SACSegmentation<PointT>::initSACModel (model_type));
480  }
481  }
482 
483  if (SACSegmentation<PointT>::samples_radius_ > 0. )
484  {
485  PCL_DEBUG ("[pcl::%s::initSAC] Setting the maximum distance to %f\n", getClassName ().c_str (), SACSegmentation<PointT>::samples_radius_);
486  // Set maximum distance for radius search during random sampling
487  model_->setSamplesMaxDist(SACSegmentation<PointT>::samples_radius_, SACSegmentation<PointT>::samples_radius_search_);
488  }
489 
490  return (true);
491 }
492 
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>;
495 
496 #endif // PCL_SEGMENTATION_IMPL_SAC_SEGMENTATION_H_
497