Point Cloud Library (PCL)  1.9.1-dev
narf.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 #pragma once
40 
41 #include <pcl/pcl_macros.h>
42 #include <pcl/features/eigen.h>
43 #include <pcl/common/common_headers.h>
44 #include <pcl/point_representation.h>
45 
46 namespace pcl
47 {
48  // Forward declarations
49  class RangeImage;
50  struct InterestPoint;
51 
52 #define NARF_DEFAULT_SURFACE_PATCH_PIXEL_SIZE 10
53 
54  /**
55  * \brief NARF (Normal Aligned Radial Features) is a point feature descriptor type for 3D data.
56  * Please refer to pcl/features/narf_descriptor.h if you want the class derived from pcl Feature.
57  * See B. Steder, R. B. Rusu, K. Konolige, and W. Burgard
58  * Point Feature Extraction on 3D Range Scans Taking into Account Object Boundaries
59  * In Proc. of the IEEE Int. Conf. on Robotics &Automation (ICRA). 2011.
60  * \author Bastian Steder
61  * \ingroup features
62  */
63  class PCL_EXPORTS Narf
64  {
65  public:
66  // =====CONSTRUCTOR & DESTRUCTOR=====
67  //! Constructor
68  Narf();
69  //! Copy Constructor
70  Narf(const Narf& other);
71  //! Destructor
72  ~Narf();
73 
74  // =====Operators=====
75  //! Assignment operator
76  const Narf& operator=(const Narf& other);
77 
78  // =====STATIC=====
79  /** The maximum number of openmp threads that can be used in this class */
80  static int max_no_of_threads;
81 
82  /** Add features extracted at the given interest point and add them to the list */
83  static void
84  extractFromRangeImageAndAddToList (const RangeImage& range_image, const Eigen::Vector3f& interest_point, int descriptor_size,
85  float support_size, bool rotation_invariant, std::vector<Narf*>& feature_list);
86  /** Same as above */
87  static void
88  extractFromRangeImageAndAddToList (const RangeImage& range_image, float image_x, float image_y, int descriptor_size,
89  float support_size, bool rotation_invariant, std::vector<Narf*>& feature_list);
90  /** Get a list of features from the given interest points. */
91  static void
92  extractForInterestPoints (const RangeImage& range_image, const PointCloud<InterestPoint>& interest_points,
93  int descriptor_size, float support_size, bool rotation_invariant, std::vector<Narf*>& feature_list);
94  /** Extract an NARF for every point in the range image. */
95  static void
96  extractForEveryRangeImagePointAndAddToList (const RangeImage& range_image, int descriptor_size, float support_size,
97  bool rotation_invariant, std::vector<Narf*>& feature_list);
98 
99  // =====PUBLIC METHODS=====
100  /** Method to extract a NARF feature from a certain 3D point using a range image.
101  * pose determines the coordinate system of the feature, whereas it transforms a point from the world into the feature system.
102  * This means the interest point at which the feature is extracted will be the inverse application of pose onto (0,0,0).
103  * descriptor_size_ determines the size of the descriptor,
104  * support_size determines the support size of the feature, meaning the size in the world it covers */
105  bool
106  extractFromRangeImage (const RangeImage& range_image, const Eigen::Affine3f& pose, int descriptor_size, float support_size,
107  int surface_patch_world_size=NARF_DEFAULT_SURFACE_PATCH_PIXEL_SIZE);
108 
109  //! Same as above, but determines the transformation from the surface in the range image
110  bool
111  extractFromRangeImage (const RangeImage& range_image, float x, float y, int descriptor_size, float support_size);
112 
113  //! Same as above
114  bool
115  extractFromRangeImage (const RangeImage& range_image, const InterestPoint& interest_point, int descriptor_size, float support_size);
116 
117  //! Same as above
118  bool
119  extractFromRangeImage (const RangeImage& range_image, const Eigen::Vector3f& interest_point, int descriptor_size, float support_size);
120 
121  /** Same as above, but using the rotational invariant version by choosing the best extracted rotation around the normal.
122  * Use extractFromRangeImageAndAddToList if you want to enable the system to return multiple features with different rotations. */
123  bool
124  extractFromRangeImageWithBestRotation (const RangeImage& range_image, const Eigen::Vector3f& interest_point,
125  int descriptor_size, float support_size);
126 
127  /* Get the dominant rotations of the current descriptor
128  * \param rotations the returned rotations
129  * \param strength values describing how pronounced the corresponding rotations are
130  */
131  void
132  getRotations (std::vector<float>& rotations, std::vector<float>& strengths) const;
133 
134  /* Get the feature with a different rotation around the normal
135  * You are responsible for deleting the new features!
136  * \param range_image the source from which the feature is extracted
137  * \param rotations list of angles (in radians)
138  * \param rvps returned features
139  */
140  void
141  getRotatedVersions (const RangeImage& range_image, const std::vector<float>& rotations, std::vector<Narf*>& features) const;
142 
143  //! Calculate descriptor distance, value in [0,1] with 0 meaning identical and 1 every cell above maximum distance
144  inline float
145  getDescriptorDistance (const Narf& other) const;
146 
147  //! How many points on each beam of the gradient star are used to calculate the descriptor?
148  inline int
149  getNoOfBeamPoints () const { return (static_cast<int> (pcl_lrint (std::ceil (0.5f * float (surface_patch_pixel_size_))))); }
150 
151  //! Copy the descriptor and pose to the point struct Narf36
152  inline void
153  copyToNarf36 (Narf36& narf36) const;
154 
155  /** Write to file */
156  void
157  saveBinary (const std::string& filename) const;
158  /** Write to output stream */
159  void
160  saveBinary (std::ostream& file) const;
161 
162  /** Read from file */
163  void
164  loadBinary (const std::string& filename);
165  /** Read from input stream */
166  void
167  loadBinary (std::istream& file);
168 
169  //! Create the descriptor from the already set other members
170  bool
171  extractDescriptor (int descriptor_size);
172 
173  // =====GETTERS=====
174  //! Getter (const) for the descriptor
175  inline const float*
176  getDescriptor () const { return descriptor_;}
177  //! Getter for the descriptor
178  inline float*
179  getDescriptor () { return descriptor_;}
180  //! Getter (const) for the descriptor length
181  inline const int&
182  getDescriptorSize () const { return descriptor_size_;}
183  //! Getter for the descriptor length
184  inline int&
185  getDescriptorSize () { return descriptor_size_;}
186  //! Getter (const) for the position
187  inline const Eigen::Vector3f&
188  getPosition () const { return position_;}
189  //! Getter for the position
190  inline Eigen::Vector3f&
191  getPosition () { return position_;}
192  //! Getter (const) for the 6DoF pose
193  inline const Eigen::Affine3f&
194  getTransformation () const { return transformation_;}
195  //! Getter for the 6DoF pose
196  inline Eigen::Affine3f&
197  getTransformation () { return transformation_;}
198  //! Getter (const) for the pixel size of the surface patch (only one dimension)
199  inline const int&
200  getSurfacePatchPixelSize () const { return surface_patch_pixel_size_;}
201  //! Getter for the pixel size of the surface patch (only one dimension)
202  inline int&
203  getSurfacePatchPixelSize () { return surface_patch_pixel_size_;}
204  //! Getter (const) for the world size of the surface patch
205  inline const float&
206  getSurfacePatchWorldSize () const { return surface_patch_world_size_;}
207  //! Getter for the world size of the surface patch
208  inline float&
209  getSurfacePatchWorldSize () { return surface_patch_world_size_;}
210  //! Getter (const) for the rotation of the surface patch
211  inline const float&
212  getSurfacePatchRotation () const { return surface_patch_rotation_;}
213  //! Getter for the rotation of the surface patch
214  inline float&
215  getSurfacePatchRotation () { return surface_patch_rotation_;}
216  //! Getter (const) for the surface patch
217  inline const float*
218  getSurfacePatch () const { return surface_patch_;}
219  //! Getter for the surface patch
220  inline float*
221  getSurfacePatch () { return surface_patch_;}
222  //! Method to erase the surface patch and free the memory
223  inline void
224  freeSurfacePatch () { delete[] surface_patch_; surface_patch_=nullptr; surface_patch_pixel_size_=0; }
225 
226  // =====SETTERS=====
227  //! Setter for the descriptor
228  inline void
229  setDescriptor (float* descriptor) { descriptor_ = descriptor;}
230  //! Setter for the surface patch
231  inline void
232  setSurfacePatch (float* surface_patch) { surface_patch_ = surface_patch;}
233 
234  // =====PUBLIC MEMBER VARIABLES=====
235 
236  // =====PUBLIC STRUCTS=====
238  {
239  using PointT = Narf *;
240  FeaturePointRepresentation(int nr_dimensions) { this->nr_dimensions_ = nr_dimensions; }
241  /** \brief Empty destructor */
243  void copyToFloatArray (const PointT& p, float* out) const override { memcpy(out, p->getDescriptor(), sizeof(*p->getDescriptor())*this->nr_dimensions_); }
244  };
245 
246  protected:
247  // =====PROTECTED METHODS=====
248  //! Reset al members to default values and free allocated memory
249  void
250  reset ();
251  //! Create a deep copy of other
252  void
253  deepCopy (const Narf& other);
254  //! Get the surface patch with a blur on it
255  float*
256  getBlurredSurfacePatch (int new_pixel_size, int blur_radius) const;
257 
258  /** Write header to output stream */
259  void
260  saveHeader (std::ostream& file) const;
261  /** Read header from input stream */
262  int
263  loadHeader (std::istream& file) const;
264 
265  // =====PROTECTED STATIC METHODS=====
266  static const std::string
267  getHeaderKeyword () { return "NARF"; }
268 
269  // =====PROTECTED STATIC VARIABLES=====
270  const static int VERSION = 1;
271 
272  // =====PROTECTED MEMBER VARIABLES=====
273  Eigen::Vector3f position_;
274  Eigen::Affine3f transformation_;
279  float* descriptor_;
281 
282  // =====STATIC PROTECTED=====
283 
284  public:
286  };
287 #undef NARF_DEFAULT_SURFACE_PATCH_PIXEL_SIZE
288 
289 } // end namespace pcl
290 
291 #include <pcl/features/impl/narf.hpp>
const float * getSurfacePatch() const
Getter (const) for the surface patch.
Definition: narf.h:218
Eigen::Affine3f & getTransformation()
Getter for the 6DoF pose.
Definition: narf.h:197
float & getSurfacePatchRotation()
Getter for the rotation of the surface patch.
Definition: narf.h:215
void loadBinary(Eigen::MatrixBase< Derived > const &matrix, std::istream &file)
Read a matrix from an input stream.
Definition: eigen.hpp:717
int getNoOfBeamPoints() const
How many points on each beam of the gradient star are used to calculate the descriptor?
Definition: narf.h:149
~FeaturePointRepresentation()
Empty destructor.
Definition: narf.h:242
Eigen::Affine3f transformation_
Definition: narf.h:274
RangeImage is derived from pcl/PointCloud and provides functionalities with focus on situations where...
Definition: range_image.h:54
void copyToFloatArray(const PointT &p, float *out) const override
Definition: narf.h:243
const Eigen::Affine3f & getTransformation() const
Getter (const) for the 6DoF pose.
Definition: narf.h:194
This file defines compatibility wrappers for low level I/O functions.
Definition: convolution.h:45
const float & getSurfacePatchWorldSize() const
Getter (const) for the world size of the surface patch.
Definition: narf.h:206
int & getDescriptorSize()
Getter for the descriptor length.
Definition: narf.h:185
int & getSurfacePatchPixelSize()
Getter for the pixel size of the surface patch (only one dimension)
Definition: narf.h:203
float surface_patch_world_size_
Definition: narf.h:277
const int & getSurfacePatchPixelSize() const
Getter (const) for the pixel size of the surface patch (only one dimension)
Definition: narf.h:200
#define PCL_MAKE_ALIGNED_OPERATOR_NEW
Macro to signal a class requires a custom allocator.
Definition: pcl_macros.h:344
void saveBinary(const Eigen::MatrixBase< Derived > &matrix, std::ostream &file)
Write a matrix to an output stream.
Definition: eigen.hpp:702
float * surface_patch_
Definition: narf.h:275
PointRepresentation provides a set of methods for converting a point structs/object into an n-dimensi...
int surface_patch_pixel_size_
Definition: narf.h:276
static const std::string getHeaderKeyword()
Definition: narf.h:267
FeaturePointRepresentation(int nr_dimensions)
Definition: narf.h:240
A point structure representing an interest point with Euclidean xyz coordinates, and an interest valu...
const Eigen::Vector3f & getPosition() const
Getter (const) for the position.
Definition: narf.h:188
NARF (Normal Aligned Radial Features) is a point feature descriptor type for 3D data.
Definition: narf.h:63
Eigen::Vector3f position_
Definition: narf.h:273
const int & getDescriptorSize() const
Getter (const) for the descriptor length.
Definition: narf.h:182
void setSurfacePatch(float *surface_patch)
Setter for the surface patch.
Definition: narf.h:232
PointCloud represents the base class in PCL for storing collections of 3D points. ...
float & getSurfacePatchWorldSize()
Getter for the world size of the surface patch.
Definition: narf.h:209
const float * getDescriptor() const
Getter (const) for the descriptor.
Definition: narf.h:176
static int max_no_of_threads
The maximum number of openmp threads that can be used in this class.
Definition: narf.h:80
const float & getSurfacePatchRotation() const
Getter (const) for the rotation of the surface patch.
Definition: narf.h:212
float * getSurfacePatch()
Getter for the surface patch.
Definition: narf.h:221
float surface_patch_rotation_
Definition: narf.h:278
void setDescriptor(float *descriptor)
Setter for the descriptor.
Definition: narf.h:229
A point structure representing the Narf descriptor.
Eigen::Vector3f & getPosition()
Getter for the position.
Definition: narf.h:191
void freeSurfacePatch()
Method to erase the surface patch and free the memory.
Definition: narf.h:224
float * descriptor_
Definition: narf.h:279
int descriptor_size_
Definition: narf.h:280
float * getDescriptor()
Getter for the descriptor.
Definition: narf.h:179