Point Cloud Library (PCL) 1.13.1
Loading...
Searching...
No Matches
spin_image.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#pragma once
41
42#include <pcl/point_types.h>
43#include <pcl/features/feature.h>
44
45namespace pcl
46{
47 /** \brief Estimates spin-image descriptors in the given input points.
48 *
49 * This class represents spin image descriptor. Spin image is
50 * a histogram of point locations summed along the bins of the image.
51 * A 2D accumulator indexed by <VAR>a</VAR> and <VAR>b</VAR> is created. Next,
52 * the coordinates (<VAR>a</VAR>, <VAR>b</VAR>) are computed for a vertex in
53 * the surface mesh that is within the support of the spin image
54 * (explained below). The bin indexed by (<VAR>a</VAR>, <VAR>b</VAR>) in
55 * the accumulator is then incremented; bilinear interpolation is used
56 * to smooth the contribution of the vertex. This procedure is repeated
57 * for all vertices within the support of the spin image.
58 * The resulting accumulator can be thought of as an image;
59 * dark areas in the image correspond to bins that contain many projected points.
60 * As long as the size of the bins in the accumulator is greater
61 * than the median distance between vertices in the mesh
62 * (the definition of mesh resolution), the position of individual
63 * vertices will be averaged out during spin image generation.
64 *
65 * \attention The input normals given by \ref setInputNormals have to match
66 * the input point cloud given by \ref setInputCloud. This behavior is
67 * different than feature estimation methods that extend \ref
68 * FeatureFromNormals, which match the normals with the search surface.
69 *
70 * With the default parameters, pcl::Histogram<153> is a good choice for PointOutT.
71 * Of course the dimension of this descriptor must change to match the number
72 * of bins set by the parameters. If you use SpinImageEstimation with something
73 * other than pcl::Histogram<153>, you may need to put `#define PCL_NO_PRECOMPILE 1`
74 * before including `pcl/features/spin_image.h`.
75 *
76 * For further information please see:
77 *
78 * - Johnson, A. E., & Hebert, M. (1998). Surface Matching for Object
79 * Recognition in Complex 3D Scenes. Image and Vision Computing, 16,
80 * 635-651.
81 *
82 * The class also implements radial spin images and spin-images in angular domain
83 * (or both).
84 *
85 * \author Roman Shapovalov, Alexander Velizhev
86 * \ingroup features
87 */
88 template <typename PointInT, typename PointNT, typename PointOutT>
89 class SpinImageEstimation : public Feature<PointInT, PointOutT>
90 {
91 public:
92 using Ptr = shared_ptr<SpinImageEstimation<PointInT, PointNT, PointOutT> >;
93 using ConstPtr = shared_ptr<const SpinImageEstimation<PointInT, PointNT, PointOutT> >;
94 using Feature<PointInT, PointOutT>::feature_name_;
95 using Feature<PointInT, PointOutT>::getClassName;
96 using Feature<PointInT, PointOutT>::indices_;
97 using Feature<PointInT, PointOutT>::search_radius_;
98 using Feature<PointInT, PointOutT>::k_;
99 using Feature<PointInT, PointOutT>::surface_;
100 using Feature<PointInT, PointOutT>::fake_surface_;
101 using PCLBase<PointInT>::input_;
102
104
108
112
113 /** \brief Constructs empty spin image estimator.
114 *
115 * \param[in] image_width spin-image resolution, number of bins along one dimension
116 * \param[in] support_angle_cos minimal allowed cosine of the angle between
117 * the normals of input point and search surface point for the point
118 * to be retained in the support
119 * \param[in] min_pts_neighb min number of points in the support to correctly estimate
120 * spin-image. If at some point the support contains less points, exception is thrown
121 */
122 SpinImageEstimation (unsigned int image_width = 8,
123 double support_angle_cos = 0.0, // when 0, this is bogus, so not applied
124 unsigned int min_pts_neighb = 0);
125
126 /** \brief Empty destructor */
127 ~SpinImageEstimation () override = default;
128
129 /** \brief Sets spin-image resolution.
130 *
131 * \param[in] bin_count spin-image resolution, number of bins along one dimension
132 */
133 void
134 setImageWidth (unsigned int bin_count)
135 {
136 const unsigned int necessary_desc_size = (bin_count+1)*(2*bin_count+1);
137 if (necessary_desc_size > static_cast<unsigned int>(PointOutT::descriptorSize())) {
138 for(int i=0; ; ++i) { // Find the biggest possible image_width_
139 if(((i+1)*(2*i+1)) <= PointOutT::descriptorSize()) {
140 image_width_ = i;
141 } else {
142 break;
143 }
144 }
145 PCL_ERROR("[pcl::SpinImageEstimation] The chosen image width is too large, setting it to %u instead. "
146 "Consider using pcl::Histogram<%u> as output type of SpinImageEstimation "
147 "(possibly with `#define PCL_NO_PRECOMPILE 1`).\n", image_width_, ((bin_count+1)*(2*bin_count+1)));
148 } else if (necessary_desc_size < static_cast<unsigned int>(PointOutT::descriptorSize())) {
149 image_width_ = bin_count;
150 PCL_WARN("[pcl::SpinImageEstimation] The chosen image width is smaller than the output histogram allows. "
151 "This is not an error, but the last few histogram bins will not be set. "
152 "Consider using pcl::Histogram<%u> as output type of SpinImageEstimation "
153 "(possibly with `#define PCL_NO_PRECOMPILE 1`).\n", ((bin_count+1)*(2*bin_count+1)));
154 } else {
155 image_width_ = bin_count;
156 }
157 }
158
159 /** \brief Sets the maximum angle for the point normal to get to support region.
160 *
161 * \param[in] support_angle_cos minimal allowed cosine of the angle between
162 * the normals of input point and search surface point for the point
163 * to be retained in the support
164 */
165 void
166 setSupportAngle (double support_angle_cos)
167 {
168 if (0.0 > support_angle_cos || support_angle_cos > 1.0) // may be permit negative cosine?
169 {
170 throw PCLException ("Cosine of support angle should be between 0 and 1",
171 "spin_image.h", "setSupportAngle");
172 }
173
174 support_angle_cos_ = support_angle_cos;
175 }
176
177 /** \brief Sets minimal points count for spin image computation.
178 *
179 * \param[in] min_pts_neighb min number of points in the support to correctly estimate
180 * spin-image. If at some point the support contains less points, exception is thrown
181 */
182 void
183 setMinPointCountInNeighbourhood (unsigned int min_pts_neighb)
184 {
185 min_pts_neighb_ = min_pts_neighb;
186 }
187
188 /** \brief Provide a pointer to the input dataset that contains the point normals of
189 * the input XYZ dataset given by \ref setInputCloud
190 *
191 * \attention The input normals given by \ref setInputNormals have to match
192 * the input point cloud given by \ref setInputCloud. This behavior is
193 * different than feature estimation methods that extend \ref
194 * FeatureFromNormals, which match the normals with the search surface.
195 * \param[in] normals the const boost shared pointer to a PointCloud of normals.
196 * By convention, L2 norm of each normal should be 1.
197 */
198 inline void
200 {
201 input_normals_ = normals;
202 }
203
204 /** \brief Sets single vector a rotation axis for all input points.
205 *
206 * It could be useful e.g. when the vertical axis is known.
207 * \param[in] axis unit-length vector that serves as rotation axis for reference frame
208 */
209 void
210 setRotationAxis (const PointNT& axis)
211 {
212 rotation_axis_ = axis;
213 use_custom_axis_ = true;
214 use_custom_axes_cloud_ = false;
215 }
216
217 /** \brief Sets array of vectors as rotation axes for input points.
218 *
219 * Useful e.g. when one wants to use tangents instead of normals as rotation axes
220 * \param[in] axes unit-length vectors that serves as rotation axes for
221 * the corresponding input points' reference frames
222 */
223 void
225 {
226 rotation_axes_cloud_ = axes;
227
228 use_custom_axes_cloud_ = true;
229 use_custom_axis_ = false;
230 }
231
232 /** \brief Sets input normals as rotation axes (default setting). */
233 void
235 {
236 use_custom_axis_ = false;
237 use_custom_axes_cloud_ = false;
238 }
239
240 /** \brief Sets/unsets flag for angular spin-image domain.
241 *
242 * Angular spin-image differs from the vanilla one in the way that not
243 * the points are collected in the bins but the angles between their
244 * normals and the normal to the reference point. For further
245 * information please see
246 * Endres, F., Plagemann, C., Stachniss, C., & Burgard, W. (2009).
247 * Unsupervised Discovery of Object Classes from Range Data using Latent Dirichlet Allocation.
248 * In Robotics: Science and Systems. Seattle, USA.
249 * \param[in] is_angular true for angular domain, false for point domain
250 */
251 void
252 setAngularDomain (bool is_angular = true) { is_angular_ = is_angular; }
253
254 /** \brief Sets/unsets flag for radial spin-image structure.
255 *
256 * Instead of rectangular coordinate system for reference frame
257 * polar coordinates are used. Binning is done depending on the distance and
258 * inclination angle from the reference point
259 * \param[in] is_radial true for radial spin-image structure, false for rectangular
260 */
261 void
262 setRadialStructure (bool is_radial = true) { is_radial_ = is_radial; }
263
264 protected:
265 /** \brief Estimate the Spin Image descriptors at a set of points given by
266 * setInputWithNormals() using the surface in setSearchSurfaceWithNormals() and the spatial locator
267 * \param[out] output the resultant point cloud that contains the Spin Image feature estimates
268 */
269 void
270 computeFeature (PointCloudOut &output) override;
271
272 /** \brief initializes computations specific to spin-image.
273 *
274 * \return true iff input data and initialization are correct
275 */
276 bool
277 initCompute () override;
278
279 /** \brief Computes a spin-image for the point of the scan.
280 * \param[in] index the index of the reference point in the input cloud
281 * \return estimated spin-image (or its variant) as a matrix
282 */
283 Eigen::ArrayXXd
284 computeSiForPoint (int index) const;
285
286 private:
287 PointCloudNConstPtr input_normals_;
288 PointCloudNConstPtr rotation_axes_cloud_;
289
290 bool is_angular_;
291
292 PointNT rotation_axis_;
293 bool use_custom_axis_;
294 bool use_custom_axes_cloud_;
295
296 bool is_radial_;
297
298 unsigned int image_width_;
299 double support_angle_cos_;
300 unsigned int min_pts_neighb_;
301 };
302}
303
304#ifdef PCL_NO_PRECOMPILE
305#include <pcl/features/impl/spin_image.hpp>
306#endif
Feature represents the base feature class.
Definition feature.h:107
const std::string & getClassName() const
Get a string representation of the name of this class.
Definition feature.h:244
double search_radius_
The nearest neighbors search radius for each point.
Definition feature.h:237
int k_
The number of K nearest neighbors to use for each point.
Definition feature.h:240
std::string feature_name_
The feature name.
Definition feature.h:220
PointCloudInConstPtr surface_
An input point cloud describing the surface that is to be used for nearest neighbors estimation.
Definition feature.h:228
bool fake_surface_
If no surface is given, we use the input PointCloud as the surface.
Definition feature.h:255
PCL base class.
Definition pcl_base.h:70
PointCloudConstPtr input_
The input point cloud dataset.
Definition pcl_base.h:147
IndicesPtr indices_
A pointer to the vector of point indices to use.
Definition pcl_base.h:150
A base class for all pcl exceptions which inherits from std::runtime_error.
Definition exceptions.h:64
shared_ptr< PointCloud< PointNT > > Ptr
shared_ptr< const PointCloud< PointNT > > ConstPtr
Estimates spin-image descriptors in the given input points.
Definition spin_image.h:90
void setRotationAxis(const PointNT &axis)
Sets single vector a rotation axis for all input points.
Definition spin_image.h:210
typename Feature< PointInT, PointOutT >::PointCloudOut PointCloudOut
Definition spin_image.h:103
Eigen::ArrayXXd computeSiForPoint(int index) const
Computes a spin-image for the point of the scan.
typename PointCloudIn::Ptr PointCloudInPtr
Definition spin_image.h:110
void useNormalsAsRotationAxis()
Sets input normals as rotation axes (default setting).
Definition spin_image.h:234
void setRadialStructure(bool is_radial=true)
Sets/unsets flag for radial spin-image structure.
Definition spin_image.h:262
shared_ptr< const SpinImageEstimation< PointInT, PointNT, PointOutT > > ConstPtr
Definition spin_image.h:93
void setAngularDomain(bool is_angular=true)
Sets/unsets flag for angular spin-image domain.
Definition spin_image.h:252
~SpinImageEstimation() override=default
Empty destructor.
typename PointCloudN::Ptr PointCloudNPtr
Definition spin_image.h:106
void setImageWidth(unsigned int bin_count)
Sets spin-image resolution.
Definition spin_image.h:134
void setMinPointCountInNeighbourhood(unsigned int min_pts_neighb)
Sets minimal points count for spin image computation.
Definition spin_image.h:183
typename PointCloudIn::ConstPtr PointCloudInConstPtr
Definition spin_image.h:111
void setInputNormals(const PointCloudNConstPtr &normals)
Provide a pointer to the input dataset that contains the point normals of the input XYZ dataset given...
Definition spin_image.h:199
typename PointCloudN::ConstPtr PointCloudNConstPtr
Definition spin_image.h:107
bool initCompute() override
initializes computations specific to spin-image.
shared_ptr< SpinImageEstimation< PointInT, PointNT, PointOutT > > Ptr
Definition spin_image.h:92
void setSupportAngle(double support_angle_cos)
Sets the maximum angle for the point normal to get to support region.
Definition spin_image.h:166
void computeFeature(PointCloudOut &output) override
Estimate the Spin Image descriptors at a set of points given by setInputWithNormals() using the surfa...
void setInputRotationAxes(const PointCloudNConstPtr &axes)
Sets array of vectors as rotation axes for input points.
Definition spin_image.h:224
Defines all the PCL implemented PointT point type structures.