Point Cloud Library (PCL) 1.12.0
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
48namespace 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>
Define methods for centroid estimation and covariance matrix calculus.
PointCloud represents the base class in PCL for storing collections of 3D points.
Definition: point_cloud.h:173
Defines all the PCL implemented PointT point type structures.
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
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
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
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:389
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
IndicesAllocator<> Indices
Type used for indices in PCL.
Definition: types.h:133
A point structure representing Euclidean xyz coordinates, and the RGB color.