Point Cloud Library (PCL) 1.15.1-dev
Loading...
Searching...
No Matches
point_representation.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 *
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 the copyright holder(s) 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$
37 *
38 */
39
40#pragma once
41
42#include <algorithm>
43#include <vector>
44
45#include <pcl/point_types.h>
46#include <pcl/memory.h>
47#include <pcl/pcl_macros.h>
48#include <pcl/for_each_type.h>
49
50namespace pcl
51{
52 /** \brief @b PointRepresentation provides a set of methods for converting a point structs/object into an
53 * n-dimensional vector.
54 * \note This is an abstract class. Subclasses must set nr_dimensions_ to the appropriate value in the constructor
55 * and provide an implementation of the pure virtual copyToFloatArray method.
56 * \author Michael Dixon
57 */
58 template <typename PointT>
60 {
61 protected:
62 /** \brief The number of dimensions in this point's vector (i.e. the "k" in "k-D") */
64 /** \brief A vector containing the rescale factor to apply to each dimension. */
65 std::vector<float> alpha_;
66 /** \brief Indicates whether this point representation is trivial. It is trivial if and only if the following
67 * conditions hold:
68 * - the relevant data consists only of float values
69 * - the vectorize operation directly copies the first nr_dimensions_ elements of PointT to the out array
70 * - sizeof(PointT) is a multiple of sizeof(float)
71 * In short, a trivial point representation converts the input point to a float array that is the same as if
72 * the point was reinterpret_casted to a float array of length nr_dimensions_ . This value says that this
73 * representation can be trivial; it is only trivial if setRescaleValues() has not been set.
74 */
75 bool trivial_ = false;
76
77 public:
78 using Ptr = shared_ptr<PointRepresentation<PointT> >;
79 using ConstPtr = shared_ptr<const PointRepresentation<PointT> >;
80
81 /** \brief Empty destructor */
82 virtual ~PointRepresentation () = default;
83 //TODO: check if copy and move constructors / assignment operators are needed
84
85 /** \brief Copy point data from input point to a float array. This method must be overridden in all subclasses.
86 * \param[in] p The input point
87 * \param[out] out A pointer to a float array.
88 */
89 virtual void copyToFloatArray (const PointT &p, float *out) const = 0;
90
91 /** \brief Returns whether this point representation is trivial. It is trivial if and only if the following
92 * conditions hold:
93 * - the relevant data consists only of float values
94 * - the vectorize operation directly copies the first nr_dimensions_ elements of PointT to the out array
95 * - sizeof(PointT) is a multiple of sizeof(float)
96 * In short, a trivial point representation converts the input point to a float array that is the same as if
97 * the point was reinterpret_casted to a float array of length nr_dimensions_ . */
98 inline bool isTrivial() const { return trivial_ && alpha_.empty (); }
99
100 /** \brief Verify that the input point is valid.
101 * \param p The point to validate
102 */
103 virtual bool
104 isValid (const PointT &p) const
105 {
106 bool is_valid = true;
107
108 if (trivial_)
109 {
110 const float* temp = reinterpret_cast<const float*>(&p);
111
112 for (int i = 0; i < nr_dimensions_; ++i)
113 {
114 if (!std::isfinite (temp[i]))
115 {
116 is_valid = false;
117 break;
118 }
119 }
120 }
121 else
122 {
123 float *temp = new float[nr_dimensions_];
124 copyToFloatArray (p, temp);
125
126 for (int i = 0; i < nr_dimensions_; ++i)
127 {
128 if (!std::isfinite (temp[i]))
129 {
130 is_valid = false;
131 break;
132 }
133 }
134 delete [] temp;
135 }
136 return (is_valid);
137 }
138
139 /** \brief Convert input point into a vector representation, rescaling by \a alpha.
140 * \param[in] p the input point
141 * \param[out] out The output vector. Can be of any type that implements the [] operator.
142 */
143 template <typename OutputType> void
144 vectorize (const PointT &p, OutputType &out) const
145 {
146 float *temp = new float[nr_dimensions_];
147 copyToFloatArray (p, temp);
148 if (alpha_.empty ())
149 {
150 for (int i = 0; i < nr_dimensions_; ++i)
151 out[i] = temp[i];
152 }
153 else
154 {
155 for (int i = 0; i < nr_dimensions_; ++i)
156 out[i] = temp[i] * alpha_[i];
157 }
158 delete [] temp;
159 }
160
161 void
162 vectorize (const PointT &p, float* out) const
163 {
164 copyToFloatArray (p, out);
165 if (!alpha_.empty ())
166 for (int i = 0; i < nr_dimensions_; ++i)
167 out[i] *= alpha_[i];
168 }
169
170 void
171 vectorize (const PointT &p, std::vector<float> &out) const
172 {
173 copyToFloatArray (p, out.data());
174 if (!alpha_.empty ())
175 for (int i = 0; i < nr_dimensions_; ++i)
176 out[i] *= alpha_[i];
177 }
178
179 /** \brief Set the rescale values to use when vectorizing points
180 * \param[in] rescale_array The array/vector of rescale values. Can be of any type that implements the [] operator.
181 */
182 void
183 setRescaleValues (const float *rescale_array)
184 {
185 alpha_.resize (nr_dimensions_);
186 std::copy(rescale_array, rescale_array + nr_dimensions_, alpha_.begin());
187 }
188
189 /** \brief Return the number of dimensions in the point's vector representation. */
190 inline int getNumberOfDimensions () const { return (nr_dimensions_); }
191 };
192
193 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
194 /** \brief @b DefaultPointRepresentation extends PointRepresentation to define default behavior for common point types.
195 */
196 template <typename PointDefault>
198 {
199 using PointRepresentation <PointDefault>::nr_dimensions_;
200 using PointRepresentation <PointDefault>::trivial_;
201
202 public:
203 // Boost shared pointers
204 using Ptr = shared_ptr<DefaultPointRepresentation<PointDefault> >;
205 using ConstPtr = shared_ptr<const DefaultPointRepresentation<PointDefault> >;
206
207 static constexpr const std::int32_t NR_DIMS = std::min<std::int32_t>(sizeof (PointDefault) / sizeof (float), 3);
208
210 {
211 // If point type is unknown, assume it's a struct/array of floats, and compute the number of dimensions
212 nr_dimensions_ = sizeof (PointDefault) / sizeof (float);
213 // Limit the default representation to the first 3 elements
214 if (nr_dimensions_ > 3) nr_dimensions_ = 3;
215
216 trivial_ = true;
217 }
218
219 ~DefaultPointRepresentation () override = default;
220
221 inline Ptr
222 makeShared () const
223 {
224 return (Ptr (new DefaultPointRepresentation<PointDefault> (*this)));
225 }
226
227 void
228 copyToFloatArray (const PointDefault &p, float * out) const override
229 {
230 // If point type is unknown, treat it as a struct/array of floats
231 const float* ptr = reinterpret_cast<const float*> (&p);
232 std::copy(ptr, ptr + nr_dimensions_, out);
233 }
234 };
235
236 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
237 /** \brief @b DefaulFeatureRepresentation extends PointRepresentation and is intended to be used when defining the
238 * default behavior for feature descriptor types (i.e., copy each element of each field into a float array).
239 */
240 template <typename PointDefault>
242 {
243 protected:
244 using PointRepresentation <PointDefault>::nr_dimensions_;
245
246 private:
247 struct IncrementFunctor
248 {
249 IncrementFunctor (int &n) : n_ (n)
250 {
251 n_ = 0;
252 }
253
254 template<typename Key> inline void operator () ()
255 {
256 n_ += pcl::traits::datatype<PointDefault, Key>::size;
257 }
258
259 private:
260 int &n_;
261 };
262
263 struct NdCopyPointFunctor
264 {
265 using Pod = typename traits::POD<PointDefault>::type;
266
267 NdCopyPointFunctor (const PointDefault &p1, float * p2)
268 : p1_ (reinterpret_cast<const Pod&>(p1)), p2_ (p2) {}
269
270 template<typename Key> inline void operator() ()
271 {
272 using FieldT = typename pcl::traits::datatype<PointDefault, Key>::type;
273 constexpr int NrDims = pcl::traits::datatype<PointDefault, Key>::size;
275 }
276
277 // Copy helper for scalar fields
278 template <typename Key, typename FieldT, int NrDims>
279 struct Helper
280 {
281 static void copyPoint (const Pod &p1, float * p2, int &f_idx)
282 {
283 const std::uint8_t * data_ptr = reinterpret_cast<const std::uint8_t *> (&p1) +
284 pcl::traits::offset<PointDefault, Key>::value;
285 p2[f_idx++] = *reinterpret_cast<const FieldT*> (data_ptr);
286 }
287 };
288 // Copy helper for array fields
289 template <typename Key, typename FieldT, int NrDims>
290 struct Helper<Key, FieldT[NrDims], NrDims>
291 {
292 static void copyPoint (const Pod &p1, float * p2, int &f_idx)
293 {
294 const std::uint8_t * data_ptr = reinterpret_cast<const std::uint8_t *> (&p1) +
295 pcl::traits::offset<PointDefault, Key>::value;
296 int nr_dims = NrDims;
297 const FieldT * array = reinterpret_cast<const FieldT *> (data_ptr);
298 for (int i = 0; i < nr_dims; ++i)
299 {
300 p2[f_idx++] = array[i];
301 }
302 }
303 };
304
305 private:
306 const Pod &p1_;
307 float * p2_;
308 int f_idx_{0};
309 };
310
311 public:
312 // Boost shared pointers
313 using Ptr = shared_ptr<DefaultFeatureRepresentation<PointDefault>>;
314 using ConstPtr = shared_ptr<const DefaultFeatureRepresentation<PointDefault>>;
315 using FieldList = typename pcl::traits::fieldList<PointDefault>::type;
316
317 static constexpr const std::int32_t NR_DIMS = pcl::detail::traits::descriptorSize_v<PointDefault>;
318
320 {
321 nr_dimensions_ = 0; // zero-out the nr_dimensions_ before it gets incremented
322 pcl::for_each_type <FieldList> (IncrementFunctor (nr_dimensions_));
323 }
324
325 inline Ptr
326 makeShared () const
327 {
328 return (Ptr (new DefaultFeatureRepresentation<PointDefault> (*this)));
329 }
330
331 void
332 copyToFloatArray (const PointDefault &p, float * out) const override
333 {
334 pcl::for_each_type <FieldList> (NdCopyPointFunctor (p, out));
335 }
336 };
337
338 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
339 template <>
341 {
342 public:
343 static constexpr const std::int32_t NR_DIMS = 3;
344
350
351 void
352 copyToFloatArray (const PointXYZ &p, float * out) const override
353 {
354 out[0] = p.x;
355 out[1] = p.y;
356 out[2] = p.z;
357 }
358 };
359
360 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
361 template <>
363 {
364 public:
365 static constexpr const std::int32_t NR_DIMS = 3;
366
372
373 void
374 copyToFloatArray (const PointXYZI &p, float * out) const override
375 {
376 out[0] = p.x;
377 out[1] = p.y;
378 out[2] = p.z;
379 // By default, p.intensity is not part of the PointXYZI vectorization
380 }
381 };
382
383 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
384 template <>
386 {
387 public:
388 static constexpr const std::int32_t NR_DIMS = 3;
389
395
396 void
397 copyToFloatArray (const PointNormal &p, float * out) const override
398 {
399 out[0] = p.x;
400 out[1] = p.y;
401 out[2] = p.z;
402 }
403 };
404
405 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
406 template <>
409
410 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
411 template <>
414
415 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
416 template <>
418 {
419 public:
420 static constexpr const std::int32_t NR_DIMS = 4;
421
427
428 void
429 copyToFloatArray (const PPFSignature &p, float * out) const override
430 {
431 out[0] = p.f1;
432 out[1] = p.f2;
433 out[2] = p.f3;
434 out[3] = p.f4;
435 }
436 };
437
438 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
439 template <>
442
443 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
444 template <>
447
448 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
449 template <>
452
453 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
454 template <>
457
458 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
459 template <>
462
463 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
464 template <>
466 {
467 public:
468 static constexpr const std::int32_t NR_DIMS = 36;
469
475
476 void
477 copyToFloatArray (const Narf36 &p, float * out) const override
478 {
479 for (int i = 0; i < nr_dimensions_; ++i)
480 out[i] = p.descriptor[i];
481 }
482 };
483 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
484 template <>
487
488 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
489 template <>
491 {
492 public:
493 static constexpr const std::int32_t NR_DIMS = 1980;
494
499
500 void
501 copyToFloatArray (const ShapeContext1980 &p, float * out) const override
502 {
503 for (int i = 0; i < nr_dimensions_; ++i)
504 out[i] = p.descriptor[i];
505 }
506 };
507
508 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
509 template <>
511 {
512 public:
513 static constexpr const std::int32_t NR_DIMS = 1960;
514
519
520 void
521 copyToFloatArray (const UniqueShapeContext1960 &p, float * out) const override
522 {
523 for (int i = 0; i < nr_dimensions_; ++i)
524 out[i] = p.descriptor[i];
525 }
526 };
527
528 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
529 template <>
531 {
532 public:
533 static constexpr const std::int32_t NR_DIMS = 352;
534
539
540 void
541 copyToFloatArray (const SHOT352 &p, float * out) const override
542 {
543 for (int i = 0; i < nr_dimensions_; ++i)
544 out[i] = p.descriptor[i];
545 }
546 };
547
548 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
549 template <>
551 {
552 public:
553 static constexpr const std::int32_t NR_DIMS = 1344;
554
559
560 void
561 copyToFloatArray (const SHOT1344 &p, float * out) const override
562 {
563 for (int i = 0; i < nr_dimensions_; ++i)
564 out[i] = p.descriptor[i];
565 }
566 };
567
568
569 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
570 /** \brief @b CustomPointRepresentation extends PointRepresentation to allow for sub-part selection on the point.
571 */
572 template <typename PointDefault>
573 class CustomPointRepresentation : public PointRepresentation <PointDefault>
574 {
575 using PointRepresentation <PointDefault>::nr_dimensions_;
576
577 public:
578 // Boost shared pointers
579 using Ptr = shared_ptr<CustomPointRepresentation<PointDefault> >;
580 using ConstPtr = shared_ptr<const CustomPointRepresentation<PointDefault> >;
581
582 /** \brief Constructor
583 * \param[in] max_dim the maximum number of dimensions to use
584 * \param[in] start_dim the starting dimension
585 */
586 CustomPointRepresentation (const int max_dim = 3, const int start_dim = 0)
587 : max_dim_(max_dim), start_dim_(start_dim)
588 {
589 // If point type is unknown, assume it's a struct/array of floats, and compute the number of dimensions
590 nr_dimensions_ = static_cast<int> (sizeof (PointDefault) / sizeof (float)) - start_dim_;
591 // Limit the default representation to the first 3 elements
594 }
595
596 inline Ptr
597 makeShared () const
598 {
599 return Ptr (new CustomPointRepresentation<PointDefault> (*this));
600 }
601
602 /** \brief Copy the point data into a float array
603 * \param[in] p the input point
604 * \param[out] out the resultant output array
605 */
606 void
607 copyToFloatArray (const PointDefault &p, float *out) const override
608 {
609 // If point type is unknown, treat it as a struct/array of floats
610 const float *ptr = (reinterpret_cast<const float*> (&p)) + start_dim_;
611 std::copy(ptr, ptr + nr_dimensions_, out);
612 }
613
614 protected:
615 /** \brief Use at most this many dimensions (i.e. the "k" in "k-D" is at most max_dim_) -- \note float fields are assumed */
617 /** \brief Use dimensions only starting with this one (i.e. the "k" in "k-D" is = dim - start_dim_) -- \note float fields are assumed */
619 };
620}
CustomPointRepresentation extends PointRepresentation to allow for sub-part selection on the point.
void copyToFloatArray(const PointDefault &p, float *out) const override
Copy the point data into a float array.
CustomPointRepresentation(const int max_dim=3, const int start_dim=0)
Constructor.
int max_dim_
Use at most this many dimensions (i.e.
shared_ptr< CustomPointRepresentation< PointDefault > > Ptr
shared_ptr< const CustomPointRepresentation< PointDefault > > ConstPtr
int start_dim_
Use dimensions only starting with this one (i.e.
DefaulFeatureRepresentation extends PointRepresentation and is intended to be used when defining the ...
shared_ptr< DefaultFeatureRepresentation< PointDefault > > Ptr
typename pcl::traits::fieldList< PointDefault >::type FieldList
static constexpr const std::int32_t NR_DIMS
void copyToFloatArray(const PointDefault &p, float *out) const override
Copy point data from input point to a float array.
shared_ptr< const DefaultFeatureRepresentation< PointDefault > > ConstPtr
void copyToFloatArray(const Narf36 &p, float *out) const override
Copy point data from input point to a float array.
void copyToFloatArray(const PPFSignature &p, float *out) const override
Copy point data from input point to a float array.
void copyToFloatArray(const PointNormal &p, float *out) const override
Copy point data from input point to a float array.
void copyToFloatArray(const PointXYZ &p, float *out) const override
Copy point data from input point to a float array.
void copyToFloatArray(const PointXYZI &p, float *out) const override
Copy point data from input point to a float array.
void copyToFloatArray(const SHOT1344 &p, float *out) const override
Copy point data from input point to a float array.
void copyToFloatArray(const SHOT352 &p, float *out) const override
Copy point data from input point to a float array.
void copyToFloatArray(const ShapeContext1980 &p, float *out) const override
Copy point data from input point to a float array.
void copyToFloatArray(const UniqueShapeContext1960 &p, float *out) const override
Copy point data from input point to a float array.
DefaultPointRepresentation extends PointRepresentation to define default behavior for common point ty...
shared_ptr< DefaultPointRepresentation< PointDefault > > Ptr
shared_ptr< const DefaultPointRepresentation< PointDefault > > ConstPtr
~DefaultPointRepresentation() override=default
void copyToFloatArray(const PointDefault &p, float *out) const override
Copy point data from input point to a float array.
static constexpr const std::int32_t NR_DIMS
PointRepresentation provides a set of methods for converting a point structs/object into an n-dimensi...
void vectorize(const PointT &p, float *out) const
shared_ptr< const PointRepresentation< PointT > > ConstPtr
virtual void copyToFloatArray(const PointT &p, float *out) const =0
Copy point data from input point to a float array.
void vectorize(const PointT &p, std::vector< float > &out) const
int nr_dimensions_
The number of dimensions in this point's vector (i.e.
bool trivial_
Indicates whether this point representation is trivial.
int getNumberOfDimensions() const
Return the number of dimensions in the point's vector representation.
bool isTrivial() const
Returns whether this point representation is trivial.
void setRescaleValues(const float *rescale_array)
Set the rescale values to use when vectorizing points.
shared_ptr< PointRepresentation< PointT > > Ptr
std::vector< float > alpha_
A vector containing the rescale factor to apply to each dimension.
virtual bool isValid(const PointT &p) const
Verify that the input point is valid.
void vectorize(const PointT &p, OutputType &out) const
Convert input point into a vector representation, rescaling by alpha.
virtual ~PointRepresentation()=default
Empty destructor.
Defines all the PCL implemented PointT point type structures.
Defines functions, macros and traits for allocating and using memory.
Defines all the PCL and non-PCL macros used.
static void copyPoint(const Pod &p1, float *p2, int &f_idx)
A point structure representing the Fast Point Feature Histogram (FPFH).
A point structure representing the Globally Aligned Spatial Distribution (GASD) shape descriptor.
A point structure representing the Globally Aligned Spatial Distribution (GASD) shape and color descr...
A point structure representing the Globally Aligned Spatial Distribution (GASD) shape and color descr...
A point structure representing the Narf descriptor.
float descriptor[36]
A point structure representing the Normal Based Signature for a feature matrix of 4-by-3.
A point structure representing the Point Feature Histogram with colors (PFHRGB).
A point structure representing the Point Feature Histogram (PFH).
A point structure for storing the Point Pair Feature (PPF) values.
A point structure representing Euclidean xyz coordinates, together with normal coordinates and the su...
A point structure representing Euclidean xyz coordinates.
A point structure representing Euclidean xyz coordinates, and the RGB color.
A point structure representing the generic Signature of Histograms of OrienTations (SHOT) - shape+col...
float descriptor[1344]
A point structure representing the generic Signature of Histograms of OrienTations (SHOT) - shape onl...
float descriptor[352]
A point structure representing a Shape Context.
A point structure representing a Unique Shape Context.
A point structure representing the Viewpoint Feature Histogram (VFH).