00001 00002 /* 00003 * Software License Agreement (BSD License) 00004 * 00005 * Point Cloud Library (PCL) - www.pointclouds.org 00006 * 00007 * All rights reserved. 00008 * 00009 * Redistribution and use in source and binary forms, with or without 00010 * modification, are permitted provided that the following conditions 00011 * are met: 00012 * 00013 * * Redistributions of source code must retain the above copyright 00014 * notice, this list of conditions and the following disclaimer. 00015 * * Redistributions in binary form must reproduce the above 00016 * copyright notice, this list of conditions and the following 00017 * disclaimer in the documentation and/or other materials provided 00018 * with the distribution. 00019 * * Neither the name of Willow Garage, Inc. nor the names of its 00020 * contributors may be used to endorse or promote products derived 00021 * from this software without specific prior written permission. 00022 * 00023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00024 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00025 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00026 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00027 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00028 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00029 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00030 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00031 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00032 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00033 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00034 * POSSIBILITY OF SUCH DAMAGE. 00035 * 00036 * Author : jpapon@gmail.com 00037 * Email : jpapon@gmail.com 00038 * 00039 */ 00040 00041 #ifndef PCL_SEGMENTATION_SUPERVOXEL_CLUSTERING_H_ 00042 #define PCL_SEGMENTATION_SUPERVOXEL_CLUSTERING_H_ 00043 00044 #include <pcl/features/normal_3d.h> 00045 #include <pcl/pcl_base.h> 00046 #include <pcl/point_cloud.h> 00047 #include <pcl/point_types.h> 00048 #include <pcl/octree/octree.h> 00049 #include <pcl/octree/octree_pointcloud_adjacency.h> 00050 #include <pcl/search/search.h> 00051 #include <pcl/segmentation/boost.h> 00052 00053 00054 00055 //DEBUG TODO REMOVE 00056 #include <pcl/common/time.h> 00057 00058 00059 namespace pcl 00060 { 00061 /** \brief Supervoxel container class - stores a cluster extracted using supervoxel clustering 00062 */ 00063 template <typename PointT> 00064 class Supervoxel 00065 { 00066 public: 00067 Supervoxel () : 00068 voxels_ (new pcl::PointCloud<PointT> ()), 00069 normals_ (new pcl::PointCloud<Normal> ()) 00070 { } 00071 00072 typedef boost::shared_ptr<Supervoxel<PointT> > Ptr; 00073 typedef boost::shared_ptr<const Supervoxel<PointT> > ConstPtr; 00074 00075 /** \brief Gets the centroid of the supervoxel 00076 * \param[out] centroid_arg centroid of the supervoxel 00077 */ 00078 void 00079 getCentroidPoint (PointXYZRGBA ¢roid_arg) 00080 { 00081 centroid_arg = centroid_; 00082 } 00083 00084 /** \brief Gets the point normal for the supervoxel 00085 * \param[out] normal_arg Point normal of the supervoxel 00086 * \note This isn't an average, it is a normal computed using all of the voxels in the supervoxel as support 00087 */ 00088 void 00089 getCentroidPointNormal (PointNormal &normal_arg) 00090 { 00091 normal_arg.x = centroid_.x; 00092 normal_arg.y = centroid_.y; 00093 normal_arg.z = centroid_.z; 00094 normal_arg.normal_x = normal_.normal_x; 00095 normal_arg.normal_y = normal_.normal_y; 00096 normal_arg.normal_z = normal_.normal_z; 00097 normal_arg.curvature = normal_.curvature; 00098 } 00099 00100 /** \brief The normal calculated for the voxels contained in the supervoxel */ 00101 pcl::Normal normal_; 00102 /** \brief The centroid of the supervoxel - average voxel */ 00103 pcl::PointXYZRGBA centroid_; 00104 /** \brief A Pointcloud of the voxels in the supervoxel */ 00105 typename pcl::PointCloud<PointT>::Ptr voxels_; 00106 /** \brief A Pointcloud of the normals for the points in the supervoxel */ 00107 typename pcl::PointCloud<Normal>::Ptr normals_; 00108 00109 public: 00110 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00111 }; 00112 00113 /** \brief Implements a supervoxel algorithm based on voxel structure, normals, and rgb values 00114 * \note Supervoxels are oversegmented volumetric patches (usually surfaces) 00115 * \note Usually, color isn't needed (and can be detrimental)- spatial structure is mainly used 00116 * - J. Papon, A. Abramov, M. Schoeler, F. Woergoetter 00117 * Voxel Cloud Connectivity Segmentation - Supervoxels from PointClouds 00118 * In Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition (CVPR) 2013 00119 * \author Jeremie Papon (jpapon@gmail.com) 00120 */ 00121 template <typename PointT> 00122 class PCL_EXPORTS SupervoxelClustering : public pcl::PCLBase<PointT> 00123 { 00124 //Forward declaration of friended helper class 00125 class SupervoxelHelper; 00126 friend class SupervoxelHelper; 00127 public: 00128 /** \brief VoxelData is a structure used for storing data within a pcl::octree::OctreePointCloudAdjacencyContainer 00129 * \note It stores xyz, rgb, normal, distance, an index, and an owner. 00130 */ 00131 class VoxelData 00132 { 00133 public: 00134 VoxelData (): 00135 xyz_ (0.0f, 0.0f, 0.0f), 00136 rgb_ (0.0f, 0.0f, 0.0f), 00137 normal_ (0.0f, 0.0f, 0.0f, 0.0f), 00138 curvature_ (0.0f), 00139 owner_ (0) 00140 {} 00141 00142 /** \brief Gets the data of in the form of a point 00143 * \param[out] point_arg Will contain the point value of the voxeldata 00144 */ 00145 void 00146 getPoint (PointT &point_arg) const; 00147 00148 /** \brief Gets the data of in the form of a normal 00149 * \param[out] normal_arg Will contain the normal value of the voxeldata 00150 */ 00151 void 00152 getNormal (Normal &normal_arg) const; 00153 00154 Eigen::Vector3f xyz_; 00155 Eigen::Vector3f rgb_; 00156 Eigen::Vector4f normal_; 00157 float curvature_; 00158 float distance_; 00159 int idx_; 00160 SupervoxelHelper* owner_; 00161 00162 public: 00163 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00164 }; 00165 00166 typedef pcl::octree::OctreePointCloudAdjacencyContainer<PointT, VoxelData> LeafContainerT; 00167 typedef std::vector <LeafContainerT*> LeafVectorT; 00168 00169 typedef typename pcl::PointCloud<PointT> PointCloudT; 00170 typedef typename pcl::PointCloud<Normal> NormalCloudT; 00171 typedef typename pcl::octree::OctreePointCloudAdjacency<PointT, LeafContainerT> OctreeAdjacencyT; 00172 typedef typename pcl::octree::OctreePointCloudSearch <PointT> OctreeSearchT; 00173 typedef typename pcl::search::KdTree<PointT> KdTreeT; 00174 typedef boost::shared_ptr<std::vector<int> > IndicesPtr; 00175 00176 using PCLBase <PointT>::initCompute; 00177 using PCLBase <PointT>::deinitCompute; 00178 using PCLBase <PointT>::input_; 00179 00180 typedef boost::adjacency_list<boost::setS, boost::setS, boost::undirectedS, uint32_t, float> VoxelAdjacencyList; 00181 typedef VoxelAdjacencyList::vertex_descriptor VoxelID; 00182 typedef VoxelAdjacencyList::edge_descriptor EdgeID; 00183 00184 00185 public: 00186 00187 /** \brief Constructor that sets default values for member variables. 00188 * \param[in] voxel_resolution The resolution (in meters) of voxels used 00189 * \param[in] seed_resolution The average size (in meters) of resulting supervoxels 00190 * \param[in] use_single_camera_transform Set to true if point density in cloud falls off with distance from origin (such as with a cloud coming from one stationary camera), set false if input cloud is from multiple captures from multiple locations. 00191 */ 00192 SupervoxelClustering (float voxel_resolution, float seed_resolution, bool use_single_camera_transform = true); 00193 00194 /** \brief This destructor destroys the cloud, normals and search method used for 00195 * finding neighbors. In other words it frees memory. 00196 */ 00197 virtual 00198 ~SupervoxelClustering (); 00199 00200 /** \brief Set the resolution of the octree voxels */ 00201 void 00202 setVoxelResolution (float resolution); 00203 00204 /** \brief Get the resolution of the octree voxels */ 00205 float 00206 getVoxelResolution () const; 00207 00208 /** \brief Set the resolution of the octree seed voxels */ 00209 void 00210 setSeedResolution (float seed_resolution); 00211 00212 /** \brief Get the resolution of the octree seed voxels */ 00213 float 00214 getSeedResolution () const; 00215 00216 /** \brief Set the importance of color for supervoxels */ 00217 void 00218 setColorImportance (float val); 00219 00220 /** \brief Set the importance of spatial distance for supervoxels */ 00221 void 00222 setSpatialImportance (float val); 00223 00224 /** \brief Set the importance of scalar normal product for supervoxels */ 00225 void 00226 setNormalImportance (float val); 00227 00228 /** \brief This method launches the segmentation algorithm and returns the supervoxels that were 00229 * obtained during the segmentation. 00230 * \param[out] supervoxel_clusters A map of labels to pointers to supervoxel structures 00231 */ 00232 virtual void 00233 extract (std::map<uint32_t,typename Supervoxel<PointT>::Ptr > &supervoxel_clusters); 00234 00235 /** \brief This method sets the cloud to be supervoxelized 00236 * \param[in] cloud The cloud to be supervoxelize 00237 */ 00238 virtual void 00239 setInputCloud (typename pcl::PointCloud<PointT>::ConstPtr cloud); 00240 00241 /** \brief This method sets the normals to be used for supervoxels (should be same size as input cloud) 00242 * \param[in] cloud The input normals 00243 */ 00244 virtual void 00245 setNormalCloud (typename NormalCloudT::ConstPtr normal_cloud); 00246 00247 /** \brief This method refines the calculated supervoxels - may only be called after extract 00248 * \param[in] num_itr The number of iterations of refinement to be done (2 or 3 is usually sufficient) 00249 * \param[out] supervoxel_clusters The resulting refined supervoxels 00250 */ 00251 virtual void 00252 refineSupervoxels (int num_itr, std::map<uint32_t,typename Supervoxel<PointT>::Ptr > &supervoxel_clusters); 00253 00254 //////////////////////////////////////////////////////////// 00255 /** \brief Returns an RGB colorized cloud showing superpixels 00256 * Otherwise it returns an empty pointer. 00257 * Points that belong to the same supervoxel have the same color. 00258 * But this function doesn't guarantee that different segments will have different 00259 * color(it's random). Points that are unlabeled will be black 00260 * \note This will expand the label_colors_ vector so that it can accomodate all labels 00261 */ 00262 typename pcl::PointCloud<PointXYZRGBA>::Ptr 00263 getColoredCloud () const; 00264 00265 /** \brief Returns a deep copy of the voxel centroid cloud */ 00266 typename pcl::PointCloud<PointT>::Ptr 00267 getVoxelCentroidCloud () const; 00268 00269 /** \brief Returns labeled cloud 00270 * Points that belong to the same supervoxel have the same label. 00271 * Labels for segments start from 1, unlabled points have label 0 00272 */ 00273 typename pcl::PointCloud<PointXYZL>::Ptr 00274 getLabeledCloud () const; 00275 00276 /** \brief Returns an RGB colorized voxelized cloud showing superpixels 00277 * Otherwise it returns an empty pointer. 00278 * Points that belong to the same supervoxel have the same color. 00279 * But this function doesn't guarantee that different segments will have different 00280 * color(it's random). Points that are unlabeled will be black 00281 * \note This will expand the label_colors_ vector so that it can accomodate all labels 00282 */ 00283 pcl::PointCloud<pcl::PointXYZRGBA>::Ptr 00284 getColoredVoxelCloud () const; 00285 00286 /** \brief Returns labeled voxelized cloud 00287 * Points that belong to the same supervoxel have the same label. 00288 * Labels for segments start from 1, unlabled points have label 0 00289 */ 00290 pcl::PointCloud<pcl::PointXYZL>::Ptr 00291 getLabeledVoxelCloud () const; 00292 00293 /** \brief Gets the adjacency list (Boost Graph library) which gives connections between supervoxels 00294 * \param[out] adjacency_list_arg BGL graph where supervoxel labels are vertices, edges are touching relationships 00295 */ 00296 void 00297 getSupervoxelAdjacencyList (VoxelAdjacencyList &adjacency_list_arg) const; 00298 00299 /** \brief Get a multimap which gives supervoxel adjacency 00300 * \param[out] label_adjacency Multi-Map which maps a supervoxel label to all adjacent supervoxel labels 00301 */ 00302 void 00303 getSupervoxelAdjacency (std::multimap<uint32_t, uint32_t> &label_adjacency) const; 00304 00305 /** \brief Static helper function which returns a pointcloud of normals for the input supervoxels 00306 * \param[in] supervoxel_clusters Supervoxel cluster map coming from this class 00307 * \returns Cloud of PointNormals of the supervoxels 00308 * 00309 */ 00310 static pcl::PointCloud<pcl::PointNormal>::Ptr 00311 makeSupervoxelNormalCloud (std::map<uint32_t,typename Supervoxel<PointT>::Ptr > &supervoxel_clusters); 00312 00313 /** \brief Returns the current maximum (highest) label */ 00314 int 00315 getMaxLabel () const; 00316 00317 private: 00318 00319 /** \brief This method initializes the label_colors_ vector (assigns random colors to labels) 00320 * \note Checks to see if it is already big enough - if so, does not reinitialize it 00321 */ 00322 void 00323 initializeLabelColors (); 00324 00325 /** \brief This method simply checks if it is possible to execute the segmentation algorithm with 00326 * the current settings. If it is possible then it returns true. 00327 */ 00328 virtual bool 00329 prepareForSegmentation (); 00330 00331 /** \brief This selects points to use as initial supervoxel centroids 00332 * \param[out] seed_points The selected points 00333 */ 00334 void 00335 selectInitialSupervoxelSeeds (std::vector<PointT, Eigen::aligned_allocator<PointT> > &seed_points); 00336 00337 /** \brief This method creates the internal supervoxel helpers based on the provided seed points 00338 * \param[in] seed_points The selected points 00339 */ 00340 void 00341 createSupervoxelHelpers (std::vector<PointT, Eigen::aligned_allocator<PointT> > &seed_points); 00342 00343 /** \brief This performs the superpixel evolution */ 00344 void 00345 expandSupervoxels (int depth); 00346 00347 /** \brief This sets the data of the voxels in the tree */ 00348 void 00349 computeVoxelData (); 00350 00351 /** \brief Reseeds the supervoxels by finding the voxel closest to current centroid */ 00352 void 00353 reseedSupervoxels (); 00354 00355 /** \brief Constructs the map of supervoxel clusters from the internal supervoxel helpers */ 00356 void 00357 makeSupervoxels (std::map<uint32_t,typename Supervoxel<PointT>::Ptr > &supervoxel_clusters); 00358 00359 /** \brief Stores the resolution used in the octree */ 00360 float resolution_; 00361 00362 /** \brief Stores the resolution used to seed the superpixels */ 00363 float seed_resolution_; 00364 00365 /** \brief Distance function used for comparing voxelDatas */ 00366 float 00367 voxelDataDistance (const VoxelData &v1, const VoxelData &v2) const; 00368 00369 /** \brief Transform function used to normalize voxel density versus distance from camera */ 00370 void 00371 transformFunction (PointT &p); 00372 00373 /** \brief Contains a KDtree for the voxelized cloud */ 00374 typename pcl::search::KdTree<PointT>::Ptr voxel_kdtree_; 00375 00376 /** \brief Octree Adjacency structure with leaves at voxel resolution */ 00377 typename OctreeAdjacencyT::Ptr adjacency_octree_; 00378 00379 /** \brief Contains the Voxelized centroid Cloud */ 00380 typename PointCloudT::Ptr voxel_centroid_cloud_; 00381 00382 /** \brief Contains the Voxelized centroid Cloud */ 00383 typename NormalCloudT::ConstPtr input_normals_; 00384 00385 /** \brief Importance of color in clustering */ 00386 float color_importance_; 00387 /** \brief Importance of distance from seed center in clustering */ 00388 float spatial_importance_; 00389 /** \brief Importance of similarity in normals for clustering */ 00390 float normal_importance_; 00391 00392 /** \brief Stores the colors used for the superpixel labels*/ 00393 std::vector<uint32_t> label_colors_; 00394 00395 /** \brief Internal storage class for supervoxels 00396 * \note Stores pointers to leaves of clustering internal octree, 00397 * \note so should not be used outside of clustering class 00398 */ 00399 class SupervoxelHelper 00400 { 00401 public: 00402 SupervoxelHelper (uint32_t label, SupervoxelClustering* parent_arg): 00403 label_ (label), 00404 parent_ (parent_arg) 00405 { } 00406 00407 void 00408 addLeaf (LeafContainerT* leaf_arg); 00409 00410 void 00411 removeLeaf (LeafContainerT* leaf_arg); 00412 00413 void 00414 removeAllLeaves (); 00415 00416 void 00417 expand (); 00418 00419 void 00420 refineNormals (); 00421 00422 void 00423 updateCentroid (); 00424 00425 void 00426 getVoxels (typename pcl::PointCloud<PointT>::Ptr &voxels) const; 00427 00428 void 00429 getNormals (typename pcl::PointCloud<Normal>::Ptr &normals) const; 00430 00431 typedef float (SupervoxelClustering::*DistFuncPtr)(const VoxelData &v1, const VoxelData &v2); 00432 00433 uint32_t 00434 getLabel () const 00435 { return label_; } 00436 00437 Eigen::Vector4f 00438 getNormal () const 00439 { return centroid_.normal_; } 00440 00441 Eigen::Vector3f 00442 getRGB () const 00443 { return centroid_.rgb_; } 00444 00445 Eigen::Vector3f 00446 getXYZ () const 00447 { return centroid_.xyz_;} 00448 00449 void 00450 getXYZ (float &x, float &y, float &z) const 00451 { x=centroid_.xyz_[0]; y=centroid_.xyz_[1]; z=centroid_.xyz_[2]; } 00452 00453 void 00454 getRGB (uint32_t &rgba) const 00455 { 00456 rgba = static_cast<uint32_t>(centroid_.rgb_[0]) << 16 | 00457 static_cast<uint32_t>(centroid_.rgb_[1]) << 8 | 00458 static_cast<uint32_t>(centroid_.rgb_[2]); 00459 } 00460 00461 void 00462 getNormal (pcl::Normal &normal_arg) const 00463 { 00464 normal_arg.normal_x = centroid_.normal_[0]; 00465 normal_arg.normal_y = centroid_.normal_[1]; 00466 normal_arg.normal_z = centroid_.normal_[2]; 00467 normal_arg.curvature = centroid_.curvature_; 00468 } 00469 00470 void 00471 getNeighborLabels (std::set<uint32_t> &neighbor_labels) const; 00472 00473 VoxelData 00474 getCentroid () const 00475 { return centroid_; } 00476 00477 00478 size_t 00479 size () const { return leaves_.size (); } 00480 private: 00481 //Stores leaves 00482 std::set<LeafContainerT*> leaves_; 00483 uint32_t label_; 00484 VoxelData centroid_; 00485 SupervoxelClustering* parent_; 00486 00487 00488 }; 00489 00490 typedef boost::ptr_list<SupervoxelHelper> HelperListT; 00491 HelperListT supervoxel_helpers_; 00492 00493 //TODO DEBUG REMOVE 00494 StopWatch timer_; 00495 public: 00496 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00497 00498 00499 00500 }; 00501 00502 } 00503 00504 #ifdef PCL_NO_PRECOMPILE 00505 #include <pcl/segmentation/impl/supervoxel_clustering.hpp> 00506 #endif 00507 00508 #endif
Except where otherwise noted, the PointClouds.org web pages are licensed under Creative Commons Attribution 3.0.
Pages generated on Wed Mar 25 00:25:57 2015