40 #ifndef PCL_SEGMENTATION_SUPERVOXEL_CLUSTERING_HPP_
41 #define PCL_SEGMENTATION_SUPERVOXEL_CLUSTERING_HPP_
43 #include <pcl/segmentation/supervoxel_clustering.h>
44 #include <pcl/common/io.h>
47 template <
typename Po
intT>
49 float seed_resolution)
50 : resolution_(voxel_resolution)
51 , seed_resolution_(seed_resolution)
53 , voxel_centroid_cloud_()
59 template <
typename Po
intT>
63 template <
typename Po
intT>
void
66 if ( cloud->
empty () )
68 PCL_ERROR (
"[pcl::SupervoxelClustering::setInputCloud] Empty cloud set, doing nothing \n");
73 adjacency_octree_->setInputCloud (cloud);
77 template <
typename Po
intT>
void
80 if ( normal_cloud->empty () )
82 PCL_ERROR (
"[pcl::SupervoxelClustering::setNormalCloud] Empty cloud set, doing nothing \n");
86 input_normals_ = normal_cloud;
90 template <
typename Po
intT>
void
96 bool segmentation_is_possible = initCompute ();
97 if ( !segmentation_is_possible )
104 segmentation_is_possible = prepareForSegmentation ();
105 if ( !segmentation_is_possible )
114 selectInitialSupervoxelSeeds (seed_indices);
116 createSupervoxelHelpers (seed_indices);
121 int max_depth =
static_cast<int> (1.8f*seed_resolution_/resolution_);
122 expandSupervoxels (max_depth);
126 makeSupervoxels (supervoxel_clusters);
142 template <
typename Po
intT>
void
145 if (supervoxel_helpers_.empty ())
147 PCL_ERROR (
"[pcl::SupervoxelClustering::refineVoxelNormals] Supervoxels not extracted, doing nothing - (Call extract first!) \n");
151 int max_depth =
static_cast<int> (1.8f*seed_resolution_/resolution_);
152 for (
int i = 0; i < num_itr; ++i)
154 for (
typename HelperListT::iterator sv_itr = supervoxel_helpers_.begin (); sv_itr != supervoxel_helpers_.end (); ++sv_itr)
156 sv_itr->refineNormals ();
159 reseedSupervoxels ();
160 expandSupervoxels (max_depth);
164 makeSupervoxels (supervoxel_clusters);
174 template <
typename Po
intT>
bool
179 if ( input_->points.empty () )
185 if ( (use_default_transform_behaviour_ && input_->isOrganized ())
186 || (!use_default_transform_behaviour_ && use_single_camera_transform_))
187 adjacency_octree_->setTransformFunction ([
this] (
PointT &p) { transformFunction (p); });
189 adjacency_octree_->addPointsFromInputCloud ();
202 template <
typename Po
intT>
void
206 voxel_centroid_cloud_->resize (adjacency_octree_->getLeafCount ());
207 auto leaf_itr = adjacency_octree_->begin ();
208 auto cent_cloud_itr = voxel_centroid_cloud_->begin ();
209 for (
int idx = 0 ; leaf_itr != adjacency_octree_->end (); ++leaf_itr, ++cent_cloud_itr, ++idx)
211 VoxelData& new_voxel_data = (*leaf_itr)->getData ();
213 new_voxel_data.getPoint (*cent_cloud_itr);
215 new_voxel_data.idx_ = idx;
222 assert (input_normals_->size () == input_->size ());
224 auto normal_itr = input_normals_->begin ();
225 for (
auto input_itr = input_->begin (); input_itr != input_->end (); ++input_itr, ++normal_itr)
228 if ( !pcl::isFinite<PointT> (*input_itr))
231 LeafContainerT* leaf = adjacency_octree_->getLeafContainerAtPoint (*input_itr);
234 VoxelData& voxel_data = leaf->getData ();
236 voxel_data.normal_ += normal_itr->getNormalVector4fMap ();
237 voxel_data.curvature_ += normal_itr->curvature;
240 for (leaf_itr = adjacency_octree_->begin (); leaf_itr != adjacency_octree_->end (); ++leaf_itr)
242 VoxelData& voxel_data = (*leaf_itr)->getData ();
243 voxel_data.normal_.normalize ();
244 voxel_data.owner_ =
nullptr;
245 voxel_data.distance_ = std::numeric_limits<float>::max ();
247 int num_points = (*leaf_itr)->getPointCounter ();
248 voxel_data.curvature_ /= num_points;
253 for (leaf_itr = adjacency_octree_->begin (); leaf_itr != adjacency_octree_->end (); ++leaf_itr)
255 VoxelData& new_voxel_data = (*leaf_itr)->getData ();
258 indices.reserve (81);
260 indices.push_back (new_voxel_data.idx_);
261 for (
auto neighb_itr=(*leaf_itr)->cbegin (); neighb_itr!=(*leaf_itr)->cend (); ++neighb_itr)
263 VoxelData& neighb_voxel_data = (*neighb_itr)->getData ();
265 indices.push_back (neighb_voxel_data.idx_);
267 for (
auto neighb_neighb_itr=(*neighb_itr)->cbegin (); neighb_neighb_itr!=(*neighb_itr)->cend (); ++neighb_neighb_itr)
269 VoxelData& neighb2_voxel_data = (*neighb_neighb_itr)->getData ();
270 indices.push_back (neighb2_voxel_data.idx_);
276 new_voxel_data.normal_[3] = 0.0f;
277 new_voxel_data.normal_.normalize ();
278 new_voxel_data.owner_ =
nullptr;
279 new_voxel_data.distance_ = std::numeric_limits<float>::max ();
287 template <
typename Po
intT>
void
292 for (
int i = 1; i < depth; ++i)
295 for (
typename HelperListT::iterator sv_itr = supervoxel_helpers_.begin (); sv_itr != supervoxel_helpers_.end (); ++sv_itr)
301 for (
typename HelperListT::iterator sv_itr = supervoxel_helpers_.begin (); sv_itr != supervoxel_helpers_.end (); )
303 if (sv_itr->size () == 0)
305 sv_itr = supervoxel_helpers_.erase (sv_itr);
309 sv_itr->updateCentroid ();
319 template <
typename Po
intT>
void
322 supervoxel_clusters.clear ();
323 for (
typename HelperListT::iterator sv_itr = supervoxel_helpers_.begin (); sv_itr != supervoxel_helpers_.end (); ++sv_itr)
325 std::uint32_t label = sv_itr->getLabel ();
326 supervoxel_clusters[label].reset (
new Supervoxel<PointT>);
327 sv_itr->getXYZ (supervoxel_clusters[label]->centroid_.x,supervoxel_clusters[label]->centroid_.y,supervoxel_clusters[label]->centroid_.z);
328 sv_itr->getRGB (supervoxel_clusters[label]->centroid_.rgba);
329 sv_itr->getNormal (supervoxel_clusters[label]->normal_);
330 sv_itr->getVoxels (supervoxel_clusters[label]->voxels_);
331 sv_itr->getNormals (supervoxel_clusters[label]->normals_);
337 template <
typename Po
intT>
void
341 supervoxel_helpers_.clear ();
342 for (std::size_t i = 0; i < seed_indices.size (); ++i)
344 supervoxel_helpers_.push_back (
new SupervoxelHelper(i+1,
this));
346 LeafContainerT* seed_leaf = adjacency_octree_->at(seed_indices[i]);
349 supervoxel_helpers_.back ().addLeaf (seed_leaf);
353 PCL_WARN (
"Could not find leaf in pcl::SupervoxelClustering<PointT>::createSupervoxelHelpers - supervoxel will be deleted \n");
359 template <
typename Po
intT>
void
368 seed_octree.setInputCloud (voxel_centroid_cloud_);
369 seed_octree.addPointsFromInputCloud ();
371 std::vector<PointT, Eigen::aligned_allocator<PointT> > voxel_centers;
372 int num_seeds = seed_octree.getOccupiedVoxelCenters(voxel_centers);
375 std::vector<int> seed_indices_orig;
376 seed_indices_orig.resize (num_seeds, 0);
377 seed_indices.clear ();
380 closest_index.resize(1,0);
384 voxel_kdtree_.reset (pcl::search::autoSelectMethod<PointT>(voxel_centroid_cloud_,
false));
387 for (
int i = 0; i < num_seeds; ++i)
389 voxel_kdtree_->nearestKSearch (voxel_centers[i], 1, closest_index,
distance);
390 seed_indices_orig[i] = closest_index[0];
394 std::vector<float> sqr_distances;
395 seed_indices.reserve (seed_indices_orig.size ());
396 float search_radius = 0.5f*seed_resolution_;
399 float min_points = 0.05f * (search_radius)*(search_radius) * 3.1415926536f / (resolution_*resolution_);
400 for (
const auto &index_orig : seed_indices_orig)
402 int num = voxel_kdtree_->radiusSearch (index_orig, search_radius , neighbors, sqr_distances);
403 if ( num > min_points)
405 seed_indices.push_back (index_orig);
415 template <
typename Po
intT>
void
419 for (
typename HelperListT::iterator sv_itr = supervoxel_helpers_.begin (); sv_itr != supervoxel_helpers_.end (); ++sv_itr)
421 sv_itr->removeAllLeaves ();
427 for (
typename HelperListT::iterator sv_itr = supervoxel_helpers_.begin (); sv_itr != supervoxel_helpers_.end (); ++sv_itr)
430 sv_itr->getXYZ (point.x, point.y, point.z);
431 voxel_kdtree_->nearestKSearch (point, 1, closest_index,
distance);
433 LeafContainerT* seed_leaf = adjacency_octree_->at (closest_index[0]);
436 sv_itr->addLeaf (seed_leaf);
440 PCL_WARN (
"Could not find leaf in pcl::SupervoxelClustering<PointT>::reseedSupervoxels - supervoxel will be deleted \n");
447 template <
typename Po
intT>
void
452 p.z = std::log (p.z);
456 template <
typename Po
intT>
float
460 float spatial_dist = (v1.xyz_ - v2.xyz_).norm () / seed_resolution_;
461 float color_dist = (v1.rgb_ - v2.rgb_).norm () / 255.0f;
462 float cos_angle_normal = 1.0f - std::abs (v1.normal_.dot (v2.normal_));
464 return cos_angle_normal * normal_importance_ + color_dist * color_importance_+ spatial_dist * spatial_importance_;
475 template <
typename Po
intT>
void
478 adjacency_list_arg.clear ();
480 std::map <std::uint32_t, VoxelID> label_ID_map;
481 for (
typename HelperListT::const_iterator sv_itr = supervoxel_helpers_.cbegin (); sv_itr != supervoxel_helpers_.cend (); ++sv_itr)
483 VoxelID node_id = add_vertex (adjacency_list_arg);
484 adjacency_list_arg[node_id] = (sv_itr->getLabel ());
485 label_ID_map.insert (std::make_pair (sv_itr->getLabel (), node_id));
488 for (
typename HelperListT::const_iterator sv_itr = supervoxel_helpers_.cbegin (); sv_itr != supervoxel_helpers_.cend (); ++sv_itr)
490 std::uint32_t label = sv_itr->getLabel ();
491 std::set<std::uint32_t> neighbor_labels;
492 sv_itr->getNeighborLabels (neighbor_labels);
493 for (
const unsigned int &neighbor_label : neighbor_labels)
497 VoxelID u = (label_ID_map.find (label))->second;
498 VoxelID v = (label_ID_map.find (neighbor_label))->second;
499 boost::tie (edge, edge_added) = add_edge (u,v,adjacency_list_arg);
503 VoxelData centroid_data = (sv_itr)->getCentroid ();
507 for (
typename HelperListT::const_iterator neighb_itr = supervoxel_helpers_.cbegin (); neighb_itr != supervoxel_helpers_.cend (); ++neighb_itr)
509 if (neighb_itr->getLabel () == neighbor_label)
511 neighb_centroid_data = neighb_itr->getCentroid ();
516 float length = voxelDataDistance (centroid_data, neighb_centroid_data);
517 adjacency_list_arg[edge] = length;
526 template <
typename Po
intT>
void
529 label_adjacency.clear ();
530 for (
typename HelperListT::const_iterator sv_itr = supervoxel_helpers_.cbegin (); sv_itr != supervoxel_helpers_.cend (); ++sv_itr)
532 std::uint32_t label = sv_itr->getLabel ();
533 std::set<std::uint32_t> neighbor_labels;
534 sv_itr->getNeighborLabels (neighbor_labels);
535 for (
const unsigned int &neighbor_label : neighbor_labels)
536 label_adjacency.insert (std::pair<std::uint32_t,std::uint32_t> (label, neighbor_label) );
548 return centroid_copy;
556 for (
typename HelperListT::const_iterator sv_itr = supervoxel_helpers_.cbegin (); sv_itr != supervoxel_helpers_.cend (); ++sv_itr)
559 sv_itr->getVoxels (voxels);
563 auto xyzl_copy_itr = xyzl_copy.
begin ();
564 for ( ; xyzl_copy_itr != xyzl_copy.
end (); ++xyzl_copy_itr)
565 xyzl_copy_itr->label = sv_itr->getLabel ();
567 *labeled_voxel_cloud += xyzl_copy;
570 return labeled_voxel_cloud;
580 auto i_input = input_->begin ();
581 for (
auto i_labeled = labeled_cloud->
begin (); i_labeled != labeled_cloud->
end (); ++i_labeled,++i_input)
583 if ( !pcl::isFinite<PointT> (*i_input))
584 i_labeled->label = 0;
587 i_labeled->label = 0;
588 LeafContainerT *leaf = adjacency_octree_->getLeafContainerAtPoint (*i_input);
591 i_labeled->label = voxel_data.
owner_->getLabel ();
597 return (labeled_cloud);
605 normal_cloud->
resize (supervoxel_clusters.size ());
606 auto normal_cloud_itr = normal_cloud->
begin ();
607 for (
auto sv_itr = supervoxel_clusters.cbegin (), sv_itr_end = supervoxel_clusters.cend ();
608 sv_itr != sv_itr_end; ++sv_itr, ++normal_cloud_itr)
610 (sv_itr->second)->getCentroidPointNormal (*normal_cloud_itr);
616 template <
typename Po
intT>
float
619 return (resolution_);
623 template <
typename Po
intT>
void
626 resolution_ = resolution;
631 template <
typename Po
intT>
float
634 return (seed_resolution_);
638 template <
typename Po
intT>
void
641 seed_resolution_ = seed_resolution;
646 template <
typename Po
intT>
void
649 color_importance_ = val;
653 template <
typename Po
intT>
void
656 spatial_importance_ = val;
660 template <
typename Po
intT>
void
663 normal_importance_ = val;
667 template <
typename Po
intT>
void
670 use_default_transform_behaviour_ =
false;
671 use_single_camera_transform_ = val;
675 template <
typename Po
intT>
int
679 for (
typename HelperListT::const_iterator sv_itr = supervoxel_helpers_.cbegin (); sv_itr != supervoxel_helpers_.cend (); ++sv_itr)
681 int temp = sv_itr->getLabel ();
682 if (temp > max_label)
694 template <
typename Po
intT>
void
697 normal_arg.normal_x = normal_[0];
698 normal_arg.normal_y = normal_[1];
699 normal_arg.normal_z = normal_[2];
707 template <
typename Po
intT>
void
710 leaves_.insert (leaf_arg);
711 VoxelData& voxel_data = leaf_arg->getData ();
712 voxel_data.owner_ =
this;
716 template <
typename Po
intT>
void
719 leaves_.erase (leaf_arg);
723 template <
typename Po
intT>
void
726 for (
auto leaf_itr = leaves_.cbegin (); leaf_itr != leaves_.cend (); ++leaf_itr)
728 VoxelData& voxel = ((*leaf_itr)->getData ());
729 voxel.owner_ =
nullptr;
730 voxel.distance_ = std::numeric_limits<float>::max ();
736 template <
typename Po
intT>
void
741 std::vector<LeafContainerT*> new_owned;
742 new_owned.reserve (leaves_.size () * 9);
744 for (
auto leaf_itr = leaves_.cbegin (); leaf_itr != leaves_.cend (); ++leaf_itr)
747 for (
auto neighb_itr=(*leaf_itr)->cbegin (); neighb_itr!=(*leaf_itr)->cend (); ++neighb_itr)
750 VoxelData& neighbor_voxel = ((*neighb_itr)->getData ());
752 if(neighbor_voxel.owner_ ==
this)
755 float dist = parent_->voxelDataDistance (centroid_, neighbor_voxel);
758 if (dist < neighbor_voxel.distance_)
760 neighbor_voxel.distance_ = dist;
761 if (neighbor_voxel.owner_ !=
this)
763 if (neighbor_voxel.owner_)
764 (neighbor_voxel.owner_)->removeLeaf(*neighb_itr);
765 neighbor_voxel.owner_ =
this;
766 new_owned.push_back (*neighb_itr);
772 for (
auto new_owned_itr = new_owned.cbegin (); new_owned_itr != new_owned.cend (); ++new_owned_itr)
774 leaves_.insert (*new_owned_itr);
779 template <
typename Po
intT>
void
783 for (
auto leaf_itr = leaves_.cbegin (); leaf_itr != leaves_.cend (); ++leaf_itr)
785 VoxelData& voxel_data = (*leaf_itr)->getData ();
787 indices.reserve (81);
789 indices.push_back (voxel_data.idx_);
790 for (
auto neighb_itr=(*leaf_itr)->cbegin (); neighb_itr!=(*leaf_itr)->cend (); ++neighb_itr)
793 VoxelData& neighbor_voxel_data = ((*neighb_itr)->getData ());
795 if (neighbor_voxel_data.owner_ ==
this)
797 indices.push_back (neighbor_voxel_data.idx_);
799 for (
auto neighb_neighb_itr=(*neighb_itr)->cbegin (); neighb_neighb_itr!=(*neighb_itr)->cend (); ++neighb_neighb_itr)
801 VoxelData& neighb_neighb_voxel_data = (*neighb_neighb_itr)->getData ();
802 if (neighb_neighb_voxel_data.owner_ ==
this)
803 indices.push_back (neighb_neighb_voxel_data.idx_);
812 voxel_data.normal_[3] = 0.0f;
813 voxel_data.normal_.normalize ();
818 template <
typename Po
intT>
void
821 centroid_.normal_ = Eigen::Vector4f::Zero ();
822 centroid_.xyz_ = Eigen::Vector3f::Zero ();
823 centroid_.rgb_ = Eigen::Vector3f::Zero ();
824 for (
auto leaf_itr = leaves_.cbegin (); leaf_itr != leaves_.cend (); ++leaf_itr)
826 const VoxelData& leaf_data = (*leaf_itr)->getData ();
827 centroid_.normal_ += leaf_data.normal_;
828 centroid_.xyz_ += leaf_data.xyz_;
829 centroid_.rgb_ += leaf_data.rgb_;
831 centroid_.normal_.normalize ();
832 centroid_.xyz_ /=
static_cast<float> (leaves_.size ());
833 centroid_.rgb_ /=
static_cast<float> (leaves_.size ());
837 template <
typename Po
intT>
void
842 voxels->
resize (leaves_.size ());
843 auto voxel_itr = voxels->
begin ();
844 for (
auto leaf_itr = leaves_.cbegin (); leaf_itr != leaves_.cend (); ++leaf_itr, ++voxel_itr)
846 const VoxelData& leaf_data = (*leaf_itr)->getData ();
847 leaf_data.getPoint (*voxel_itr);
852 template <
typename Po
intT>
void
857 normals->
resize (leaves_.size ());
858 auto normal_itr = normals->
begin ();
859 for (
auto leaf_itr = leaves_.cbegin (); leaf_itr != leaves_.cend (); ++leaf_itr, ++normal_itr)
861 const VoxelData& leaf_data = (*leaf_itr)->getData ();
862 leaf_data.getNormal (*normal_itr);
867 template <
typename Po
intT>
void
870 neighbor_labels.clear ();
872 for (
auto leaf_itr = leaves_.cbegin (); leaf_itr != leaves_.cend (); ++leaf_itr)
875 for (
auto neighb_itr=(*leaf_itr)->cbegin (); neighb_itr!=(*leaf_itr)->cend (); ++neighb_itr)
878 VoxelData& neighbor_voxel = ((*neighb_itr)->getData ());
880 if (neighbor_voxel.owner_ !=
this && neighbor_voxel.owner_)
882 neighbor_labels.insert (neighbor_voxel.owner_->getLabel ());
PointCloud represents the base class in PCL for storing collections of 3D points.
void resize(std::size_t count)
Resizes the container to contain count elements.
void clear()
Removes all points in a cloud and sets the width and height to 0.
shared_ptr< PointCloud< PointT > > Ptr
iterator begin() noexcept
shared_ptr< const PointCloud< PointT > > ConstPtr
VoxelData is a structure used for storing data within a pcl::octree::OctreePointCloudAdjacencyContain...
SupervoxelHelper * owner_
void getNormal(Normal &normal_arg) const
Gets the data of in the form of a normal.
Implements a supervoxel algorithm based on voxel structure, normals, and rgb values.
static pcl::PointCloud< pcl::PointNormal >::Ptr makeSupervoxelNormalCloud(std::map< std::uint32_t, typename Supervoxel< PointT >::Ptr > &supervoxel_clusters)
Static helper function which returns a pointcloud of normals for the input supervoxels.
VoxelAdjacencyList::edge_descriptor EdgeID
int getMaxLabel() const
Returns the current maximum (highest) label.
virtual void refineSupervoxels(int num_itr, std::map< std::uint32_t, typename Supervoxel< PointT >::Ptr > &supervoxel_clusters)
This method refines the calculated supervoxels - may only be called after extract.
void setSpatialImportance(float val)
Set the importance of spatial distance for supervoxels.
float getVoxelResolution() const
Get the resolution of the octree voxels.
virtual void setNormalCloud(typename NormalCloudT::ConstPtr normal_cloud)
This method sets the normals to be used for supervoxels (should be same size as input cloud)
void setColorImportance(float val)
Set the importance of color for supervoxels.
pcl::PointCloud< pcl::PointXYZL >::Ptr getLabeledVoxelCloud() const
Returns labeled voxelized cloud Points that belong to the same supervoxel have the same label.
void setVoxelResolution(float resolution)
Set the resolution of the octree voxels.
void setInputCloud(const typename pcl::PointCloud< PointT >::ConstPtr &cloud) override
This method sets the cloud to be supervoxelized.
virtual void extract(std::map< std::uint32_t, typename Supervoxel< PointT >::Ptr > &supervoxel_clusters)
This method launches the segmentation algorithm and returns the supervoxels that were obtained during...
boost::adjacency_list< boost::setS, boost::setS, boost::undirectedS, std::uint32_t, float > VoxelAdjacencyList
pcl::octree::OctreePointCloudAdjacency< PointT, LeafContainerT > OctreeAdjacencyT
pcl::PointCloud< PointT >::Ptr getVoxelCentroidCloud() const
Returns a deep copy of the voxel centroid cloud.
void setSeedResolution(float seed_resolution)
Set the resolution of the octree seed voxels.
void getSupervoxelAdjacency(std::multimap< std::uint32_t, std::uint32_t > &label_adjacency) const
Get a multimap which gives supervoxel adjacency.
void setUseSingleCameraTransform(bool val)
Set whether or not to use the single camera transform.
SupervoxelClustering(float voxel_resolution, float seed_resolution)
Constructor that sets default values for member variables.
void getSupervoxelAdjacencyList(VoxelAdjacencyList &adjacency_list_arg) const
Gets the adjacency list (Boost Graph library) which gives connections between supervoxels.
VoxelAdjacencyList::vertex_descriptor VoxelID
~SupervoxelClustering() override
This destructor destroys the cloud, normals and search method used for finding neighbors.
float getSeedResolution() const
Get the resolution of the octree seed voxels.
void setNormalImportance(float val)
Set the importance of scalar normal product for supervoxels.
pcl::PointCloud< PointXYZL >::Ptr getLabeledCloud() const
Returns labeled cloud Points that belong to the same supervoxel have the same label.
shared_ptr< Supervoxel< PointT > > Ptr
Octree adjacency leaf container class- stores a list of pointers to neighbors, number of points added...
DataT & getData()
Returns a reference to the data member to access it without copying.
Octree pointcloud search class
void copyPointCloud(const pcl::PointCloud< PointInT > &cloud_in, pcl::PointCloud< PointOutT > &cloud_out)
Copy all the fields from a given point cloud into a new point cloud.
void flipNormalTowardsViewpoint(const PointT &point, float vp_x, float vp_y, float vp_z, Eigen::Matrix< Scalar, 4, 1 > &normal)
Flip (in place) the estimated normal of a point towards a given viewpoint.
bool computePointNormal(const pcl::PointCloud< PointT > &cloud, Eigen::Vector4f &plane_parameters, float &curvature)
Compute the Least-Squares plane fit for a given set of points, and return the estimated plane paramet...
float distance(const PointT &p1, const PointT &p2)
IndicesAllocator<> Indices
Type used for indices in PCL.
A point structure representing normal coordinates and the surface curvature estimate.
A point structure representing Euclidean xyz coordinates, and the RGB color.