Point Cloud Library (PCL)  1.11.1-dev
transforms.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2010, Willow Garage, Inc.
6  * Copyright (c) 2012-, Open Perception, Inc.
7  *
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * * Redistributions of source code must retain the above copyright
15  * notice, this list of conditions and the following disclaimer.
16  * * Redistributions in binary form must reproduce the above
17  * copyright notice, this list of conditions and the following
18  * disclaimer in the documentation and/or other materials provided
19  * with the distribution.
20  * * Neither the name of the copyright holder(s) nor the names of its
21  * contributors may be used to endorse or promote products derived
22  * from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  *
37  *
38  */
39 
40 #pragma once
41 
42 #include <pcl/point_cloud.h>
43 #include <pcl/point_types.h>
44 #include <pcl/common/centroid.h>
45 #include <pcl/common/eigen.h>
46 #include <pcl/PointIndices.h>
47 
48 namespace pcl
49 {
50  /** \brief Apply an affine transform defined by an Eigen Transform
51  * \param[in] cloud_in the input point cloud
52  * \param[out] cloud_out the resultant output point cloud
53  * \param[in] transform an affine transformation (typically a rigid transformation)
54  * \param[in] copy_all_fields flag that controls whether the contents of the fields
55  * (other than x, y, z) should be copied into the new transformed cloud
56  * \note Can be used with cloud_in equal to cloud_out
57  * \ingroup common
58  */
59  template <typename PointT, typename Scalar> void
61  pcl::PointCloud<PointT> &cloud_out,
62  const Eigen::Transform<Scalar, 3, Eigen::Affine> &transform,
63  bool copy_all_fields = true)
64  {
65  return (transformPointCloud<PointT, Scalar> (cloud_in, cloud_out, transform.matrix (), copy_all_fields));
66  }
67 
68  template <typename PointT> void
70  pcl::PointCloud<PointT> &cloud_out,
71  const Eigen::Affine3f &transform,
72  bool copy_all_fields = true)
73  {
74  return (transformPointCloud<PointT, float> (cloud_in, cloud_out, transform.matrix (), copy_all_fields));
75  }
76 
77  /** \brief Apply an affine transform defined by an Eigen Transform
78  * \param[in] cloud_in the input point cloud
79  * \param[in] indices the set of point indices to use from the input point cloud
80  * \param[out] cloud_out the resultant output point cloud
81  * \param[in] transform an affine transformation (typically a rigid transformation)
82  * \param[in] copy_all_fields flag that controls whether the contents of the fields
83  * (other than x, y, z) should be copied into the new transformed cloud
84  * \ingroup common
85  */
86  template <typename PointT, typename Scalar> void
88  const Indices &indices,
89  pcl::PointCloud<PointT> &cloud_out,
90  const Eigen::Transform<Scalar, 3, Eigen::Affine> &transform,
91  bool copy_all_fields = true)
92  {
93  return (transformPointCloud<PointT, Scalar> (cloud_in, indices, cloud_out, transform.matrix (), copy_all_fields));
94  }
95 
96  template <typename PointT> void
98  const Indices &indices,
99  pcl::PointCloud<PointT> &cloud_out,
100  const Eigen::Affine3f &transform,
101  bool copy_all_fields = true)
102  {
103  return (transformPointCloud<PointT, float> (cloud_in, indices, cloud_out, transform.matrix (), copy_all_fields));
104  }
105 
106  /** \brief Apply an affine transform defined by an Eigen Transform
107  * \param[in] cloud_in the input point cloud
108  * \param[in] indices the set of point indices to use from the input point cloud
109  * \param[out] cloud_out the resultant output point cloud
110  * \param[in] transform an affine transformation (typically a rigid transformation)
111  * \param[in] copy_all_fields flag that controls whether the contents of the fields
112  * (other than x, y, z) should be copied into the new transformed cloud
113  * \ingroup common
114  */
115  template <typename PointT, typename Scalar> void
117  const pcl::PointIndices &indices,
118  pcl::PointCloud<PointT> &cloud_out,
119  const Eigen::Transform<Scalar, 3, Eigen::Affine> &transform,
120  bool copy_all_fields = true)
121  {
122  return (transformPointCloud<PointT, Scalar> (cloud_in, indices.indices, cloud_out, transform.matrix (), copy_all_fields));
123  }
124 
125  template <typename PointT> void
127  const pcl::PointIndices &indices,
128  pcl::PointCloud<PointT> &cloud_out,
129  const Eigen::Affine3f &transform,
130  bool copy_all_fields = true)
131  {
132  return (transformPointCloud<PointT, float> (cloud_in, indices.indices, cloud_out, transform.matrix (), copy_all_fields));
133  }
134 
135  /** \brief Transform a point cloud and rotate its normals using an Eigen transform.
136  * \param[in] cloud_in the input point cloud
137  * \param[out] cloud_out the resultant output point cloud
138  * \param[in] transform an affine transformation (typically a rigid transformation)
139  * \param[in] copy_all_fields flag that controls whether the contents of the fields
140  * (other than x, y, z, normal_x, normal_y, normal_z) should be copied into the new
141  * transformed cloud
142  * \note Can be used with cloud_in equal to cloud_out
143  */
144  template <typename PointT, typename Scalar> void
146  pcl::PointCloud<PointT> &cloud_out,
147  const Eigen::Transform<Scalar, 3, Eigen::Affine> &transform,
148  bool copy_all_fields = true)
149  {
150  return (transformPointCloudWithNormals<PointT, Scalar> (cloud_in, cloud_out, transform.matrix (), copy_all_fields));
151  }
152 
153  template <typename PointT> void
155  pcl::PointCloud<PointT> &cloud_out,
156  const Eigen::Affine3f &transform,
157  bool copy_all_fields = true)
158  {
159  return (transformPointCloudWithNormals<PointT, float> (cloud_in, cloud_out, transform.matrix (), copy_all_fields));
160  }
161 
162  /** \brief Transform a point cloud and rotate its normals using an Eigen transform.
163  * \param[in] cloud_in the input point cloud
164  * \param[in] indices the set of point indices to use from the input point cloud
165  * \param[out] cloud_out the resultant output point cloud
166  * \param[in] transform an affine transformation (typically a rigid transformation)
167  * \param[in] copy_all_fields flag that controls whether the contents of the fields
168  * (other than x, y, z, normal_x, normal_y, normal_z) should be copied into the new
169  * transformed cloud
170  */
171  template <typename PointT, typename Scalar> void
173  const Indices &indices,
174  pcl::PointCloud<PointT> &cloud_out,
175  const Eigen::Transform<Scalar, 3, Eigen::Affine> &transform,
176  bool copy_all_fields = true)
177  {
178  return (transformPointCloudWithNormals<PointT, Scalar> (cloud_in, indices, cloud_out, transform.matrix (), copy_all_fields));
179  }
180 
181  template <typename PointT> void
183  const Indices &indices,
184  pcl::PointCloud<PointT> &cloud_out,
185  const Eigen::Affine3f &transform,
186  bool copy_all_fields = true)
187  {
188  return (transformPointCloudWithNormals<PointT, float> (cloud_in, indices, cloud_out, transform.matrix (), copy_all_fields));
189  }
190 
191  /** \brief Transform a point cloud and rotate its normals using an Eigen transform.
192  * \param[in] cloud_in the input point cloud
193  * \param[in] indices the set of point indices to use from the input point cloud
194  * \param[out] cloud_out the resultant output point cloud
195  * \param[in] transform an affine transformation (typically a rigid transformation)
196  * \param[in] copy_all_fields flag that controls whether the contents of the fields
197  * (other than x, y, z, normal_x, normal_y, normal_z) should be copied into the new
198  * transformed cloud
199  */
200  template <typename PointT, typename Scalar> void
202  const pcl::PointIndices &indices,
203  pcl::PointCloud<PointT> &cloud_out,
204  const Eigen::Transform<Scalar, 3, Eigen::Affine> &transform,
205  bool copy_all_fields = true)
206  {
207  return (transformPointCloudWithNormals<PointT, Scalar> (cloud_in, indices.indices, cloud_out, transform.matrix (), copy_all_fields));
208  }
209 
210 
211  template <typename PointT> void
213  const pcl::PointIndices &indices,
214  pcl::PointCloud<PointT> &cloud_out,
215  const Eigen::Affine3f &transform,
216  bool copy_all_fields = true)
217  {
218  return (transformPointCloudWithNormals<PointT, float> (cloud_in, indices.indices, cloud_out, transform.matrix (), copy_all_fields));
219  }
220 
221  /** \brief Apply a rigid transform defined by a 4x4 matrix
222  * \param[in] cloud_in the input point cloud
223  * \param[out] cloud_out the resultant output point cloud
224  * \param[in] transform a rigid transformation
225  * \param[in] copy_all_fields flag that controls whether the contents of the fields
226  * (other than x, y, z) should be copied into the new transformed cloud
227  * \note Can be used with cloud_in equal to cloud_out
228  * \ingroup common
229  */
230  template <typename PointT, typename Scalar> void
232  pcl::PointCloud<PointT> &cloud_out,
233  const Eigen::Matrix<Scalar, 4, 4> &transform,
234  bool copy_all_fields = true);
235 
236  template <typename PointT> void
238  pcl::PointCloud<PointT> &cloud_out,
239  const Eigen::Matrix4f &transform,
240  bool copy_all_fields = true)
241  {
242  return (transformPointCloud<PointT, float> (cloud_in, cloud_out, transform, copy_all_fields));
243  }
244 
245  /** \brief Apply a rigid transform defined by a 4x4 matrix
246  * \param[in] cloud_in the input point cloud
247  * \param[in] indices the set of point indices to use from the input point cloud
248  * \param[out] cloud_out the resultant output point cloud
249  * \param[in] transform a rigid transformation
250  * \param[in] copy_all_fields flag that controls whether the contents of the fields
251  * (other than x, y, z) should be copied into the new transformed cloud
252  * \ingroup common
253  */
254  template <typename PointT, typename Scalar> void
256  const Indices &indices,
257  pcl::PointCloud<PointT> &cloud_out,
258  const Eigen::Matrix<Scalar, 4, 4> &transform,
259  bool copy_all_fields = true);
260 
261  template <typename PointT> void
263  const Indices &indices,
264  pcl::PointCloud<PointT> &cloud_out,
265  const Eigen::Matrix4f &transform,
266  bool copy_all_fields = true)
267  {
268  return (transformPointCloud<PointT, float> (cloud_in, indices, cloud_out, transform, copy_all_fields));
269  }
270 
271  /** \brief Apply a rigid transform defined by a 4x4 matrix
272  * \param[in] cloud_in the input point cloud
273  * \param[in] indices the set of point indices to use from the input point cloud
274  * \param[out] cloud_out the resultant output point cloud
275  * \param[in] transform a rigid transformation
276  * \param[in] copy_all_fields flag that controls whether the contents of the fields
277  * (other than x, y, z) should be copied into the new transformed cloud
278  * \ingroup common
279  */
280  template <typename PointT, typename Scalar> void
282  const pcl::PointIndices &indices,
283  pcl::PointCloud<PointT> &cloud_out,
284  const Eigen::Matrix<Scalar, 4, 4> &transform,
285  bool copy_all_fields = true)
286  {
287  return (transformPointCloud<PointT, Scalar> (cloud_in, indices.indices, cloud_out, transform, copy_all_fields));
288  }
289 
290  template <typename PointT> void
292  const pcl::PointIndices &indices,
293  pcl::PointCloud<PointT> &cloud_out,
294  const Eigen::Matrix4f &transform,
295  bool copy_all_fields = true)
296  {
297  return (transformPointCloud<PointT, float> (cloud_in, indices, cloud_out, transform, copy_all_fields));
298  }
299 
300  /** \brief Transform a point cloud and rotate its normals using an Eigen transform.
301  * \param[in] cloud_in the input point cloud
302  * \param[out] cloud_out the resultant output point cloud
303  * \param[in] transform an affine transformation (typically a rigid transformation)
304  * \param[in] copy_all_fields flag that controls whether the contents of the fields
305  * (other than x, y, z, normal_x, normal_y, normal_z) should be copied into the new
306  * transformed cloud
307  * \note Can be used with cloud_in equal to cloud_out
308  * \ingroup common
309  */
310  template <typename PointT, typename Scalar> void
312  pcl::PointCloud<PointT> &cloud_out,
313  const Eigen::Matrix<Scalar, 4, 4> &transform,
314  bool copy_all_fields = true);
315 
316 
317  template <typename PointT> void
319  pcl::PointCloud<PointT> &cloud_out,
320  const Eigen::Matrix4f &transform,
321  bool copy_all_fields = true)
322  {
323  return (transformPointCloudWithNormals<PointT, float> (cloud_in, cloud_out, transform, copy_all_fields));
324  }
325 
326  /** \brief Transform a point cloud and rotate its normals using an Eigen transform.
327  * \param[in] cloud_in the input point cloud
328  * \param[in] indices the set of point indices to use from the input point cloud
329  * \param[out] cloud_out the resultant output point cloud
330  * \param[in] transform an affine transformation (typically a rigid transformation)
331  * \param[in] copy_all_fields flag that controls whether the contents of the fields
332  * (other than x, y, z, normal_x, normal_y, normal_z) should be copied into the new
333  * transformed cloud
334  * \note Can be used with cloud_in equal to cloud_out
335  * \ingroup common
336  */
337  template <typename PointT, typename Scalar> void
339  const Indices &indices,
340  pcl::PointCloud<PointT> &cloud_out,
341  const Eigen::Matrix<Scalar, 4, 4> &transform,
342  bool copy_all_fields = true);
343 
344 
345  template <typename PointT> void
347  const Indices &indices,
348  pcl::PointCloud<PointT> &cloud_out,
349  const Eigen::Matrix4f &transform,
350  bool copy_all_fields = true)
351  {
352  return (transformPointCloudWithNormals<PointT, float> (cloud_in, indices, cloud_out, transform, copy_all_fields));
353  }
354 
355  /** \brief Transform a point cloud and rotate its normals using an Eigen transform.
356  * \param[in] cloud_in the input point cloud
357  * \param[in] indices the set of point indices to use from the input point cloud
358  * \param[out] cloud_out the resultant output point cloud
359  * \param[in] transform an affine transformation (typically a rigid transformation)
360  * \param[in] copy_all_fields flag that controls whether the contents of the fields
361  * (other than x, y, z, normal_x, normal_y, normal_z) should be copied into the new
362  * transformed cloud
363  * \note Can be used with cloud_in equal to cloud_out
364  * \ingroup common
365  */
366  template <typename PointT, typename Scalar> void
368  const pcl::PointIndices &indices,
369  pcl::PointCloud<PointT> &cloud_out,
370  const Eigen::Matrix<Scalar, 4, 4> &transform,
371  bool copy_all_fields = true)
372  {
373  return (transformPointCloudWithNormals<PointT, Scalar> (cloud_in, indices.indices, cloud_out, transform, copy_all_fields));
374  }
375 
376 
377  template <typename PointT> void
379  const pcl::PointIndices &indices,
380  pcl::PointCloud<PointT> &cloud_out,
381  const Eigen::Matrix4f &transform,
382  bool copy_all_fields = true)
383  {
384  return (transformPointCloudWithNormals<PointT, float> (cloud_in, indices.indices, cloud_out, transform, copy_all_fields));
385  }
386 
387  /** \brief Apply a rigid transform defined by a 3D offset and a quaternion
388  * \param[in] cloud_in the input point cloud
389  * \param[out] cloud_out the resultant output point cloud
390  * \param[in] offset the translation component of the rigid transformation
391  * \param[in] rotation the rotation component of the rigid transformation
392  * \param[in] copy_all_fields flag that controls whether the contents of the fields
393  * (other than x, y, z) should be copied into the new transformed cloud
394  * \ingroup common
395  */
396  template <typename PointT, typename Scalar> inline void
398  pcl::PointCloud<PointT> &cloud_out,
399  const Eigen::Matrix<Scalar, 3, 1> &offset,
400  const Eigen::Quaternion<Scalar> &rotation,
401  bool copy_all_fields = true);
402 
403  template <typename PointT> inline void
405  pcl::PointCloud<PointT> &cloud_out,
406  const Eigen::Vector3f &offset,
407  const Eigen::Quaternionf &rotation,
408  bool copy_all_fields = true)
409  {
410  return (transformPointCloud<PointT, float> (cloud_in, cloud_out, offset, rotation, copy_all_fields));
411  }
412 
413  /** \brief Transform a point cloud and rotate its normals using an Eigen transform.
414  * \param[in] cloud_in the input point cloud
415  * \param[out] cloud_out the resultant output point cloud
416  * \param[in] offset the translation component of the rigid transformation
417  * \param[in] rotation the rotation component of the rigid transformation
418  * \param[in] copy_all_fields flag that controls whether the contents of the fields
419  * (other than x, y, z, normal_x, normal_y, normal_z) should be copied into the new
420  * transformed cloud
421  * \ingroup common
422  */
423  template <typename PointT, typename Scalar> inline void
425  pcl::PointCloud<PointT> &cloud_out,
426  const Eigen::Matrix<Scalar, 3, 1> &offset,
427  const Eigen::Quaternion<Scalar> &rotation,
428  bool copy_all_fields = true);
429 
430  template <typename PointT> void
432  pcl::PointCloud<PointT> &cloud_out,
433  const Eigen::Vector3f &offset,
434  const Eigen::Quaternionf &rotation,
435  bool copy_all_fields = true)
436  {
437  return (transformPointCloudWithNormals<PointT, float> (cloud_in, cloud_out, offset, rotation, copy_all_fields));
438  }
439 
440  /** \brief Transform a point with members x,y,z
441  * \param[in] point the point to transform
442  * \param[out] transform the transformation to apply
443  * \return the transformed point
444  * \ingroup common
445  */
446  template <typename PointT, typename Scalar> inline PointT
447  transformPoint (const PointT &point,
448  const Eigen::Transform<Scalar, 3, Eigen::Affine> &transform);
449 
450  template <typename PointT> inline PointT
451  transformPoint (const PointT &point,
452  const Eigen::Affine3f &transform)
453  {
454  return (transformPoint<PointT, float> (point, transform));
455  }
456 
457  /** \brief Transform a point with members x,y,z,normal_x,normal_y,normal_z
458  * \param[in] point the point to transform
459  * \param[out] transform the transformation to apply
460  * \return the transformed point
461  * \ingroup common
462  */
463  template <typename PointT, typename Scalar> inline PointT
464  transformPointWithNormal (const PointT &point,
465  const Eigen::Transform<Scalar, 3, Eigen::Affine> &transform);
466 
467  template <typename PointT> inline PointT
469  const Eigen::Affine3f &transform)
470  {
471  return (transformPointWithNormal<PointT, float> (point, transform));
472  }
473 
474  /** \brief Calculates the principal (PCA-based) alignment of the point cloud
475  * \param[in] cloud the input point cloud
476  * \param[out] transform the resultant transform
477  * \return the ratio lambda1/lambda2 or lambda2/lambda3, whatever is closer to 1.
478  * \note If the return value is close to one then the transformation might be not unique -> two principal directions have
479  * almost same variance (extend)
480  */
481  template <typename PointT, typename Scalar> inline double
483  Eigen::Transform<Scalar, 3, Eigen::Affine> &transform);
484 
485  template <typename PointT> inline double
487  Eigen::Affine3f &transform)
488  {
489  return (getPrincipalTransformation<PointT, float> (cloud, transform));
490  }
491 }
492 
493 #include <pcl/common/impl/transforms.hpp>
pcl
Definition: convolution.h:46
point_types.h
pcl::PointIndices::indices
Indices indices
Definition: PointIndices.h:21
pcl::PointCloud
PointCloud represents the base class in PCL for storing collections of 3D points.
Definition: distances.h:55
pcl::PointXYZRGB
A point structure representing Euclidean xyz coordinates, and the RGB color.
Definition: point_types.hpp:630
pcl::transformPointCloud
void transformPointCloud(const pcl::PointCloud< PointT > &cloud_in, pcl::PointCloud< PointT > &cloud_out, const Eigen::Matrix< Scalar, 4, 4 > &transform, bool copy_all_fields)
Apply a rigid transform defined by a 4x4 matrix.
Definition: transforms.hpp:221
pcl::transformPointCloudWithNormals
void transformPointCloudWithNormals(const pcl::PointCloud< PointT > &cloud_in, pcl::PointCloud< PointT > &cloud_out, const Eigen::Matrix< Scalar, 4, 4 > &transform, bool copy_all_fields)
Transform a point cloud and rotate its normals using an Eigen transform.
Definition: transforms.hpp:310
pcl::PointIndices
Definition: PointIndices.h:11
pcl::Indices
IndicesAllocator<> Indices
Type used for indices in PCL.
Definition: types.h:133
pcl::transformPointWithNormal
PointT transformPointWithNormal(const PointT &point, const Eigen::Transform< Scalar, 3, Eigen::Affine > &transform)
Transform a point with members x,y,z,normal_x,normal_y,normal_z.
Definition: transforms.hpp:445
pcl::getPrincipalTransformation
double getPrincipalTransformation(const pcl::PointCloud< PointT > &cloud, Eigen::Transform< Scalar, 3, Eigen::Affine > &transform)
Calculates the principal (PCA-based) alignment of the point cloud.
Definition: transforms.hpp:456
pcl::transformPoint
void transformPoint(const Eigen::Matrix< Scalar, 3, 1 > &point_in, Eigen::Matrix< Scalar, 3, 1 > &point_out, const Eigen::Transform< Scalar, 3, Eigen::Affine > &transformation)
Transform a point using an affine matrix.
Definition: eigen.h:417
centroid.h