Point Cloud Library (PCL)  1.9.0-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 #ifndef PCL_TRANSFORMS_H_
40 #define PCL_TRANSFORMS_H_
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  template <typename PointT> void
67  pcl::PointCloud<PointT> &cloud_out,
68  const Eigen::Affine3f &transform,
69  bool copy_all_fields = true)
70  {
71  return (transformPointCloud<PointT, float> (cloud_in, cloud_out, transform, copy_all_fields));
72  }
73 
74  /** \brief Apply an affine transform defined by an Eigen Transform
75  * \param[in] cloud_in the input point cloud
76  * \param[in] indices the set of point indices to use from the input point cloud
77  * \param[out] cloud_out the resultant output point cloud
78  * \param[in] transform an affine transformation (typically a rigid transformation)
79  * \param[in] copy_all_fields flag that controls whether the contents of the fields
80  * (other than x, y, z) should be copied into the new transformed cloud
81  * \ingroup common
82  */
83  template <typename PointT, typename Scalar> void
85  const std::vector<int> &indices,
86  pcl::PointCloud<PointT> &cloud_out,
87  const Eigen::Transform<Scalar, 3, Eigen::Affine> &transform,
88  bool copy_all_fields = true);
89 
90  template <typename PointT> void
92  const std::vector<int> &indices,
93  pcl::PointCloud<PointT> &cloud_out,
94  const Eigen::Affine3f &transform,
95  bool copy_all_fields = true)
96  {
97  return (transformPointCloud<PointT, float> (cloud_in, indices, cloud_out, transform, copy_all_fields));
98  }
99 
100  /** \brief Apply an affine transform defined by an Eigen Transform
101  * \param[in] cloud_in the input point cloud
102  * \param[in] indices the set of point indices to use from the input point cloud
103  * \param[out] cloud_out the resultant output point cloud
104  * \param[in] transform an affine transformation (typically a rigid transformation)
105  * \param[in] copy_all_fields flag that controls whether the contents of the fields
106  * (other than x, y, z) should be copied into the new transformed cloud
107  * \ingroup common
108  */
109  template <typename PointT, typename Scalar> void
111  const pcl::PointIndices &indices,
112  pcl::PointCloud<PointT> &cloud_out,
113  const Eigen::Transform<Scalar, 3, Eigen::Affine> &transform,
114  bool copy_all_fields = true)
115  {
116  return (transformPointCloud<PointT, Scalar> (cloud_in, indices.indices, cloud_out, transform, copy_all_fields));
117  }
118 
119  template <typename PointT> void
121  const pcl::PointIndices &indices,
122  pcl::PointCloud<PointT> &cloud_out,
123  const Eigen::Affine3f &transform,
124  bool copy_all_fields = true)
125  {
126  return (transformPointCloud<PointT, float> (cloud_in, indices, cloud_out, transform, copy_all_fields));
127  }
128 
129  /** \brief Transform a point cloud and rotate its normals using an Eigen transform.
130  * \param[in] cloud_in the input point cloud
131  * \param[out] cloud_out the resultant output point cloud
132  * \param[in] transform an affine transformation (typically a rigid transformation)
133  * \param[in] copy_all_fields flag that controls whether the contents of the fields
134  * (other than x, y, z, normal_x, normal_y, normal_z) should be copied into the new
135  * transformed cloud
136  * \note Can be used with cloud_in equal to cloud_out
137  */
138  template <typename PointT, typename Scalar> void
140  pcl::PointCloud<PointT> &cloud_out,
141  const Eigen::Transform<Scalar, 3, Eigen::Affine> &transform,
142  bool copy_all_fields = true);
143 
144  template <typename PointT> void
146  pcl::PointCloud<PointT> &cloud_out,
147  const Eigen::Affine3f &transform,
148  bool copy_all_fields = true)
149  {
150  return (transformPointCloudWithNormals<PointT, float> (cloud_in, cloud_out, transform, copy_all_fields));
151  }
152 
153  /** \brief Transform a point cloud and rotate its normals using an Eigen transform.
154  * \param[in] cloud_in the input point cloud
155  * \param[in] indices the set of point indices to use from the input point cloud
156  * \param[out] cloud_out the resultant output point cloud
157  * \param[in] transform an affine transformation (typically a rigid transformation)
158  * \param[in] copy_all_fields flag that controls whether the contents of the fields
159  * (other than x, y, z, normal_x, normal_y, normal_z) should be copied into the new
160  * transformed cloud
161  */
162  template <typename PointT, typename Scalar> void
164  const std::vector<int> &indices,
165  pcl::PointCloud<PointT> &cloud_out,
166  const Eigen::Transform<Scalar, 3, Eigen::Affine> &transform,
167  bool copy_all_fields = true);
168 
169  template <typename PointT> void
171  const std::vector<int> &indices,
172  pcl::PointCloud<PointT> &cloud_out,
173  const Eigen::Affine3f &transform,
174  bool copy_all_fields = true)
175  {
176  return (transformPointCloudWithNormals<PointT, float> (cloud_in, indices, cloud_out, transform, copy_all_fields));
177  }
178 
179  /** \brief Transform a point cloud and rotate its normals using an Eigen transform.
180  * \param[in] cloud_in the input point cloud
181  * \param[in] indices the set of point indices to use from the input point cloud
182  * \param[out] cloud_out the resultant output point cloud
183  * \param[in] transform an affine transformation (typically a rigid transformation)
184  * \param[in] copy_all_fields flag that controls whether the contents of the fields
185  * (other than x, y, z, normal_x, normal_y, normal_z) should be copied into the new
186  * transformed cloud
187  */
188  template <typename PointT, typename Scalar> void
190  const pcl::PointIndices &indices,
191  pcl::PointCloud<PointT> &cloud_out,
192  const Eigen::Transform<Scalar, 3, Eigen::Affine> &transform,
193  bool copy_all_fields = true)
194  {
195  return (transformPointCloudWithNormals<PointT, Scalar> (cloud_in, indices.indices, cloud_out, transform, copy_all_fields));
196  }
197 
198 
199  template <typename PointT> void
201  const pcl::PointIndices &indices,
202  pcl::PointCloud<PointT> &cloud_out,
203  const Eigen::Affine3f &transform,
204  bool copy_all_fields = true)
205  {
206  return (transformPointCloudWithNormals<PointT, float> (cloud_in, indices, cloud_out, transform, copy_all_fields));
207  }
208 
209  /** \brief Apply a rigid transform defined by a 4x4 matrix
210  * \param[in] cloud_in the input point cloud
211  * \param[out] cloud_out the resultant output point cloud
212  * \param[in] transform a rigid transformation
213  * \param[in] copy_all_fields flag that controls whether the contents of the fields
214  * (other than x, y, z) should be copied into the new transformed cloud
215  * \note Can be used with cloud_in equal to cloud_out
216  * \ingroup common
217  */
218  template <typename PointT, typename Scalar> void
220  pcl::PointCloud<PointT> &cloud_out,
221  const Eigen::Matrix<Scalar, 4, 4> &transform,
222  bool copy_all_fields = true)
223  {
224  Eigen::Transform<Scalar, 3, Eigen::Affine> t (transform);
225  return (transformPointCloud<PointT, Scalar> (cloud_in, cloud_out, t, copy_all_fields));
226  }
227 
228  template <typename PointT> void
230  pcl::PointCloud<PointT> &cloud_out,
231  const Eigen::Matrix4f &transform,
232  bool copy_all_fields = true)
233  {
234  return (transformPointCloud<PointT, float> (cloud_in, cloud_out, transform, copy_all_fields));
235  }
236 
237  /** \brief Apply a rigid transform defined by a 4x4 matrix
238  * \param[in] cloud_in the input point cloud
239  * \param[in] indices the set of point indices to use from the input point cloud
240  * \param[out] cloud_out the resultant output point cloud
241  * \param[in] transform a rigid transformation
242  * \param[in] copy_all_fields flag that controls whether the contents of the fields
243  * (other than x, y, z) should be copied into the new transformed cloud
244  * \ingroup common
245  */
246  template <typename PointT, typename Scalar> void
248  const std::vector<int> &indices,
249  pcl::PointCloud<PointT> &cloud_out,
250  const Eigen::Matrix<Scalar, 4, 4> &transform,
251  bool copy_all_fields = true)
252  {
253  Eigen::Transform<Scalar, 3, Eigen::Affine> t (transform);
254  return (transformPointCloud<PointT, Scalar> (cloud_in, indices, cloud_out, t, copy_all_fields));
255  }
256 
257  template <typename PointT> void
259  const std::vector<int> &indices,
260  pcl::PointCloud<PointT> &cloud_out,
261  const Eigen::Matrix4f &transform,
262  bool copy_all_fields = true)
263  {
264  return (transformPointCloud<PointT, float> (cloud_in, indices, cloud_out, transform, copy_all_fields));
265  }
266 
267  /** \brief Apply a rigid transform defined by a 4x4 matrix
268  * \param[in] cloud_in the input point cloud
269  * \param[in] indices the set of point indices to use from the input point cloud
270  * \param[out] cloud_out the resultant output point cloud
271  * \param[in] transform a rigid transformation
272  * \param[in] copy_all_fields flag that controls whether the contents of the fields
273  * (other than x, y, z) should be copied into the new transformed cloud
274  * \ingroup common
275  */
276  template <typename PointT, typename Scalar> void
278  const pcl::PointIndices &indices,
279  pcl::PointCloud<PointT> &cloud_out,
280  const Eigen::Matrix<Scalar, 4, 4> &transform,
281  bool copy_all_fields = true)
282  {
283  return (transformPointCloud<PointT, Scalar> (cloud_in, indices.indices, cloud_out, transform, copy_all_fields));
284  }
285 
286  template <typename PointT> void
288  const pcl::PointIndices &indices,
289  pcl::PointCloud<PointT> &cloud_out,
290  const Eigen::Matrix4f &transform,
291  bool copy_all_fields = true)
292  {
293  return (transformPointCloud<PointT, float> (cloud_in, indices, cloud_out, transform, copy_all_fields));
294  }
295 
296  /** \brief Transform a point cloud and rotate its normals using an Eigen transform.
297  * \param[in] cloud_in the input point cloud
298  * \param[out] cloud_out the resultant output point cloud
299  * \param[in] transform an affine transformation (typically a rigid transformation)
300  * \param[in] copy_all_fields flag that controls whether the contents of the fields
301  * (other than x, y, z, normal_x, normal_y, normal_z) should be copied into the new
302  * transformed cloud
303  * \note Can be used with cloud_in equal to cloud_out
304  * \ingroup common
305  */
306  template <typename PointT, typename Scalar> void
308  pcl::PointCloud<PointT> &cloud_out,
309  const Eigen::Matrix<Scalar, 4, 4> &transform,
310  bool copy_all_fields = true)
311  {
312  Eigen::Transform<Scalar, 3, Eigen::Affine> t (transform);
313  return (transformPointCloudWithNormals<PointT, Scalar> (cloud_in, cloud_out, t, copy_all_fields));
314  }
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 std::vector<int> &indices,
340  pcl::PointCloud<PointT> &cloud_out,
341  const Eigen::Matrix<Scalar, 4, 4> &transform,
342  bool copy_all_fields = true)
343  {
344  Eigen::Transform<Scalar, 3, Eigen::Affine> t (transform);
345  return (transformPointCloudWithNormals<PointT, Scalar> (cloud_in, indices, cloud_out, t, copy_all_fields));
346  }
347 
348 
349  template <typename PointT> void
351  const std::vector<int> &indices,
352  pcl::PointCloud<PointT> &cloud_out,
353  const Eigen::Matrix4f &transform,
354  bool copy_all_fields = true)
355  {
356  return (transformPointCloudWithNormals<PointT, float> (cloud_in, indices, cloud_out, transform, copy_all_fields));
357  }
358 
359  /** \brief Transform a point cloud and rotate its normals using an Eigen transform.
360  * \param[in] cloud_in the input point cloud
361  * \param[in] indices the set of point indices to use from the input point cloud
362  * \param[out] cloud_out the resultant output point cloud
363  * \param[in] transform an affine transformation (typically a rigid transformation)
364  * \param[in] copy_all_fields flag that controls whether the contents of the fields
365  * (other than x, y, z, normal_x, normal_y, normal_z) should be copied into the new
366  * transformed cloud
367  * \note Can be used with cloud_in equal to cloud_out
368  * \ingroup common
369  */
370  template <typename PointT, typename Scalar> void
372  const pcl::PointIndices &indices,
373  pcl::PointCloud<PointT> &cloud_out,
374  const Eigen::Matrix<Scalar, 4, 4> &transform,
375  bool copy_all_fields = true)
376  {
377  Eigen::Transform<Scalar, 3, Eigen::Affine> t (transform);
378  return (transformPointCloudWithNormals<PointT, Scalar> (cloud_in, indices, cloud_out, t, copy_all_fields));
379  }
380 
381 
382  template <typename PointT> void
384  const pcl::PointIndices &indices,
385  pcl::PointCloud<PointT> &cloud_out,
386  const Eigen::Matrix4f &transform,
387  bool copy_all_fields = true)
388  {
389  return (transformPointCloudWithNormals<PointT, float> (cloud_in, indices, cloud_out, transform, copy_all_fields));
390  }
391 
392  /** \brief Apply a rigid transform defined by a 3D offset and a quaternion
393  * \param[in] cloud_in the input point cloud
394  * \param[out] cloud_out the resultant output point cloud
395  * \param[in] offset the translation component of the rigid transformation
396  * \param[in] rotation the rotation component of the rigid transformation
397  * \param[in] copy_all_fields flag that controls whether the contents of the fields
398  * (other than x, y, z) should be copied into the new transformed cloud
399  * \ingroup common
400  */
401  template <typename PointT, typename Scalar> inline void
403  pcl::PointCloud<PointT> &cloud_out,
404  const Eigen::Matrix<Scalar, 3, 1> &offset,
405  const Eigen::Quaternion<Scalar> &rotation,
406  bool copy_all_fields = true);
407 
408  template <typename PointT> inline void
410  pcl::PointCloud<PointT> &cloud_out,
411  const Eigen::Vector3f &offset,
412  const Eigen::Quaternionf &rotation,
413  bool copy_all_fields = true)
414  {
415  return (transformPointCloud<PointT, float> (cloud_in, cloud_out, offset, rotation, copy_all_fields));
416  }
417 
418  /** \brief Transform a point cloud and rotate its normals using an Eigen transform.
419  * \param[in] cloud_in the input point cloud
420  * \param[out] cloud_out the resultant output point cloud
421  * \param[in] offset the translation component of the rigid transformation
422  * \param[in] rotation the rotation component of the rigid transformation
423  * \param[in] copy_all_fields flag that controls whether the contents of the fields
424  * (other than x, y, z, normal_x, normal_y, normal_z) should be copied into the new
425  * transformed cloud
426  * \ingroup common
427  */
428  template <typename PointT, typename Scalar> inline void
430  pcl::PointCloud<PointT> &cloud_out,
431  const Eigen::Matrix<Scalar, 3, 1> &offset,
432  const Eigen::Quaternion<Scalar> &rotation,
433  bool copy_all_fields = true);
434 
435  template <typename PointT> void
437  pcl::PointCloud<PointT> &cloud_out,
438  const Eigen::Vector3f &offset,
439  const Eigen::Quaternionf &rotation,
440  bool copy_all_fields = true)
441  {
442  return (transformPointCloudWithNormals<PointT, float> (cloud_in, cloud_out, offset, rotation, copy_all_fields));
443  }
444 
445  /** \brief Transform a point with members x,y,z
446  * \param[in] point the point to transform
447  * \param[out] transform the transformation to apply
448  * \return the transformed point
449  * \ingroup common
450  */
451  template <typename PointT, typename Scalar> inline PointT
452  transformPoint (const PointT &point,
453  const Eigen::Transform<Scalar, 3, Eigen::Affine> &transform);
454 
455  template <typename PointT> inline PointT
456  transformPoint (const PointT &point,
457  const Eigen::Affine3f &transform)
458  {
459  return (transformPoint<PointT, float> (point, transform));
460  }
461 
462  /** \brief Transform a point with members x,y,z,normal_x,normal_y,normal_z
463  * \param[in] point the point to transform
464  * \param[out] transform the transformation to apply
465  * \return the transformed point
466  * \ingroup common
467  */
468  template <typename PointT, typename Scalar> inline PointT
469  transformPointWithNormal (const PointT &point,
470  const Eigen::Transform<Scalar, 3, Eigen::Affine> &transform);
471 
472  template <typename PointT> inline PointT
474  const Eigen::Affine3f &transform)
475  {
476  return (transformPointWithNormal<PointT, float> (point, transform));
477  }
478 
479  /** \brief Calculates the principal (PCA-based) alignment of the point cloud
480  * \param[in] cloud the input point cloud
481  * \param[out] transform the resultant transform
482  * \return the ratio lambda1/lambda2 or lambda2/lambda3, whatever is closer to 1.
483  * \note If the return value is close to one then the transformation might be not unique -> two principal directions have
484  * almost same variance (extend)
485  */
486  template <typename PointT, typename Scalar> inline double
488  Eigen::Transform<Scalar, 3, Eigen::Affine> &transform);
489 
490  template <typename PointT> inline double
492  Eigen::Affine3f &transform)
493  {
494  return (getPrincipalTransformation<PointT, float> (cloud, transform));
495  }
496 }
497 
498 #include <pcl/common/impl/transforms.hpp>
499 
500 #endif // PCL_TRANSFORMS_H_
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:423
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
This file defines compatibility wrappers for low level I/O functions.
Definition: convolution.h:45
void transformPointCloudWithNormals(const pcl::PointCloud< PointT > &cloud_in, pcl::PointCloud< PointT > &cloud_out, const Eigen::Transform< Scalar, 3, Eigen::Affine > &transform, bool copy_all_fields=true)
Transform a point cloud and rotate its normals using an Eigen transform.
Definition: transforms.hpp:306
std::vector< int > indices
Definition: PointIndices.h:19
void transformPointCloud(const pcl::PointCloud< PointT > &cloud_in, pcl::PointCloud< PointT > &cloud_out, const Eigen::Transform< Scalar, 3, Eigen::Affine > &transform, bool copy_all_fields=true)
Apply an affine transform defined by an Eigen Transform.
Definition: transforms.hpp:215
PointCloud represents the base class in PCL for storing collections of 3D points. ...
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:444
A point structure representing Euclidean xyz coordinates, and the RGB color.