/* * Software License Agreement (BSD License) * * Point Cloud Library (PCL) - www.pointclouds.org * Copyright (c) 2012, Jeremie Papon * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of Willow Garage, Inc. nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Author : jpapon@gmail.com * Email : jpapon@gmail.com */ #pragma once #include #include #include // for adjacency_list namespace pcl { namespace octree { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** \brief @b Octree pointcloud voxel class which maintains adjacency information for * its voxels. * * This pointcloud octree class generates an octree from a point cloud (zero-copy). The * octree pointcloud is initialized with its voxel resolution. Its bounding box is * automatically adjusted or can be predefined. * * The OctreePointCloudAdjacencyContainer class can be used to store data in leaf nodes. * * An optional transform function can be provided which changes how the voxel grid is * computed - this can be used to, for example, make voxel bins larger as they increase * in distance from the origin (camera). \note See SupervoxelClustering for an example * of how to provide a transform function. * * If used in academic work, please cite: * * - J. Papon, A. Abramov, M. Schoeler, F. Woergoetter * Voxel Cloud Connectivity Segmentation - Supervoxels from PointClouds * In Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition * (CVPR) 2013 * * \ingroup octree * \author Jeremie Papon (jpapon@gmail.com) */ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// template , typename BranchContainerT = OctreeContainerEmpty> class OctreePointCloudAdjacency : public OctreePointCloud { public: using OctreeBaseT = OctreeBase; using OctreeAdjacencyT = OctreePointCloudAdjacency; using Ptr = shared_ptr; using ConstPtr = shared_ptr; using OctreePointCloudT = OctreePointCloud; using LeafNode = typename OctreePointCloudT::LeafNode; using BranchNode = typename OctreePointCloudT::BranchNode; using PointCloud = pcl::PointCloud; using PointCloudPtr = typename PointCloud::Ptr; using PointCloudConstPtr = typename PointCloud::ConstPtr; // BGL graph using VoxelAdjacencyList = boost:: adjacency_list; using VoxelID = typename VoxelAdjacencyList::vertex_descriptor; using EdgeID = typename VoxelAdjacencyList::edge_descriptor; // Leaf vector - pointers to all leaves using LeafVectorT = std::vector; // Fast leaf iterators that don't require traversing tree using iterator = typename LeafVectorT::iterator; using const_iterator = typename LeafVectorT::const_iterator; inline iterator begin() { return (leaf_vector_.begin()); } inline iterator end() { return (leaf_vector_.end()); } inline LeafContainerT* at(std::size_t idx) { return leaf_vector_.at(idx); } // Size of neighbors inline std::size_t size() const { return leaf_vector_.size(); } /** \brief Constructor. * * \param[in] resolution_arg Octree resolution at lowest octree level (voxel size) */ OctreePointCloudAdjacency(const double resolution_arg); /** \brief Adds points from cloud to the octree. * * \note This overrides addPointsFromInputCloud() from the OctreePointCloud class. */ void addPointsFromInputCloud(); /** \brief Gets the leaf container for a given point. * * \param[in] point_arg Point to search for * * \returns Pointer to the leaf container - null if no leaf container found. */ LeafContainerT* getLeafContainerAtPoint(const PointT& point_arg) const; /** \brief Computes an adjacency graph of voxel relations. * * \warning This slows down rapidly as cloud size increases due to the number of * edges. * * \param[out] voxel_adjacency_graph Boost Graph Library Adjacency graph of the voxel * touching relationships. Vertices are PointT, edges represent touching, and edge * lengths are the distance between the points. */ void computeVoxelAdjacencyGraph(VoxelAdjacencyList& voxel_adjacency_graph); /** \brief Sets a point transform (and inverse) used to transform the space of the * input cloud. * * This is useful for changing how adjacency is calculated - such as relaxing the * adjacency criterion for points further from the camera. * * \param[in] transform_func A boost:function pointer to the transform to be used. The * transform must have one parameter (a point) which it modifies in place. */ void setTransformFunction(std::function transform_func) { transform_func_ = transform_func; } /** \brief Tests whether input point is occluded from specified camera point by other * voxels. * * \param[in] point_arg Point to test for * \param[in] camera_pos Position of camera, defaults to origin * * \returns True if path to camera is blocked by a voxel, false otherwise. */ bool testForOcclusion(const PointT& point_arg, const PointXYZ& camera_pos = PointXYZ(0, 0, 0)); protected: /** \brief Add point at index from input pointcloud dataset to octree. * * \param[in] point_idx_arg The index representing the point in the dataset given by * setInputCloud() to be added * * \note This virtual implementation allows the use of a transform function to compute * keys. */ void addPointIdx(uindex_t point_idx_arg) override; /** \brief Fills in the neighbors fields for new voxels. * * \param[in] key_arg Key of the voxel to check neighbors for * \param[in] leaf_container Pointer to container of the leaf to check neighbors for */ void computeNeighbors(OctreeKey& key_arg, LeafContainerT* leaf_container); /** \brief Generates octree key for specified point (uses transform if provided). * * \param[in] point_arg Point to generate key for * \param[out] key_arg Resulting octree key */ void genOctreeKeyforPoint(const PointT& point_arg, OctreeKey& key_arg) const; private: /** \brief Add point at given index from input point cloud to octree. * * Index will be also added to indices vector. This functionality is not enabled for * adjacency octree. */ using OctreePointCloudT::addPointFromCloud; /** \brief Add point simultaneously to octree and input point cloud. * * This functionality is not enabled for adjacency octree. */ using OctreePointCloudT::addPointToCloud; using OctreePointCloudT::input_; using OctreePointCloudT::max_x_; using OctreePointCloudT::max_y_; using OctreePointCloudT::max_z_; using OctreePointCloudT::min_x_; using OctreePointCloudT::min_y_; using OctreePointCloudT::min_z_; using OctreePointCloudT::resolution_; /// Local leaf pointer vector used to make iterating through leaves fast. LeafVectorT leaf_vector_; std::function transform_func_; }; } // namespace octree } // namespace pcl // Note: Do not precompile this octree type because it is typically used with custom // leaf containers. #include