Point Cloud Library (PCL)  1.9.1-dev
io.h
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  * 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  * $Id$
38  *
39  */
40 
41 #pragma once
42 
43 #include <string>
44 #include <pcl/pcl_base.h>
45 #include <pcl/PointIndices.h>
46 #include <pcl/conversions.h>
47 #include <pcl/exceptions.h>
48 #include <locale>
49 
50 namespace pcl
51 {
52  /** \brief Get the index of a specified field (i.e., dimension/channel)
53  * \param[in] cloud the point cloud message
54  * \param[in] field_name the string defining the field name
55  * \ingroup common
56  */
57  inline int
58  getFieldIndex (const pcl::PCLPointCloud2 &cloud, const std::string &field_name)
59  {
60  // Get the index we need
61  for (size_t d = 0; d < cloud.fields.size (); ++d)
62  if (cloud.fields[d].name == field_name)
63  return (static_cast<int>(d));
64  return (-1);
65  }
66 
67  /** \brief Get the index of a specified field (i.e., dimension/channel)
68  * \param[in] cloud the point cloud message
69  * \param[in] field_name the string defining the field name
70  * \param[out] fields a vector to the original \a PCLPointField vector that the raw PointCloud message contains
71  * \ingroup common
72  */
73  template <typename PointT> inline int
74  getFieldIndex (const pcl::PointCloud<PointT> &cloud, const std::string &field_name,
75  std::vector<pcl::PCLPointField> &fields);
76 
77  /** \brief Get the index of a specified field (i.e., dimension/channel)
78  * \param[in] field_name the string defining the field name
79  * \param[out] fields a vector to the original \a PCLPointField vector that the raw PointCloud message contains
80  * \ingroup common
81  */
82  template <typename PointT> inline int
83  getFieldIndex (const std::string &field_name,
84  std::vector<pcl::PCLPointField> &fields);
85 
86  /** \brief Get the list of available fields (i.e., dimension/channel)
87  * \param[in] cloud the point cloud message
88  * \param[out] fields a vector to the original \a PCLPointField vector that the raw PointCloud message contains
89  * \ingroup common
90  */
91  template <typename PointT> inline void
92  getFields (const pcl::PointCloud<PointT> &cloud, std::vector<pcl::PCLPointField> &fields);
93 
94  /** \brief Get the list of available fields (i.e., dimension/channel)
95  * \param[out] fields a vector to the original \a PCLPointField vector that the raw PointCloud message contains
96  * \ingroup common
97  */
98  template <typename PointT> inline void
99  getFields (std::vector<pcl::PCLPointField> &fields);
100 
101  /** \brief Get the list of all fields available in a given cloud
102  * \param[in] cloud the point cloud message
103  * \ingroup common
104  */
105  template <typename PointT> inline std::string
106  getFieldsList (const pcl::PointCloud<PointT> &cloud);
107 
108  /** \brief Get the available point cloud fields as a space separated string
109  * \param[in] cloud a pointer to the PointCloud message
110  * \ingroup common
111  */
112  inline std::string
114  {
115  std::string result;
116  for (size_t i = 0; i < cloud.fields.size () - 1; ++i)
117  result += cloud.fields[i].name + " ";
118  result += cloud.fields[cloud.fields.size () - 1].name;
119  return (result);
120  }
121 
122  /** \brief Obtains the size of a specific field data type in bytes
123  * \param[in] datatype the field data type (see PCLPointField.h)
124  * \ingroup common
125  */
126  inline int
127  getFieldSize (const int datatype)
128  {
129  switch (datatype)
130  {
133  return (1);
134 
137  return (2);
138 
142  return (4);
143 
145  return (8);
146 
147  default:
148  return (0);
149  }
150  }
151 
152  /** \brief Obtain a vector with the sizes of all valid fields (e.g., not "_")
153  * \param[in] fields the input vector containing the fields
154  * \param[out] field_sizes the resultant field sizes in bytes
155  */
156  PCL_EXPORTS void
157  getFieldsSizes (const std::vector<pcl::PCLPointField> &fields,
158  std::vector<int> &field_sizes);
159 
160  /** \brief Obtains the type of the PCLPointField from a specific size and type
161  * \param[in] size the size in bytes of the data field
162  * \param[in] type a char describing the type of the field ('F' = float, 'I' = signed, 'U' = unsigned)
163  * \ingroup common
164  */
165  inline int
166  getFieldType (const int size, char type)
167  {
168  type = std::toupper (type, std::locale::classic ());
169  switch (size)
170  {
171  case 1:
172  if (type == 'I')
173  return (pcl::PCLPointField::INT8);
174  if (type == 'U')
175  return (pcl::PCLPointField::UINT8);
176  break;
177 
178  case 2:
179  if (type == 'I')
180  return (pcl::PCLPointField::INT16);
181  if (type == 'U')
183  break;
184 
185  case 4:
186  if (type == 'I')
187  return (pcl::PCLPointField::INT32);
188  if (type == 'U')
190  if (type == 'F')
192  break;
193 
194  case 8:
195  if (type == 'F')
197  break;
198  }
199  return (-1);
200  }
201 
202  /** \brief Obtains the type of the PCLPointField from a specific PCLPointField as a char
203  * \param[in] type the PCLPointField field type
204  * \ingroup common
205  */
206  inline char
207  getFieldType (const int type)
208  {
209  switch (type)
210  {
214  return ('I');
215 
219  return ('U');
220 
223  return ('F');
224  default:
225  return ('?');
226  }
227  }
228 
229  typedef enum
230  {
236 
237  /** \brief \return the right index according to the interpolation type.
238  * \note this is adapted from OpenCV
239  * \param p the index of point to interpolate
240  * \param length the top/bottom row or left/right column index
241  * \param type the requested interpolation
242  * \throws pcl::BadArgumentException if type is unknown
243  */
244  PCL_EXPORTS int
245  interpolatePointIndex (int p, int length, InterpolationType type);
246 
247  /** \brief Concatenate two pcl::PCLPointCloud2.
248  * \param[in] cloud1 the first input point cloud dataset
249  * \param[in] cloud2 the second input point cloud dataset
250  * \param[out] cloud_out the resultant output point cloud dataset
251  * \return true if successful, false if failed (e.g., name/number of fields differs)
252  * \ingroup common
253  */
254  PCL_EXPORTS bool
256  const pcl::PCLPointCloud2 &cloud2,
257  pcl::PCLPointCloud2 &cloud_out);
258 
259  /** \brief Extract the indices of a given point cloud as a new point cloud
260  * \param[in] cloud_in the input point cloud dataset
261  * \param[in] indices the vector of indices representing the points to be copied from \a cloud_in
262  * \param[out] cloud_out the resultant output point cloud dataset
263  * \note Assumes unique indices.
264  * \ingroup common
265  */
266  PCL_EXPORTS void
267  copyPointCloud (const pcl::PCLPointCloud2 &cloud_in,
268  const std::vector<int> &indices,
269  pcl::PCLPointCloud2 &cloud_out);
270 
271  /** \brief Extract the indices of a given point cloud as a new point cloud
272  * \param[in] cloud_in the input point cloud dataset
273  * \param[in] indices the vector of indices representing the points to be copied from \a cloud_in
274  * \param[out] cloud_out the resultant output point cloud dataset
275  * \note Assumes unique indices.
276  * \ingroup common
277  */
278  PCL_EXPORTS void
279  copyPointCloud (const pcl::PCLPointCloud2 &cloud_in,
280  const std::vector<int, Eigen::aligned_allocator<int> > &indices,
281  pcl::PCLPointCloud2 &cloud_out);
282 
283  /** \brief Copy fields and point cloud data from \a cloud_in to \a cloud_out
284  * \param[in] cloud_in the input point cloud dataset
285  * \param[out] cloud_out the resultant output point cloud dataset
286  * \ingroup common
287  */
288  PCL_EXPORTS void
289  copyPointCloud (const pcl::PCLPointCloud2 &cloud_in,
290  pcl::PCLPointCloud2 &cloud_out);
291 
292  /** \brief Check if two given point types are the same or not. */
293  template <typename Point1T, typename Point2T> inline bool
295  {
296  return (typeid (Point1T) == typeid (Point2T));
297  }
298 
299  /** \brief Extract the indices of a given point cloud as a new point cloud
300  * \param[in] cloud_in the input point cloud dataset
301  * \param[in] indices the vector of indices representing the points to be copied from \a cloud_in
302  * \param[out] cloud_out the resultant output point cloud dataset
303  * \note Assumes unique indices.
304  * \ingroup common
305  */
306  template <typename PointT> void
307  copyPointCloud (const pcl::PointCloud<PointT> &cloud_in,
308  const std::vector<int> &indices,
309  pcl::PointCloud<PointT> &cloud_out);
310 
311  /** \brief Extract the indices of a given point cloud as a new point cloud
312  * \param[in] cloud_in the input point cloud dataset
313  * \param[in] indices the vector of indices representing the points to be copied from \a cloud_in
314  * \param[out] cloud_out the resultant output point cloud dataset
315  * \note Assumes unique indices.
316  * \ingroup common
317  */
318  template <typename PointT> void
319  copyPointCloud (const pcl::PointCloud<PointT> &cloud_in,
320  const std::vector<int, Eigen::aligned_allocator<int> > &indices,
321  pcl::PointCloud<PointT> &cloud_out);
322 
323  /** \brief Extract the indices of a given point cloud as a new point cloud
324  * \param[in] cloud_in the input point cloud dataset
325  * \param[in] indices the PointIndices structure representing the points to be copied from cloud_in
326  * \param[out] cloud_out the resultant output point cloud dataset
327  * \note Assumes unique indices.
328  * \ingroup common
329  */
330  template <typename PointT> void
331  copyPointCloud (const pcl::PointCloud<PointT> &cloud_in,
332  const PointIndices &indices,
333  pcl::PointCloud<PointT> &cloud_out);
334 
335  /** \brief Extract the indices of a given point cloud as a new point cloud
336  * \param[in] cloud_in the input point cloud dataset
337  * \param[in] indices the vector of indices representing the points to be copied from \a cloud_in
338  * \param[out] cloud_out the resultant output point cloud dataset
339  * \note Assumes unique indices.
340  * \ingroup common
341  */
342  template <typename PointT> void
343  copyPointCloud (const pcl::PointCloud<PointT> &cloud_in,
344  const std::vector<pcl::PointIndices> &indices,
345  pcl::PointCloud<PointT> &cloud_out);
346 
347  /** \brief Copy all the fields from a given point cloud into a new point cloud
348  * \param[in] cloud_in the input point cloud dataset
349  * \param[out] cloud_out the resultant output point cloud dataset
350  * \ingroup common
351  */
352  template <typename PointInT, typename PointOutT> void
353  copyPointCloud (const pcl::PointCloud<PointInT> &cloud_in,
354  pcl::PointCloud<PointOutT> &cloud_out);
355 
356  /** \brief Extract the indices of a given point cloud as a new point cloud
357  * \param[in] cloud_in the input point cloud dataset
358  * \param[in] indices the vector of indices representing the points to be copied from \a cloud_in
359  * \param[out] cloud_out the resultant output point cloud dataset
360  * \note Assumes unique indices.
361  * \ingroup common
362  */
363  template <typename PointInT, typename PointOutT> void
364  copyPointCloud (const pcl::PointCloud<PointInT> &cloud_in,
365  const std::vector<int> &indices,
366  pcl::PointCloud<PointOutT> &cloud_out);
367 
368  /** \brief Extract the indices of a given point cloud as a new point cloud
369  * \param[in] cloud_in the input point cloud dataset
370  * \param[in] indices the vector of indices representing the points to be copied from \a cloud_in
371  * \param[out] cloud_out the resultant output point cloud dataset
372  * \note Assumes unique indices.
373  * \ingroup common
374  */
375  template <typename PointInT, typename PointOutT> void
376  copyPointCloud (const pcl::PointCloud<PointInT> &cloud_in,
377  const std::vector<int, Eigen::aligned_allocator<int> > &indices,
378  pcl::PointCloud<PointOutT> &cloud_out);
379 
380  /** \brief Extract the indices of a given point cloud as a new point cloud
381  * \param[in] cloud_in the input point cloud dataset
382  * \param[in] indices the PointIndices structure representing the points to be copied from cloud_in
383  * \param[out] cloud_out the resultant output point cloud dataset
384  * \note Assumes unique indices.
385  * \ingroup common
386  */
387  template <typename PointInT, typename PointOutT> void
388  copyPointCloud (const pcl::PointCloud<PointInT> &cloud_in,
389  const PointIndices &indices,
390  pcl::PointCloud<PointOutT> &cloud_out);
391 
392  /** \brief Extract the indices of a given point cloud as a new point cloud
393  * \param[in] cloud_in the input point cloud dataset
394  * \param[in] indices the vector of indices representing the points to be copied from cloud_in
395  * \param[out] cloud_out the resultant output point cloud dataset
396  * \note Assumes unique indices.
397  * \ingroup common
398  */
399  template <typename PointInT, typename PointOutT> void
400  copyPointCloud (const pcl::PointCloud<PointInT> &cloud_in,
401  const std::vector<pcl::PointIndices> &indices,
402  pcl::PointCloud<PointOutT> &cloud_out);
403 
404  /** \brief Copy a point cloud inside a larger one interpolating borders.
405  * \param[in] cloud_in the input point cloud dataset
406  * \param[out] cloud_out the resultant output point cloud dataset
407  * \param top
408  * \param bottom
409  * \param left
410  * \param right
411  * Position of cloud_in inside cloud_out is given by \a top, \a left, \a bottom \a right.
412  * \param[in] border_type the interpolating method (pcl::BORDER_XXX)
413  * BORDER_REPLICATE: aaaaaa|abcdefgh|hhhhhhh
414  * BORDER_REFLECT: fedcba|abcdefgh|hgfedcb
415  * BORDER_REFLECT_101: gfedcb|abcdefgh|gfedcba
416  * BORDER_WRAP: cdefgh|abcdefgh|abcdefg
417  * BORDER_CONSTANT: iiiiii|abcdefgh|iiiiiii with some specified 'i'
418  * BORDER_TRANSPARENT: mnopqr|abcdefgh|tuvwxyz where m-r and t-z are original values of cloud_out
419  * \param value
420  * \throw pcl::BadArgumentException if any of top, bottom, left or right is negative.
421  * \ingroup common
422  */
423  template <typename PointT> void
424  copyPointCloud (const pcl::PointCloud<PointT> &cloud_in,
425  pcl::PointCloud<PointT> &cloud_out,
426  int top, int bottom, int left, int right,
427  pcl::InterpolationType border_type, const PointT& value);
428 
429  /** \brief Concatenate two datasets representing different fields.
430  *
431  * \note If the input datasets have overlapping fields (i.e., both contain
432  * the same fields), then the data in the second cloud (cloud2_in) will
433  * overwrite the data in the first (cloud1_in).
434  *
435  * \param[in] cloud1_in the first input dataset
436  * \param[in] cloud2_in the second input dataset (overwrites the fields of the first dataset for those that are shared)
437  * \param[out] cloud_out the resultant output dataset created by the concatenation of all the fields in the input datasets
438  * \ingroup common
439  */
440  template <typename PointIn1T, typename PointIn2T, typename PointOutT> void
442  const pcl::PointCloud<PointIn2T> &cloud2_in,
443  pcl::PointCloud<PointOutT> &cloud_out);
444 
445  /** \brief Concatenate two datasets representing different fields.
446  *
447  * \note If the input datasets have overlapping fields (i.e., both contain
448  * the same fields), then the data in the second cloud (cloud2_in) will
449  * overwrite the data in the first (cloud1_in).
450  *
451  * \param[in] cloud1_in the first input dataset
452  * \param[in] cloud2_in the second input dataset (overwrites the fields of the first dataset for those that are shared)
453  * \param[out] cloud_out the output dataset created by concatenating all the fields in the input datasets
454  * \ingroup common
455  */
456  PCL_EXPORTS bool
457  concatenateFields (const pcl::PCLPointCloud2 &cloud1_in,
458  const pcl::PCLPointCloud2 &cloud2_in,
459  pcl::PCLPointCloud2 &cloud_out);
460 
461  /** \brief Copy the XYZ dimensions of a pcl::PCLPointCloud2 into Eigen format
462  * \param[in] in the point cloud message
463  * \param[out] out the resultant Eigen MatrixXf format containing XYZ0 / point
464  * \ingroup common
465  */
466  PCL_EXPORTS bool
467  getPointCloudAsEigen (const pcl::PCLPointCloud2 &in, Eigen::MatrixXf &out);
468 
469  /** \brief Copy the XYZ dimensions from an Eigen MatrixXf into a pcl::PCLPointCloud2 message
470  * \param[in] in the Eigen MatrixXf format containing XYZ0 / point
471  * \param[out] out the resultant point cloud message
472  * \note the method assumes that the PCLPointCloud2 message already has the fields set up properly !
473  * \ingroup common
474  */
475  PCL_EXPORTS bool
476  getEigenAsPointCloud (Eigen::MatrixXf &in, pcl::PCLPointCloud2 &out);
477 
478  namespace io
479  {
480  /** \brief swap bytes order of a char array of length N
481  * \param bytes char array to swap
482  * \ingroup common
483  */
484  template <std::size_t N> void
485  swapByte (char* bytes);
486 
487  /** \brief specialization of swapByte for dimension 1
488  * \param bytes char array to swap
489  */
490  template <> inline void
491  swapByte<1> (char* bytes) { bytes[0] = bytes[0]; }
492 
493 
494  /** \brief specialization of swapByte for dimension 2
495  * \param bytes char array to swap
496  */
497  template <> inline void
498  swapByte<2> (char* bytes) { std::swap (bytes[0], bytes[1]); }
499 
500  /** \brief specialization of swapByte for dimension 4
501  * \param bytes char array to swap
502  */
503  template <> inline void
504  swapByte<4> (char* bytes)
505  {
506  std::swap (bytes[0], bytes[3]);
507  std::swap (bytes[1], bytes[2]);
508  }
509 
510  /** \brief specialization of swapByte for dimension 8
511  * \param bytes char array to swap
512  */
513  template <> inline void
514  swapByte<8> (char* bytes)
515  {
516  std::swap (bytes[0], bytes[7]);
517  std::swap (bytes[1], bytes[6]);
518  std::swap (bytes[2], bytes[5]);
519  std::swap (bytes[3], bytes[4]);
520  }
521 
522  /** \brief swaps byte of an arbitrary type T casting it to char*
523  * \param value the data you want its bytes swapped
524  */
525  template <typename T> void
526  swapByte (T& value)
527  {
528  pcl::io::swapByte<sizeof(T)> (reinterpret_cast<char*> (&value));
529  }
530  }
531 }
532 
533 #include <pcl/common/impl/io.hpp>
int getFieldIndex(const pcl::PCLPointCloud2 &cloud, const std::string &field_name)
Get the index of a specified field (i.e., dimension/channel)
Definition: io.h:58
This file defines compatibility wrappers for low level I/O functions.
Definition: convolution.h:44
std::string getFieldsList(const pcl::PointCloud< PointT > &cloud)
Get the list of all fields available in a given cloud.
Definition: io.hpp:97
void swapByte< 8 >(char *bytes)
specialization of swapByte for dimension 8
Definition: io.h:514
bool isSamePointType()
Check if two given point types are the same or not.
Definition: io.h:294
void swapByte(char *bytes)
swap bytes order of a char array of length N
PCL_EXPORTS void copyPointCloud(const pcl::PCLPointCloud2 &cloud_in, const std::vector< int > &indices, pcl::PCLPointCloud2 &cloud_out)
Extract the indices of a given point cloud as a new point cloud.
int getFieldType(const int size, char type)
Obtains the type of the PCLPointField from a specific size and type.
Definition: io.h:166
PCL_EXPORTS bool getPointCloudAsEigen(const pcl::PCLPointCloud2 &in, Eigen::MatrixXf &out)
Copy the XYZ dimensions of a pcl::PCLPointCloud2 into Eigen format.
PCL_EXPORTS void getFieldsSizes(const std::vector< pcl::PCLPointField > &fields, std::vector< int > &field_sizes)
Obtain a vector with the sizes of all valid fields (e.g., not "_")
void swapByte< 1 >(char *bytes)
specialization of swapByte for dimension 1
Definition: io.h:491
int getFieldSize(const int datatype)
Obtains the size of a specific field data type in bytes.
Definition: io.h:127
PointCloud represents the base class in PCL for storing collections of 3D points. ...
InterpolationType
Definition: io.h:229
std::vector< ::pcl::PCLPointField > fields
PCL_EXPORTS bool getEigenAsPointCloud(Eigen::MatrixXf &in, pcl::PCLPointCloud2 &out)
Copy the XYZ dimensions from an Eigen MatrixXf into a pcl::PCLPointCloud2 message.
PCL_EXPORTS int interpolatePointIndex(int p, int length, InterpolationType type)
void swapByte< 2 >(char *bytes)
specialization of swapByte for dimension 2
Definition: io.h:498
PCL_EXPORTS bool concatenatePointCloud(const pcl::PCLPointCloud2 &cloud1, const pcl::PCLPointCloud2 &cloud2, pcl::PCLPointCloud2 &cloud_out)
Concatenate two pcl::PCLPointCloud2.
A point structure representing Euclidean xyz coordinates, and the RGB color.
void swapByte< 4 >(char *bytes)
specialization of swapByte for dimension 4
Definition: io.h:504
void concatenateFields(const pcl::PointCloud< PointIn1T > &cloud1_in, const pcl::PointCloud< PointIn2T > &cloud2_in, pcl::PointCloud< PointOutT > &cloud_out)
Concatenate two datasets representing different fields.
Definition: io.hpp:346
void getFields(const pcl::PointCloud< PointT > &cloud, std::vector< pcl::PCLPointField > &fields)
Get the list of available fields (i.e., dimension/channel)
Definition: io.hpp:79