Point Cloud Library (PCL)  1.6.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
normal_3d.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) 2010-2011, 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  * $Id: normal_3d.h 6144 2012-07-04 22:06:28Z rusu $
37  *
38  */
39 
40 #ifndef PCL_NORMAL_3D_H_
41 #define PCL_NORMAL_3D_H_
42 
43 #include <pcl/features/feature.h>
44 
45 namespace pcl
46 {
57  template <typename PointT> inline void
59  Eigen::Vector4f &plane_parameters, float &curvature)
60  {
61  // Placeholder for the 3x3 covariance matrix at each surface patch
62  EIGEN_ALIGN16 Eigen::Matrix3f covariance_matrix;
63  // 16-bytes aligned placeholder for the XYZ centroid of a surface patch
64  Eigen::Vector4f xyz_centroid;
65 
66  if (computeMeanAndCovarianceMatrix (cloud, covariance_matrix, xyz_centroid) == 0)
67  {
68  plane_parameters.setConstant (std::numeric_limits<float>::quiet_NaN ());
69  curvature = std::numeric_limits<float>::quiet_NaN ();
70  return;
71  }
72 
73  // Get the plane normal and surface curvature
74  solvePlaneParameters (covariance_matrix, xyz_centroid, plane_parameters, curvature);
75  }
76 
88  template <typename PointT> inline void
89  computePointNormal (const pcl::PointCloud<PointT> &cloud, const std::vector<int> &indices,
90  Eigen::Vector4f &plane_parameters, float &curvature)
91  {
92  // Placeholder for the 3x3 covariance matrix at each surface patch
93  EIGEN_ALIGN16 Eigen::Matrix3f covariance_matrix;
94  // 16-bytes aligned placeholder for the XYZ centroid of a surface patch
95  Eigen::Vector4f xyz_centroid;
96  if (computeMeanAndCovarianceMatrix (cloud, indices, covariance_matrix, xyz_centroid) == 0)
97  {
98  plane_parameters.setConstant (std::numeric_limits<float>::quiet_NaN ());
99  curvature = std::numeric_limits<float>::quiet_NaN ();
100  return;
101  }
102  // Get the plane normal and surface curvature
103  solvePlaneParameters (covariance_matrix, xyz_centroid, plane_parameters, curvature);
104  }
105 
114  template <typename PointT, typename Scalar> inline void
115  flipNormalTowardsViewpoint (const PointT &point, float vp_x, float vp_y, float vp_z,
116  Eigen::Matrix<Scalar, 4, 1>& normal)
117  {
118  Eigen::Matrix <Scalar, 4, 1> vp (vp_x - point.x, vp_y - point.x, vp_z - point.z, 0);
119 
120  // Dot product between the (viewpoint - point) and the plane normal
121  float cos_theta = vp.dot (normal);
122 
123  // Flip the plane normal
124  if (cos_theta < 0)
125  {
126  normal *= -1;
127  normal[3] = 0.0f;
128  // Hessian form (D = nc . p_plane (centroid here) + p)
129  normal[3] = -1 * normal.dot (point.getVector4fMap ());
130  }
131  }
132 
141  template <typename PointT, typename Scalar> inline void
142  flipNormalTowardsViewpoint (const PointT &point, float vp_x, float vp_y, float vp_z,
143  Eigen::Matrix<Scalar, 3, 1>& normal)
144  {
145  Eigen::Matrix <Scalar, 3, 1> vp (vp_x - point.x, vp_y - point.x, vp_z - point.z);
146 
147  // Flip the plane normal
148  if (vp.dot (normal) < 0)
149  normal *= -1;
150  }
151 
162  template <typename PointT> inline void
163  flipNormalTowardsViewpoint (const PointT &point, float vp_x, float vp_y, float vp_z,
164  float &nx, float &ny, float &nz)
165  {
166  // See if we need to flip any plane normals
167  vp_x -= point.x;
168  vp_y -= point.y;
169  vp_z -= point.z;
170 
171  // Dot product between the (viewpoint - point) and the plane normal
172  float cos_theta = (vp_x * nx + vp_y * ny + vp_z * nz);
173 
174  // Flip the plane normal
175  if (cos_theta < 0)
176  {
177  nx *= -1;
178  ny *= -1;
179  nz *= -1;
180  }
181  }
182 
192  template <typename PointInT, typename PointOutT>
193  class NormalEstimation: public Feature<PointInT, PointOutT>
194  {
195  public:
204 
207 
210  : vpx_ (0)
211  , vpy_ (0)
212  , vpz_ (0)
213  , covariance_matrix_ ()
214  , xyz_centroid_ ()
215  , use_sensor_origin_ (true)
216  {
217  feature_name_ = "NormalEstimation";
218  };
219 
230  inline void
231  computePointNormal (const pcl::PointCloud<PointInT> &cloud, const std::vector<int> &indices, Eigen::Vector4f &plane_parameters, float &curvature)
232  {
233  if (computeMeanAndCovarianceMatrix (cloud, indices, covariance_matrix_, xyz_centroid_) == 0)
234  {
235  plane_parameters.setConstant (std::numeric_limits<float>::quiet_NaN ());
236  curvature = std::numeric_limits<float>::quiet_NaN ();
237  return;
238  }
239 
240  // Get the plane normal and surface curvature
241  solvePlaneParameters (covariance_matrix_, xyz_centroid_, plane_parameters, curvature);
242  }
243 
256  inline void
257  computePointNormal (const pcl::PointCloud<PointInT> &cloud, const std::vector<int> &indices, float &nx, float &ny, float &nz, float &curvature)
258  {
259  if (computeMeanAndCovarianceMatrix (cloud, indices, covariance_matrix_, xyz_centroid_) == 0)
260  {
261  nx = ny = nz = curvature = std::numeric_limits<float>::quiet_NaN ();
262  return;
263  }
264 
265  // Get the plane normal and surface curvature
266  solvePlaneParameters (covariance_matrix_, nx, ny, nz, curvature);
267  }
268 
272  virtual inline void
274  {
275  input_ = cloud;
276  if (use_sensor_origin_)
277  {
278  vpx_ = input_->sensor_origin_.coeff (0);
279  vpy_ = input_->sensor_origin_.coeff (1);
280  vpz_ = input_->sensor_origin_.coeff (2);
281  }
282  }
283 
289  inline void
290  setViewPoint (float vpx, float vpy, float vpz)
291  {
292  vpx_ = vpx;
293  vpy_ = vpy;
294  vpz_ = vpz;
295  use_sensor_origin_ = false;
296  }
297 
306  inline void
307  getViewPoint (float &vpx, float &vpy, float &vpz)
308  {
309  vpx = vpx_;
310  vpy = vpy_;
311  vpz = vpz_;
312  }
313 
318  inline void
320  {
321  use_sensor_origin_ = true;
322  if (input_)
323  {
324  vpx_ = input_->sensor_origin_.coeff (0);
325  vpy_ = input_->sensor_origin_.coeff (1);
326  vpz_ = input_->sensor_origin_.coeff (2);
327  }
328  else
329  {
330  vpx_ = 0;
331  vpy_ = 0;
332  vpz_ = 0;
333  }
334  }
335 
336  protected:
342  void
343  computeFeature (PointCloudOut &output);
344 
347  float vpx_, vpy_, vpz_;
348 
350  EIGEN_ALIGN16 Eigen::Matrix3f covariance_matrix_;
351 
353  Eigen::Vector4f xyz_centroid_;
354 
356  bool use_sensor_origin_;
357 
358  private:
362  void
363  computeFeatureEigen (pcl::PointCloud<Eigen::MatrixXf> &) {}
364  };
365 
374  template <typename PointInT>
375  class NormalEstimation<PointInT, Eigen::MatrixXf>: public NormalEstimation<PointInT, pcl::Normal>
376  {
377  public:
388 
389  private:
395  void
396  computeFeatureEigen (pcl::PointCloud<Eigen::MatrixXf> &output);
397 
401  void
403  };
404 }
405 
406 #endif //#ifndef PCL_NORMAL_3D_H_
407 
408