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);
385 voxel_kdtree_ ->setInputCloud (voxel_centroid_cloud_);
388 for (
int i = 0; i < num_seeds; ++i)
390 voxel_kdtree_->nearestKSearch (voxel_centers[i], 1, closest_index,
distance);
391 seed_indices_orig[i] = closest_index[0];
395 std::vector<float> sqr_distances;
396 seed_indices.reserve (seed_indices_orig.size ());
397 float search_radius = 0.5f*seed_resolution_;
400 float min_points = 0.05f * (search_radius)*(search_radius) * 3.1415926536f / (resolution_*resolution_);
401 for (
const auto &index_orig : seed_indices_orig)
403 int num = voxel_kdtree_->radiusSearch (index_orig, search_radius , neighbors, sqr_distances);
404 if ( num > min_points)
406 seed_indices.push_back (index_orig);
416 template <
typename Po
intT>
void
420 for (
typename HelperListT::iterator sv_itr = supervoxel_helpers_.begin (); sv_itr != supervoxel_helpers_.end (); ++sv_itr)
422 sv_itr->removeAllLeaves ();
428 for (
typename HelperListT::iterator sv_itr = supervoxel_helpers_.begin (); sv_itr != supervoxel_helpers_.end (); ++sv_itr)
431 sv_itr->getXYZ (point.x, point.y, point.z);
432 voxel_kdtree_->nearestKSearch (point, 1, closest_index,
distance);
434 LeafContainerT* seed_leaf = adjacency_octree_->at (closest_index[0]);
437 sv_itr->addLeaf (seed_leaf);
441 PCL_WARN (
"Could not find leaf in pcl::SupervoxelClustering<PointT>::reseedSupervoxels - supervoxel will be deleted \n");
448 template <
typename Po
intT>
void
453 p.z = std::log (p.z);
457 template <
typename Po
intT>
float
461 float spatial_dist = (v1.xyz_ - v2.xyz_).norm () / seed_resolution_;
462 float color_dist = (v1.rgb_ - v2.rgb_).norm () / 255.0f;
463 float cos_angle_normal = 1.0f - std::abs (v1.normal_.dot (v2.normal_));
465 return cos_angle_normal * normal_importance_ + color_dist * color_importance_+ spatial_dist * spatial_importance_;
476 template <
typename Po
intT>
void
479 adjacency_list_arg.clear ();
481 std::map <std::uint32_t, VoxelID> label_ID_map;
482 for (
typename HelperListT::const_iterator sv_itr = supervoxel_helpers_.cbegin (); sv_itr != supervoxel_helpers_.cend (); ++sv_itr)
484 VoxelID node_id = add_vertex (adjacency_list_arg);
485 adjacency_list_arg[node_id] = (sv_itr->getLabel ());
486 label_ID_map.insert (std::make_pair (sv_itr->getLabel (), node_id));
489 for (
typename HelperListT::const_iterator sv_itr = supervoxel_helpers_.cbegin (); sv_itr != supervoxel_helpers_.cend (); ++sv_itr)
491 std::uint32_t label = sv_itr->getLabel ();
492 std::set<std::uint32_t> neighbor_labels;
493 sv_itr->getNeighborLabels (neighbor_labels);
494 for (
const unsigned int &neighbor_label : neighbor_labels)
498 VoxelID u = (label_ID_map.find (label))->second;
499 VoxelID v = (label_ID_map.find (neighbor_label))->second;
500 boost::tie (edge, edge_added) = add_edge (u,v,adjacency_list_arg);
504 VoxelData centroid_data = (sv_itr)->getCentroid ();
508 for (
typename HelperListT::const_iterator neighb_itr = supervoxel_helpers_.cbegin (); neighb_itr != supervoxel_helpers_.cend (); ++neighb_itr)
510 if (neighb_itr->getLabel () == neighbor_label)
512 neighb_centroid_data = neighb_itr->getCentroid ();
517 float length = voxelDataDistance (centroid_data, neighb_centroid_data);
518 adjacency_list_arg[edge] = length;
527 template <
typename Po
intT>
void
530 label_adjacency.clear ();
531 for (
typename HelperListT::const_iterator sv_itr = supervoxel_helpers_.cbegin (); sv_itr != supervoxel_helpers_.cend (); ++sv_itr)
533 std::uint32_t label = sv_itr->getLabel ();
534 std::set<std::uint32_t> neighbor_labels;
535 sv_itr->getNeighborLabels (neighbor_labels);
536 for (
const unsigned int &neighbor_label : neighbor_labels)
537 label_adjacency.insert (std::pair<std::uint32_t,std::uint32_t> (label, neighbor_label) );
549 return centroid_copy;
557 for (
typename HelperListT::const_iterator sv_itr = supervoxel_helpers_.cbegin (); sv_itr != supervoxel_helpers_.cend (); ++sv_itr)
560 sv_itr->getVoxels (voxels);
564 auto xyzl_copy_itr = xyzl_copy.
begin ();
565 for ( ; xyzl_copy_itr != xyzl_copy.
end (); ++xyzl_copy_itr)
566 xyzl_copy_itr->label = sv_itr->getLabel ();
568 *labeled_voxel_cloud += xyzl_copy;
571 return labeled_voxel_cloud;
581 auto i_input = input_->begin ();
582 for (
auto i_labeled = labeled_cloud->
begin (); i_labeled != labeled_cloud->
end (); ++i_labeled,++i_input)
584 if ( !pcl::isFinite<PointT> (*i_input))
585 i_labeled->label = 0;
588 i_labeled->label = 0;
589 LeafContainerT *leaf = adjacency_octree_->getLeafContainerAtPoint (*i_input);
592 i_labeled->label = voxel_data.
owner_->getLabel ();
598 return (labeled_cloud);
606 normal_cloud->
resize (supervoxel_clusters.size ());
607 auto normal_cloud_itr = normal_cloud->
begin ();
608 for (
auto sv_itr = supervoxel_clusters.cbegin (), sv_itr_end = supervoxel_clusters.cend ();
609 sv_itr != sv_itr_end; ++sv_itr, ++normal_cloud_itr)
611 (sv_itr->second)->getCentroidPointNormal (*normal_cloud_itr);
617 template <
typename Po
intT>
float
620 return (resolution_);
624 template <
typename Po
intT>
void
627 resolution_ = resolution;
632 template <
typename Po
intT>
float
635 return (seed_resolution_);
639 template <
typename Po
intT>
void
642 seed_resolution_ = seed_resolution;
647 template <
typename Po
intT>
void
650 color_importance_ = val;
654 template <
typename Po
intT>
void
657 spatial_importance_ = val;
661 template <
typename Po
intT>
void
664 normal_importance_ = val;
668 template <
typename Po
intT>
void
671 use_default_transform_behaviour_ =
false;
672 use_single_camera_transform_ = val;
676 template <
typename Po
intT>
int
680 for (
typename HelperListT::const_iterator sv_itr = supervoxel_helpers_.cbegin (); sv_itr != supervoxel_helpers_.cend (); ++sv_itr)
682 int temp = sv_itr->getLabel ();
683 if (temp > max_label)
731 template<
typename Po
intT>
void
735 point_arg.x = xyz_[0];
736 point_arg.y = xyz_[1];
737 point_arg.z = xyz_[2];
741 template <
typename Po
intT>
void
744 normal_arg.normal_x = normal_[0];
745 normal_arg.normal_y = normal_[1];
746 normal_arg.normal_z = normal_[2];
754 template <
typename Po
intT>
void
757 leaves_.insert (leaf_arg);
758 VoxelData& voxel_data = leaf_arg->getData ();
759 voxel_data.owner_ =
this;
763 template <
typename Po
intT>
void
766 leaves_.erase (leaf_arg);
770 template <
typename Po
intT>
void
773 for (
auto leaf_itr = leaves_.cbegin (); leaf_itr != leaves_.cend (); ++leaf_itr)
775 VoxelData& voxel = ((*leaf_itr)->getData ());
776 voxel.owner_ =
nullptr;
777 voxel.distance_ = std::numeric_limits<float>::max ();
783 template <
typename Po
intT>
void
788 std::vector<LeafContainerT*> new_owned;
789 new_owned.reserve (leaves_.size () * 9);
791 for (
auto leaf_itr = leaves_.cbegin (); leaf_itr != leaves_.cend (); ++leaf_itr)
794 for (
auto neighb_itr=(*leaf_itr)->cbegin (); neighb_itr!=(*leaf_itr)->cend (); ++neighb_itr)
797 VoxelData& neighbor_voxel = ((*neighb_itr)->getData ());
799 if(neighbor_voxel.owner_ ==
this)
802 float dist = parent_->voxelDataDistance (centroid_, neighbor_voxel);
805 if (dist < neighbor_voxel.distance_)
807 neighbor_voxel.distance_ = dist;
808 if (neighbor_voxel.owner_ !=
this)
810 if (neighbor_voxel.owner_)
811 (neighbor_voxel.owner_)->removeLeaf(*neighb_itr);
812 neighbor_voxel.owner_ =
this;
813 new_owned.push_back (*neighb_itr);
819 for (
auto new_owned_itr = new_owned.cbegin (); new_owned_itr != new_owned.cend (); ++new_owned_itr)
821 leaves_.insert (*new_owned_itr);
826 template <
typename Po
intT>
void
830 for (
auto leaf_itr = leaves_.cbegin (); leaf_itr != leaves_.cend (); ++leaf_itr)
832 VoxelData& voxel_data = (*leaf_itr)->getData ();
834 indices.reserve (81);
836 indices.push_back (voxel_data.idx_);
837 for (
auto neighb_itr=(*leaf_itr)->cbegin (); neighb_itr!=(*leaf_itr)->cend (); ++neighb_itr)
840 VoxelData& neighbor_voxel_data = ((*neighb_itr)->getData ());
842 if (neighbor_voxel_data.owner_ ==
this)
844 indices.push_back (neighbor_voxel_data.idx_);
846 for (
auto neighb_neighb_itr=(*neighb_itr)->cbegin (); neighb_neighb_itr!=(*neighb_itr)->cend (); ++neighb_neighb_itr)
848 VoxelData& neighb_neighb_voxel_data = (*neighb_neighb_itr)->getData ();
849 if (neighb_neighb_voxel_data.owner_ ==
this)
850 indices.push_back (neighb_neighb_voxel_data.idx_);
859 voxel_data.normal_[3] = 0.0f;
860 voxel_data.normal_.normalize ();
865 template <
typename Po
intT>
void
868 centroid_.normal_ = Eigen::Vector4f::Zero ();
869 centroid_.xyz_ = Eigen::Vector3f::Zero ();
870 centroid_.rgb_ = Eigen::Vector3f::Zero ();
871 for (
auto leaf_itr = leaves_.cbegin (); leaf_itr != leaves_.cend (); ++leaf_itr)
873 const VoxelData& leaf_data = (*leaf_itr)->getData ();
874 centroid_.normal_ += leaf_data.normal_;
875 centroid_.xyz_ += leaf_data.xyz_;
876 centroid_.rgb_ += leaf_data.rgb_;
878 centroid_.normal_.normalize ();
879 centroid_.xyz_ /=
static_cast<float> (leaves_.size ());
880 centroid_.rgb_ /=
static_cast<float> (leaves_.size ());
884 template <
typename Po
intT>
void
889 voxels->
resize (leaves_.size ());
890 auto voxel_itr = voxels->
begin ();
891 for (
auto leaf_itr = leaves_.cbegin (); leaf_itr != leaves_.cend (); ++leaf_itr, ++voxel_itr)
893 const VoxelData& leaf_data = (*leaf_itr)->getData ();
894 leaf_data.getPoint (*voxel_itr);
899 template <
typename Po
intT>
void
904 normals->
resize (leaves_.size ());
905 auto normal_itr = normals->
begin ();
906 for (
auto leaf_itr = leaves_.cbegin (); leaf_itr != leaves_.cend (); ++leaf_itr, ++normal_itr)
908 const VoxelData& leaf_data = (*leaf_itr)->getData ();
909 leaf_data.getNormal (*normal_itr);
914 template <
typename Po
intT>
void
917 neighbor_labels.clear ();
919 for (
auto leaf_itr = leaves_.cbegin (); leaf_itr != leaves_.cend (); ++leaf_itr)
922 for (
auto neighb_itr=(*leaf_itr)->cbegin (); neighb_itr!=(*leaf_itr)->cend (); ++neighb_itr)
925 VoxelData& neighbor_voxel = ((*neighb_itr)->getData ());
927 if (neighbor_voxel.owner_ !=
this && neighbor_voxel.owner_)
929 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...
void getPoint(PointT &point_arg) const
Gets the data of in the form of a point.
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
search::KdTree is a wrapper class which inherits the pcl::KdTree class for performing search function...
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.
A point structure representing Euclidean xyz coordinates, and the RGBA color.
A point structure representing Euclidean xyz coordinates, and the RGB color.