Point Cloud Library (PCL)  1.6.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sac_model_cone.h
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2009-2012, Willow Garage, Inc.
6  *
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * * Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  * * Neither the name of Willow Garage, Inc. nor the names of its
20  * contributors may be used to endorse or promote products derived
21  * from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  *
36  */
37 
38 #ifndef PCL_SAMPLE_CONSENSUS_MODEL_CONE_H_
39 #define PCL_SAMPLE_CONSENSUS_MODEL_CONE_H_
40 
43 #include <boost/thread/mutex.hpp>
44 #include <pcl/common/common.h>
45 #include <pcl/common/distances.h>
46 #include <limits.h>
47 
48 namespace pcl
49 {
51 
65  template <typename PointT, typename PointNT>
66  class SampleConsensusModelCone : public SampleConsensusModel<PointT>, public SampleConsensusModelFromNormals<PointT, PointNT>
67  {
74 
75  public:
79 
80  typedef boost::shared_ptr<SampleConsensusModelCone> Ptr;
81 
86  SampleConsensusModel<PointT> (cloud), axis_ (Eigen::Vector3f::Zero ()), eps_angle_ (0), min_angle_ (-std::numeric_limits<double>::max()), max_angle_ (std::numeric_limits<double>::max()),
87  tmp_inliers_ ()
88  {
89  }
90 
95  SampleConsensusModelCone (const PointCloudConstPtr &cloud, const std::vector<int> &indices) :
96  SampleConsensusModel<PointT> (cloud, indices),
97  axis_ (Eigen::Vector3f::Zero ()), eps_angle_ (0), min_angle_ (-std::numeric_limits<double>::max()), max_angle_ (std::numeric_limits<double>::max()),
98  tmp_inliers_ ()
99  {
100  }
101 
106  SampleConsensusModel<PointT> (), axis_ (), eps_angle_ (), min_angle_ (), max_angle_ (), tmp_inliers_ ()
107  {
108  *this = source;
109  }
110 
116  {
118  axis_ = source.axis_;
119  eps_angle_ = source.eps_angle_;
120  min_angle_ = source.min_angle_;
121  max_angle_ = source.max_angle_;
122  tmp_inliers_ = source.tmp_inliers_;
123  return (*this);
124  }
125 
129  inline void
130  setEpsAngle (double ea) { eps_angle_ = ea; }
131 
133  inline double
134  getEpsAngle () const { return (eps_angle_); }
135 
139  inline void
140  setAxis (const Eigen::Vector3f &ax) { axis_ = ax; }
141 
143  inline Eigen::Vector3f
144  getAxis () const { return (axis_); }
145 
151  inline void
152  setMinMaxOpeningAngle (const double &min_angle, const double &max_angle)
153  {
154  min_angle_ = min_angle;
155  max_angle_ = max_angle;
156  }
157 
162  inline void
163  getMinMaxOpeningAngle (double &min_angle, double &max_angle) const
164  {
165  min_angle = min_angle_;
166  max_angle = max_angle_;
167  }
168 
175  bool
176  computeModelCoefficients (const std::vector<int> &samples,
177  Eigen::VectorXf &model_coefficients);
178 
183  void
184  getDistancesToModel (const Eigen::VectorXf &model_coefficients,
185  std::vector<double> &distances);
186 
192  void
193  selectWithinDistance (const Eigen::VectorXf &model_coefficients,
194  const double threshold,
195  std::vector<int> &inliers);
196 
203  virtual int
204  countWithinDistance (const Eigen::VectorXf &model_coefficients,
205  const double threshold);
206 
207 
214  void
215  optimizeModelCoefficients (const std::vector<int> &inliers,
216  const Eigen::VectorXf &model_coefficients,
217  Eigen::VectorXf &optimized_coefficients);
218 
219 
226  void
227  projectPoints (const std::vector<int> &inliers,
228  const Eigen::VectorXf &model_coefficients,
229  PointCloud &projected_points,
230  bool copy_data_fields = true);
231 
237  bool
238  doSamplesVerifyModel (const std::set<int> &indices,
239  const Eigen::VectorXf &model_coefficients,
240  const double threshold);
241 
243  inline pcl::SacModel
244  getModelType () const { return (SACMODEL_CONE); }
245 
246  protected:
251  double
252  pointToAxisDistance (const Eigen::Vector4f &pt, const Eigen::VectorXf &model_coefficients);
253 
255  std::string
256  getName () const { return ("SampleConsensusModelCone"); }
257 
258  protected:
262  bool
263  isModelValid (const Eigen::VectorXf &model_coefficients);
264 
269  bool
270  isSampleGood (const std::vector<int> &samples) const;
271 
272  private:
274  Eigen::Vector3f axis_;
275 
277  double eps_angle_;
278 
280  double min_angle_;
281  double max_angle_;
282 
284  const std::vector<int> *tmp_inliers_;
285 
286 #if defined BUILD_Maintainer && defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ > 3
287 #pragma GCC diagnostic ignored "-Weffc++"
288 #endif
289 
290  struct OptimizationFunctor : pcl::Functor<float>
291  {
297  OptimizationFunctor (int m_data_points, pcl::SampleConsensusModelCone<PointT, PointNT> *model) :
298  pcl::Functor<float> (m_data_points), model_ (model) {}
299 
305  int
306  operator() (const Eigen::VectorXf &x, Eigen::VectorXf &fvec) const
307  {
308  Eigen::Vector4f apex (x[0], x[1], x[2], 0);
309  Eigen::Vector4f axis_dir (x[3], x[4], x[5], 0);
310  float opening_angle = x[6];
311 
312  float apexdotdir = apex.dot (axis_dir);
313  float dirdotdir = 1.0f / axis_dir.dot (axis_dir);
314 
315  for (int i = 0; i < values (); ++i)
316  {
317  // dist = f - r
318  Eigen::Vector4f pt (model_->input_->points[(*model_->tmp_inliers_)[i]].x,
319  model_->input_->points[(*model_->tmp_inliers_)[i]].y,
320  model_->input_->points[(*model_->tmp_inliers_)[i]].z, 0);
321 
322  // Calculate the point's projection on the cone axis
323  float k = (pt.dot (axis_dir) - apexdotdir) * dirdotdir;
324  Eigen::Vector4f pt_proj = apex + k * axis_dir;
325 
326  // Calculate the actual radius of the cone at the level of the projected point
327  Eigen::Vector4f height = apex-pt_proj;
328  float actual_cone_radius = tanf (opening_angle) * height.norm ();
329 
330  fvec[i] = static_cast<float> (pcl::sqrPointToLineDistance (pt, apex, axis_dir) - actual_cone_radius * actual_cone_radius);
331  }
332  return (0);
333  }
334 
336  };
337 #if defined BUILD_Maintainer && defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ > 3
338 #pragma GCC diagnostic warning "-Weffc++"
339 #endif
340  };
341 }
342 
343 #endif //#ifndef PCL_SAMPLE_CONSENSUS_MODEL_CONE_H_