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 resolution_ (voxel_resolution),
50 seed_resolution_ (seed_resolution),
52 voxel_centroid_cloud_ (),
53 color_importance_ (0.1f),
54 spatial_importance_ (0.4f),
55 normal_importance_ (1.0f),
56 use_default_transform_behaviour_ (true)
62 template <
typename Po
intT>
66 template <
typename Po
intT>
void
69 if ( cloud->
empty () )
71 PCL_ERROR (
"[pcl::SupervoxelClustering::setInputCloud] Empty cloud set, doing nothing \n");
76 adjacency_octree_->setInputCloud (cloud);
80 template <
typename Po
intT>
void
83 if ( normal_cloud->empty () )
85 PCL_ERROR (
"[pcl::SupervoxelClustering::setNormalCloud] Empty cloud set, doing nothing \n");
89 input_normals_ = normal_cloud;
93 template <
typename Po
intT>
void
99 bool segmentation_is_possible = initCompute ();
100 if ( !segmentation_is_possible )
107 segmentation_is_possible = prepareForSegmentation ();
108 if ( !segmentation_is_possible )
117 selectInitialSupervoxelSeeds (seed_indices);
119 createSupervoxelHelpers (seed_indices);
124 int max_depth =
static_cast<int> (1.8f*seed_resolution_/resolution_);
125 expandSupervoxels (max_depth);
129 makeSupervoxels (supervoxel_clusters);
145 template <
typename Po
intT>
void
148 if (supervoxel_helpers_.empty ())
150 PCL_ERROR (
"[pcl::SupervoxelClustering::refineVoxelNormals] Supervoxels not extracted, doing nothing - (Call extract first!) \n");
154 int max_depth =
static_cast<int> (1.8f*seed_resolution_/resolution_);
155 for (
int i = 0; i < num_itr; ++i)
157 for (
typename HelperListT::iterator sv_itr = supervoxel_helpers_.begin (); sv_itr != supervoxel_helpers_.end (); ++sv_itr)
159 sv_itr->refineNormals ();
162 reseedSupervoxels ();
163 expandSupervoxels (max_depth);
167 makeSupervoxels (supervoxel_clusters);
177 template <
typename Po
intT>
bool
182 if ( input_->points.empty () )
188 if ( (use_default_transform_behaviour_ && input_->isOrganized ())
189 || (!use_default_transform_behaviour_ && use_single_camera_transform_))
190 adjacency_octree_->setTransformFunction ([
this] (
PointT &p) { transformFunction (p); });
192 adjacency_octree_->addPointsFromInputCloud ();
205 template <
typename Po
intT>
void
209 voxel_centroid_cloud_->resize (adjacency_octree_->getLeafCount ());
210 auto leaf_itr = adjacency_octree_->begin ();
211 auto cent_cloud_itr = voxel_centroid_cloud_->begin ();
212 for (
int idx = 0 ; leaf_itr != adjacency_octree_->end (); ++leaf_itr, ++cent_cloud_itr, ++idx)
214 VoxelData& new_voxel_data = (*leaf_itr)->getData ();
216 new_voxel_data.getPoint (*cent_cloud_itr);
218 new_voxel_data.idx_ = idx;
225 assert (input_normals_->size () == input_->size ());
227 auto normal_itr = input_normals_->begin ();
228 for (
auto input_itr = input_->begin (); input_itr != input_->end (); ++input_itr, ++normal_itr)
231 if ( !pcl::isFinite<PointT> (*input_itr))
234 LeafContainerT* leaf = adjacency_octree_->getLeafContainerAtPoint (*input_itr);
237 VoxelData& voxel_data = leaf->getData ();
239 voxel_data.normal_ += normal_itr->getNormalVector4fMap ();
240 voxel_data.curvature_ += normal_itr->curvature;
243 for (leaf_itr = adjacency_octree_->begin (); leaf_itr != adjacency_octree_->end (); ++leaf_itr)
245 VoxelData& voxel_data = (*leaf_itr)->getData ();
246 voxel_data.normal_.normalize ();
247 voxel_data.owner_ =
nullptr;
248 voxel_data.distance_ = std::numeric_limits<float>::max ();
250 int num_points = (*leaf_itr)->getPointCounter ();
251 voxel_data.curvature_ /= num_points;
256 for (leaf_itr = adjacency_octree_->begin (); leaf_itr != adjacency_octree_->end (); ++leaf_itr)
258 VoxelData& new_voxel_data = (*leaf_itr)->getData ();
261 indices.reserve (81);
263 indices.push_back (new_voxel_data.idx_);
264 for (
auto neighb_itr=(*leaf_itr)->cbegin (); neighb_itr!=(*leaf_itr)->cend (); ++neighb_itr)
266 VoxelData& neighb_voxel_data = (*neighb_itr)->getData ();
268 indices.push_back (neighb_voxel_data.idx_);
270 for (
auto neighb_neighb_itr=(*neighb_itr)->cbegin (); neighb_neighb_itr!=(*neighb_itr)->cend (); ++neighb_neighb_itr)
272 VoxelData& neighb2_voxel_data = (*neighb_neighb_itr)->getData ();
273 indices.push_back (neighb2_voxel_data.idx_);
279 new_voxel_data.normal_[3] = 0.0f;
280 new_voxel_data.normal_.normalize ();
281 new_voxel_data.owner_ =
nullptr;
282 new_voxel_data.distance_ = std::numeric_limits<float>::max ();
290 template <
typename Po
intT>
void
295 for (
int i = 1; i < depth; ++i)
298 for (
typename HelperListT::iterator sv_itr = supervoxel_helpers_.begin (); sv_itr != supervoxel_helpers_.end (); ++sv_itr)
304 for (
typename HelperListT::iterator sv_itr = supervoxel_helpers_.begin (); sv_itr != supervoxel_helpers_.end (); )
306 if (sv_itr->size () == 0)
308 sv_itr = supervoxel_helpers_.erase (sv_itr);
312 sv_itr->updateCentroid ();
322 template <
typename Po
intT>
void
325 supervoxel_clusters.clear ();
326 for (
typename HelperListT::iterator sv_itr = supervoxel_helpers_.begin (); sv_itr != supervoxel_helpers_.end (); ++sv_itr)
328 std::uint32_t label = sv_itr->getLabel ();
329 supervoxel_clusters[label].reset (
new Supervoxel<PointT>);
330 sv_itr->getXYZ (supervoxel_clusters[label]->centroid_.x,supervoxel_clusters[label]->centroid_.y,supervoxel_clusters[label]->centroid_.z);
331 sv_itr->getRGB (supervoxel_clusters[label]->centroid_.rgba);
332 sv_itr->getNormal (supervoxel_clusters[label]->normal_);
333 sv_itr->getVoxels (supervoxel_clusters[label]->voxels_);
334 sv_itr->getNormals (supervoxel_clusters[label]->normals_);
340 template <
typename Po
intT>
void
344 supervoxel_helpers_.clear ();
345 for (std::size_t i = 0; i < seed_indices.size (); ++i)
347 supervoxel_helpers_.push_back (
new SupervoxelHelper(i+1,
this));
349 LeafContainerT* seed_leaf = adjacency_octree_->at(seed_indices[i]);
352 supervoxel_helpers_.back ().addLeaf (seed_leaf);
356 PCL_WARN (
"Could not find leaf in pcl::SupervoxelClustering<PointT>::createSupervoxelHelpers - supervoxel will be deleted \n");
362 template <
typename Po
intT>
void
371 seed_octree.setInputCloud (voxel_centroid_cloud_);
372 seed_octree.addPointsFromInputCloud ();
374 std::vector<PointT, Eigen::aligned_allocator<PointT> > voxel_centers;
375 int num_seeds = seed_octree.getOccupiedVoxelCenters(voxel_centers);
378 std::vector<int> seed_indices_orig;
379 seed_indices_orig.resize (num_seeds, 0);
380 seed_indices.clear ();
383 closest_index.resize(1,0);
388 voxel_kdtree_ ->setInputCloud (voxel_centroid_cloud_);
391 for (
int i = 0; i < num_seeds; ++i)
393 voxel_kdtree_->nearestKSearch (voxel_centers[i], 1, closest_index,
distance);
394 seed_indices_orig[i] = closest_index[0];
398 std::vector<float> sqr_distances;
399 seed_indices.reserve (seed_indices_orig.size ());
400 float search_radius = 0.5f*seed_resolution_;
403 float min_points = 0.05f * (search_radius)*(search_radius) * 3.1415926536f / (resolution_*resolution_);
404 for (
const auto &index_orig : seed_indices_orig)
406 int num = voxel_kdtree_->radiusSearch (index_orig, search_radius , neighbors, sqr_distances);
407 if ( num > min_points)
409 seed_indices.push_back (index_orig);
419 template <
typename Po
intT>
void
423 for (
typename HelperListT::iterator sv_itr = supervoxel_helpers_.begin (); sv_itr != supervoxel_helpers_.end (); ++sv_itr)
425 sv_itr->removeAllLeaves ();
431 for (
typename HelperListT::iterator sv_itr = supervoxel_helpers_.begin (); sv_itr != supervoxel_helpers_.end (); ++sv_itr)
434 sv_itr->getXYZ (point.x, point.y, point.z);
435 voxel_kdtree_->nearestKSearch (point, 1, closest_index,
distance);
437 LeafContainerT* seed_leaf = adjacency_octree_->at (closest_index[0]);
440 sv_itr->addLeaf (seed_leaf);
444 PCL_WARN (
"Could not find leaf in pcl::SupervoxelClustering<PointT>::reseedSupervoxels - supervoxel will be deleted \n");
451 template <
typename Po
intT>
void
456 p.z = std::log (p.z);
460 template <
typename Po
intT>
float
464 float spatial_dist = (v1.xyz_ - v2.xyz_).norm () / seed_resolution_;
465 float color_dist = (v1.rgb_ - v2.rgb_).norm () / 255.0f;
466 float cos_angle_normal = 1.0f - std::abs (v1.normal_.dot (v2.normal_));
468 return cos_angle_normal * normal_importance_ + color_dist * color_importance_+ spatial_dist * spatial_importance_;
479 template <
typename Po
intT>
void
482 adjacency_list_arg.clear ();
484 std::map <std::uint32_t, VoxelID> label_ID_map;
485 for (
typename HelperListT::const_iterator sv_itr = supervoxel_helpers_.cbegin (); sv_itr != supervoxel_helpers_.cend (); ++sv_itr)
487 VoxelID node_id = add_vertex (adjacency_list_arg);
488 adjacency_list_arg[node_id] = (sv_itr->getLabel ());
489 label_ID_map.insert (std::make_pair (sv_itr->getLabel (), node_id));
492 for (
typename HelperListT::const_iterator sv_itr = supervoxel_helpers_.cbegin (); sv_itr != supervoxel_helpers_.cend (); ++sv_itr)
494 std::uint32_t label = sv_itr->getLabel ();
495 std::set<std::uint32_t> neighbor_labels;
496 sv_itr->getNeighborLabels (neighbor_labels);
497 for (
const unsigned int &neighbor_label : neighbor_labels)
501 VoxelID u = (label_ID_map.find (label))->second;
502 VoxelID v = (label_ID_map.find (neighbor_label))->second;
503 boost::tie (edge, edge_added) = add_edge (u,v,adjacency_list_arg);
507 VoxelData centroid_data = (sv_itr)->getCentroid ();
511 for (
typename HelperListT::const_iterator neighb_itr = supervoxel_helpers_.cbegin (); neighb_itr != supervoxel_helpers_.cend (); ++neighb_itr)
513 if (neighb_itr->getLabel () == neighbor_label)
515 neighb_centroid_data = neighb_itr->getCentroid ();
520 float length = voxelDataDistance (centroid_data, neighb_centroid_data);
521 adjacency_list_arg[edge] = length;
530 template <
typename Po
intT>
void
533 label_adjacency.clear ();
534 for (
typename HelperListT::const_iterator sv_itr = supervoxel_helpers_.cbegin (); sv_itr != supervoxel_helpers_.cend (); ++sv_itr)
536 std::uint32_t label = sv_itr->getLabel ();
537 std::set<std::uint32_t> neighbor_labels;
538 sv_itr->getNeighborLabels (neighbor_labels);
539 for (
const unsigned int &neighbor_label : neighbor_labels)
540 label_adjacency.insert (std::pair<std::uint32_t,std::uint32_t> (label, neighbor_label) );
552 return centroid_copy;
560 for (
typename HelperListT::const_iterator sv_itr = supervoxel_helpers_.cbegin (); sv_itr != supervoxel_helpers_.cend (); ++sv_itr)
563 sv_itr->getVoxels (voxels);
567 auto xyzl_copy_itr = xyzl_copy.
begin ();
568 for ( ; xyzl_copy_itr != xyzl_copy.
end (); ++xyzl_copy_itr)
569 xyzl_copy_itr->label = sv_itr->getLabel ();
571 *labeled_voxel_cloud += xyzl_copy;
574 return labeled_voxel_cloud;
584 auto i_input = input_->begin ();
585 for (
auto i_labeled = labeled_cloud->
begin (); i_labeled != labeled_cloud->
end (); ++i_labeled,++i_input)
587 if ( !pcl::isFinite<PointT> (*i_input))
588 i_labeled->label = 0;
591 i_labeled->label = 0;
592 LeafContainerT *leaf = adjacency_octree_->getLeafContainerAtPoint (*i_input);
595 i_labeled->label = voxel_data.
owner_->getLabel ();
601 return (labeled_cloud);
609 normal_cloud->
resize (supervoxel_clusters.size ());
610 auto normal_cloud_itr = normal_cloud->
begin ();
611 for (
auto sv_itr = supervoxel_clusters.cbegin (), sv_itr_end = supervoxel_clusters.cend ();
612 sv_itr != sv_itr_end; ++sv_itr, ++normal_cloud_itr)
614 (sv_itr->second)->getCentroidPointNormal (*normal_cloud_itr);
620 template <
typename Po
intT>
float
623 return (resolution_);
627 template <
typename Po
intT>
void
630 resolution_ = resolution;
635 template <
typename Po
intT>
float
638 return (seed_resolution_);
642 template <
typename Po
intT>
void
645 seed_resolution_ = seed_resolution;
650 template <
typename Po
intT>
void
653 color_importance_ = val;
657 template <
typename Po
intT>
void
660 spatial_importance_ = val;
664 template <
typename Po
intT>
void
667 normal_importance_ = val;
671 template <
typename Po
intT>
void
674 use_default_transform_behaviour_ =
false;
675 use_single_camera_transform_ = val;
679 template <
typename Po
intT>
int
683 for (
typename HelperListT::const_iterator sv_itr = supervoxel_helpers_.cbegin (); sv_itr != supervoxel_helpers_.cend (); ++sv_itr)
685 int temp = sv_itr->getLabel ();
686 if (temp > max_label)
734 template<
typename Po
intT>
void
738 point_arg.x = xyz_[0];
739 point_arg.y = xyz_[1];
740 point_arg.z = xyz_[2];
744 template <
typename Po
intT>
void
747 normal_arg.normal_x = normal_[0];
748 normal_arg.normal_y = normal_[1];
749 normal_arg.normal_z = normal_[2];
757 template <
typename Po
intT>
void
760 leaves_.insert (leaf_arg);
761 VoxelData& voxel_data = leaf_arg->getData ();
762 voxel_data.owner_ =
this;
766 template <
typename Po
intT>
void
769 leaves_.erase (leaf_arg);
773 template <
typename Po
intT>
void
776 for (
auto leaf_itr = leaves_.cbegin (); leaf_itr != leaves_.cend (); ++leaf_itr)
778 VoxelData& voxel = ((*leaf_itr)->getData ());
779 voxel.owner_ =
nullptr;
780 voxel.distance_ = std::numeric_limits<float>::max ();
786 template <
typename Po
intT>
void
791 std::vector<LeafContainerT*> new_owned;
792 new_owned.reserve (leaves_.size () * 9);
794 for (
auto leaf_itr = leaves_.cbegin (); leaf_itr != leaves_.cend (); ++leaf_itr)
797 for (
auto neighb_itr=(*leaf_itr)->cbegin (); neighb_itr!=(*leaf_itr)->cend (); ++neighb_itr)
800 VoxelData& neighbor_voxel = ((*neighb_itr)->getData ());
802 if(neighbor_voxel.owner_ ==
this)
805 float dist = parent_->voxelDataDistance (centroid_, neighbor_voxel);
808 if (dist < neighbor_voxel.distance_)
810 neighbor_voxel.distance_ = dist;
811 if (neighbor_voxel.owner_ !=
this)
813 if (neighbor_voxel.owner_)
814 (neighbor_voxel.owner_)->removeLeaf(*neighb_itr);
815 neighbor_voxel.owner_ =
this;
816 new_owned.push_back (*neighb_itr);
822 for (
auto new_owned_itr = new_owned.cbegin (); new_owned_itr != new_owned.cend (); ++new_owned_itr)
824 leaves_.insert (*new_owned_itr);
829 template <
typename Po
intT>
void
833 for (
auto leaf_itr = leaves_.cbegin (); leaf_itr != leaves_.cend (); ++leaf_itr)
835 VoxelData& voxel_data = (*leaf_itr)->getData ();
837 indices.reserve (81);
839 indices.push_back (voxel_data.idx_);
840 for (
auto neighb_itr=(*leaf_itr)->cbegin (); neighb_itr!=(*leaf_itr)->cend (); ++neighb_itr)
843 VoxelData& neighbor_voxel_data = ((*neighb_itr)->getData ());
845 if (neighbor_voxel_data.owner_ ==
this)
847 indices.push_back (neighbor_voxel_data.idx_);
849 for (
auto neighb_neighb_itr=(*neighb_itr)->cbegin (); neighb_neighb_itr!=(*neighb_itr)->cend (); ++neighb_neighb_itr)
851 VoxelData& neighb_neighb_voxel_data = (*neighb_neighb_itr)->getData ();
852 if (neighb_neighb_voxel_data.owner_ ==
this)
853 indices.push_back (neighb_neighb_voxel_data.idx_);
862 voxel_data.normal_[3] = 0.0f;
863 voxel_data.normal_.normalize ();
868 template <
typename Po
intT>
void
871 centroid_.normal_ = Eigen::Vector4f::Zero ();
872 centroid_.xyz_ = Eigen::Vector3f::Zero ();
873 centroid_.rgb_ = Eigen::Vector3f::Zero ();
874 for (
auto leaf_itr = leaves_.cbegin (); leaf_itr != leaves_.cend (); ++leaf_itr)
876 const VoxelData& leaf_data = (*leaf_itr)->getData ();
877 centroid_.normal_ += leaf_data.normal_;
878 centroid_.xyz_ += leaf_data.xyz_;
879 centroid_.rgb_ += leaf_data.rgb_;
881 centroid_.normal_.normalize ();
882 centroid_.xyz_ /=
static_cast<float> (leaves_.size ());
883 centroid_.rgb_ /=
static_cast<float> (leaves_.size ());
887 template <
typename Po
intT>
void
892 voxels->
resize (leaves_.size ());
893 auto voxel_itr = voxels->
begin ();
894 for (
auto leaf_itr = leaves_.cbegin (); leaf_itr != leaves_.cend (); ++leaf_itr, ++voxel_itr)
896 const VoxelData& leaf_data = (*leaf_itr)->getData ();
897 leaf_data.getPoint (*voxel_itr);
902 template <
typename Po
intT>
void
907 normals->
resize (leaves_.size ());
908 auto normal_itr = normals->
begin ();
909 for (
auto leaf_itr = leaves_.cbegin (); leaf_itr != leaves_.cend (); ++leaf_itr, ++normal_itr)
911 const VoxelData& leaf_data = (*leaf_itr)->getData ();
912 leaf_data.getNormal (*normal_itr);
917 template <
typename Po
intT>
void
920 neighbor_labels.clear ();
922 for (
auto leaf_itr = leaves_.cbegin (); leaf_itr != leaves_.cend (); ++leaf_itr)
925 for (
auto neighb_itr=(*leaf_itr)->cbegin (); neighb_itr!=(*leaf_itr)->cend (); ++neighb_itr)
928 VoxelData& neighbor_voxel = ((*neighb_itr)->getData ());
930 if (neighbor_voxel.owner_ !=
this && neighbor_voxel.owner_)
932 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::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 voxel class which maintains adjacency information for its voxels.
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.