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 Willow Garage, Inc. 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  */
37 
38 #pragma once
39 
40 // PCL includes
41 #include <pcl/pcl_base.h>
42 #include <pcl/search/search.h> // for Search
43 #include <pcl/pcl_config.h>
44 
45 #include <functional>
46 
47 namespace pcl
48 {
49   /** \brief @b Keypoint represents the base class for key points.
50     * \author Bastian Steder
51     * \ingroup keypoints
52     */
53   template <typename PointInT, typename PointOutT>
54   class Keypoint : public PCLBase<PointInT>
55   {
56     public:
57       using Ptr = shared_ptr<Keypoint<PointInT, PointOutT> >;
58       using ConstPtr = shared_ptr<const Keypoint<PointInT, PointOutT> >;
59 
60       using PCLBase<PointInT>::indices_;
61       using PCLBase<PointInT>::input_;
62 
63       using BaseClass = PCLBase<PointInT>;
64       using KdTree = pcl::search::Search<PointInT>;
65       using KdTreePtr = typename KdTree::Ptr;
66       using PointCloudIn = pcl::PointCloud<PointInT>;
67       using PointCloudInPtr = typename PointCloudIn::Ptr;
68       using PointCloudInConstPtr = typename PointCloudIn::ConstPtr;
69       using PointCloudOut = pcl::PointCloud<PointOutT>;
70       using SearchMethod = std::function<int (pcl::index_t, double, pcl::Indices &, std::vector<float> &)>;
71       using SearchMethodSurface = std::function<int (const PointCloudIn &cloud, pcl::index_t index, double, pcl::Indices &, std::vector<float> &)>;
72 
73     public:
74       /** \brief Empty constructor. */
Keypoint()75       Keypoint () :
76         BaseClass (),
77         search_method_surface_ (),
78         surface_ (),
79         tree_ (),
80         search_parameter_ (0),
81         search_radius_ (0),
82         k_ (0)
83       {};
84 
85       /** \brief Empty destructor */
~Keypoint()86       ~Keypoint () {}
87 
88       /** \brief Provide a pointer to the input dataset that we need to estimate features at every point for.
89         * \param cloud the const boost shared pointer to a PointCloud message
90         */
91       virtual void
setSearchSurface(const PointCloudInConstPtr & cloud)92       setSearchSurface (const PointCloudInConstPtr &cloud) { surface_ = cloud; }
93 
94       /** \brief Get a pointer to the surface point cloud dataset. */
95       inline PointCloudInConstPtr
getSearchSurface()96       getSearchSurface () { return (surface_); }
97 
98       /** \brief Provide a pointer to the search object.
99         * \param tree a pointer to the spatial search object.
100         */
101       inline void
setSearchMethod(const KdTreePtr & tree)102       setSearchMethod (const KdTreePtr &tree) { tree_ = tree; }
103 
104       /** \brief Get a pointer to the search method used. */
105       inline KdTreePtr
getSearchMethod()106       getSearchMethod () { return (tree_); }
107 
108       /** \brief Get the internal search parameter. */
109       inline double
getSearchParameter()110       getSearchParameter () { return (search_parameter_); }
111 
112       /** \brief Set the number of k nearest neighbors to use for the feature estimation.
113         * \param k the number of k-nearest neighbors
114         */
115       inline void
setKSearch(int k)116       setKSearch (int k) { k_ = k; }
117 
118       /** \brief get the number of k nearest neighbors used for the feature estimation. */
119       inline int
getKSearch()120       getKSearch () { return (k_); }
121 
122       /** \brief Set the sphere radius that is to be used for determining the nearest neighbors used for the
123        *         key point detection
124         * \param radius the sphere radius used as the maximum distance to consider a point a neighbor
125         */
126       inline void
setRadiusSearch(double radius)127       setRadiusSearch (double radius) { search_radius_ = radius; }
128 
129       /** \brief Get the sphere radius used for determining the neighbors. */
130       inline double
getRadiusSearch()131       getRadiusSearch () { return (search_radius_); }
132 
133       /** \brief \return the keypoints indices in the input cloud.
134         * \note not all the daughter classes populate the keypoints indices so check emptiness before use.
135         */
136       pcl::PointIndicesConstPtr
getKeypointsIndices()137       getKeypointsIndices () { return (keypoints_indices_); }
138 
139       /** \brief Base method for key point detection for all points given in <setInputCloud (), setIndices ()> using
140         * the surface in setSearchSurface () and the spatial locator in setSearchMethod ()
141         * \param output the resultant point cloud model dataset containing the estimated features
142         */
143       inline void
144       compute (PointCloudOut &output);
145 
146       /** \brief Search for k-nearest neighbors using the spatial locator from \a setSearchmethod, and the given surface
147         * from \a setSearchSurface.
148         * \param index the index of the query point
149         * \param parameter the search parameter (either k or radius)
150         * \param indices the resultant vector of indices representing the k-nearest neighbors
151         * \param distances the resultant vector of distances representing the distances from the query point to the
152         * k-nearest neighbors
153         */
154       inline int
searchForNeighbors(pcl::index_t index,double parameter,pcl::Indices & indices,std::vector<float> & distances)155       searchForNeighbors (pcl::index_t index, double parameter, pcl::Indices &indices, std::vector<float> &distances) const
156       {
157         if (surface_ == input_)       // if the two surfaces are the same
158           return (search_method_ (index, parameter, indices, distances));
159         return (search_method_surface_ (*input_, index, parameter, indices, distances));
160       }
161 
162     protected:
163       using PCLBase<PointInT>::deinitCompute;
164 
165       virtual bool
166       initCompute ();
167 
168       /** \brief The key point detection method's name. */
169       std::string name_;
170 
171       /** \brief The search method template for indices. */
172       SearchMethod search_method_;
173 
174       /** \brief The search method template for points. */
175       SearchMethodSurface search_method_surface_;
176 
177       /** \brief An input point cloud describing the surface that is to be used for nearest neighbors estimation. */
178       PointCloudInConstPtr surface_;
179 
180       /** \brief A pointer to the spatial search object. */
181       KdTreePtr tree_;
182 
183       /** \brief The actual search parameter (casted from either \a search_radius_ or \a k_). */
184       double search_parameter_;
185 
186       /** \brief The nearest neighbors search radius for each point. */
187       double search_radius_;
188 
189       /** \brief The number of K nearest neighbors to use for each point. */
190       int k_;
191 
192       /** \brief Indices of the keypoints in the input cloud. */
193       pcl::PointIndicesPtr keypoints_indices_;
194 
195       /** \brief Get a string representation of the name of this class. */
196       inline const std::string&
getClassName()197       getClassName () const { return (name_); }
198 
199       /** \brief Abstract key point detection method. */
200       virtual void
201       detectKeypoints (PointCloudOut &output) = 0;
202   };
203 }
204 
205 #include <pcl/keypoints/impl/keypoint.hpp>
206