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