1 /* 2 * Software License Agreement (BSD License) 3 * 4 * Point Cloud Library (PCL) - www.pointclouds.org 5 * 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * * Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * * Redistributions in binary form must reproduce the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer in the documentation and/or other materials provided 17 * with the distribution. 18 * * Neither the name of Willow Garage, Inc. nor the names of its 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 * 35 * Author : Sergey Ushakov 36 * Email : sergey.s.ushakov@mail.ru 37 * 38 */ 39 40 #pragma once 41 42 #include <pcl/memory.h> 43 #include <pcl/pcl_macros.h> 44 #include <pcl/Vertices.h> // for Vertices 45 #include <pcl/features/feature.h> 46 #include <set> 47 48 namespace pcl 49 { 50 /** \brief 51 * This class implements the method for extracting RoPS features presented in the article 52 * "Rotational Projection Statistics for 3D Local Surface Description and Object Recognition" by 53 * Yulan Guo, Ferdous Sohel, Mohammed Bennamoun, Min Lu and Jianwei Wan. 54 */ 55 template <typename PointInT, typename PointOutT> 56 class PCL_EXPORTS ROPSEstimation : public pcl::Feature <PointInT, PointOutT> 57 { 58 public: 59 60 using Feature <PointInT, PointOutT>::input_; 61 using Feature <PointInT, PointOutT>::indices_; 62 using Feature <PointInT, PointOutT>::surface_; 63 using Feature <PointInT, PointOutT>::tree_; 64 65 using PointCloudOut = typename pcl::Feature <PointInT, PointOutT>::PointCloudOut; 66 using PointCloudIn = typename pcl::Feature <PointInT, PointOutT>::PointCloudIn; 67 68 public: 69 70 /** \brief Simple constructor. */ 71 ROPSEstimation (); 72 73 /** \brief Virtual destructor. */ 74 75 ~ROPSEstimation (); 76 77 /** \brief Allows to set the number of partition bins that is used for distribution matrix calculation. 78 * \param[in] number_of_bins number of partition bins 79 */ 80 void 81 setNumberOfPartitionBins (unsigned int number_of_bins); 82 83 /** \brief Returns the number of partition bins. */ 84 unsigned int 85 getNumberOfPartitionBins () const; 86 87 /** \brief This method sets the number of rotations. 88 * \param[in] number_of_rotations number of rotations 89 */ 90 void 91 setNumberOfRotations (unsigned int number_of_rotations); 92 93 /** \brief returns the number of rotations. */ 94 unsigned int 95 getNumberOfRotations () const; 96 97 /** \brief Allows to set the support radius that is used to crop the local surface of the point. 98 * \param[in] support_radius support radius 99 */ 100 void 101 setSupportRadius (float support_radius); 102 103 /** \brief Returns the support radius. */ 104 float 105 getSupportRadius () const; 106 107 /** \brief This method sets the triangles of the mesh. 108 * \param[in] triangles list of triangles of the mesh 109 */ 110 void 111 setTriangles (const std::vector <pcl::Vertices>& triangles); 112 113 /** \brief Returns the triangles of the mesh. 114 * \param[out] triangles triangles of the mesh 115 */ 116 void 117 getTriangles (std::vector <pcl::Vertices>& triangles) const; 118 119 private: 120 121 /** \brief Abstract feature estimation method. 122 * \param[out] output the resultant features 123 */ 124 void 125 computeFeature (PointCloudOut& output) override; 126 127 /** \brief This method simply builds the list of triangles for every point. 128 * The list of triangles for each point consists of indices of triangles it belongs to. 129 * The only purpose of this method is to improve performance of the algorithm. 130 */ 131 void 132 buildListOfPointsTriangles (); 133 134 /** \brief This method crops all the triangles within the given radius of the given point. 135 * \param[in] point point for which the local surface is computed 136 * \param[out] local_triangles stores the indices of the triangles that belong to the local surface 137 * \param[out] local_points stores the indices of the points that belong to the local surface 138 */ 139 void 140 getLocalSurface (const PointInT& point, std::set <unsigned int>& local_triangles, pcl::Indices& local_points) const; 141 142 /** \brief This method computes LRF (Local Reference Frame) matrix for the given point. 143 * \param[in] point point for which the LRF is computed 144 * \param[in] local_triangles list of triangles that represents the local surface of the point 145 * \paran[out] lrf_matrix stores computed LRF matrix for the given point 146 */ 147 void 148 computeLRF (const PointInT& point, const std::set <unsigned int>& local_triangles, Eigen::Matrix3f& lrf_matrix) const; 149 150 /** \brief This method calculates the eigen values and eigen vectors 151 * for the given covariance matrix. Note that it returns normalized eigen 152 * vectors that always form the right-handed coordinate system. 153 * \param[in] matrix covariance matrix of the cloud 154 * \param[out] major_axis eigen vector which corresponds to a major eigen value 155 * \param[out] middle_axis eigen vector which corresponds to a middle eigen value 156 * \param[out] minor_axis eigen vector which corresponds to a minor eigen value 157 */ 158 void 159 computeEigenVectors (const Eigen::Matrix3f& matrix, Eigen::Vector3f& major_axis, Eigen::Vector3f& middle_axis, 160 Eigen::Vector3f& minor_axis) const; 161 162 /** \brief This method translates the cloud so that the given point becomes the origin. 163 * After that the cloud is rotated with the help of the given matrix. 164 * \param[in] point point which stores the translation information 165 * \param[in] matrix rotation matrix 166 * \param[in] local_points point to transform 167 * \param[out] transformed_cloud stores the transformed cloud 168 */ 169 void 170 transformCloud (const PointInT& point, const Eigen::Matrix3f& matrix, const pcl::Indices& local_points, PointCloudIn& transformed_cloud) const; 171 172 /** \brief This method rotates the cloud around the given axis and computes AABB of the rotated cloud. 173 * \param[in] axis axis around which cloud must be rotated 174 * \param[in] angle angle in degrees 175 * \param[in] cloud cloud to rotate 176 * \param[out] rotated_cloud stores the rotated cloud 177 * \param[out] min stores the min point of the AABB 178 * \param[out] max stores the max point of the AABB 179 */ 180 void 181 rotateCloud (const PointInT& axis, const float angle, const PointCloudIn& cloud, PointCloudIn& rotated_cloud, 182 Eigen::Vector3f& min, Eigen::Vector3f& max) const; 183 184 /** \brief This method projects the local surface onto the XY, XZ or YZ plane 185 * and computes the distribution matrix. 186 * \param[in] projection represents the case of projection. 1 - XY, 2 - XZ, 3 - YZ 187 * \param[in] min min point of the AABB 188 * \param[in] max max point of the AABB 189 * \param[in] cloud cloud containing the points of the local surface 190 * \param[out] matrix stores computed distribution matrix 191 */ 192 void 193 getDistributionMatrix (const unsigned int projection, const Eigen::Vector3f& min, const Eigen::Vector3f& max, const PointCloudIn& cloud, Eigen::MatrixXf& matrix) const; 194 195 /** \brief This method computes the set ofcentral moments for the given matrix. 196 * \param[in] matrix input matrix 197 * \param[out] moments set of computed moments 198 */ 199 void 200 computeCentralMoments (const Eigen::MatrixXf& matrix, std::vector <float>& moments) const; 201 202 private: 203 204 /** \brief Stores the number of partition bins that is used for distribution matrix calculation. */ 205 unsigned int number_of_bins_; 206 207 /** \brief Stores number of rotations. Central moments are calculated for every rotation. */ 208 unsigned int number_of_rotations_; 209 210 /** \brief Support radius that is used to crop the local surface of the point. */ 211 float support_radius_; 212 213 /** \brief Stores the squared support radius. Used to improve performance. */ 214 float sqr_support_radius_; 215 216 /** \brief Stores the angle step. Step is calculated with respect to number of rotations. */ 217 float step_; 218 219 /** \brief Stores the set of triangles representing the mesh. */ 220 std::vector <pcl::Vertices> triangles_; 221 222 /** \brief Stores the set of triangles for each point. Its purpose is to improve performance. */ 223 std::vector <std::vector <unsigned int> > triangles_of_the_point_; 224 225 public: 226 PCL_MAKE_ALIGNED_OPERATOR_NEW 227 }; 228 } 229 230 #define PCL_INSTANTIATE_ROPSEstimation(InT, OutT) template class pcl::ROPSEstimation<InT, OutT>; 231 232 #ifdef PCL_NO_PRECOMPILE 233 #include <pcl/features/impl/rops_estimation.hpp> 234 #endif 235