40 #ifndef PCL_SEGMENTATION_SUPERVOXEL_CLUSTERING_HPP_
41 #define PCL_SEGMENTATION_SUPERVOXEL_CLUSTERING_HPP_
43 #include <pcl/segmentation/supervoxel_clustering.h>
46 template <
typename Po
intT>
48 resolution_ (voxel_resolution),
49 seed_resolution_ (seed_resolution),
51 voxel_centroid_cloud_ (),
52 color_importance_(0.1f),
53 spatial_importance_(0.4f),
54 normal_importance_(1.0f),
57 label_colors_.reserve (MAX_LABEL);
58 label_colors_.push_back (static_cast<uint32_t>(255) << 16 | static_cast<uint32_t>(0) << 8 | static_cast<uint32_t>(0));
60 srand (static_cast<unsigned int> (time (0)));
61 for (
size_t i_segment = 0; i_segment < MAX_LABEL - 1; i_segment++)
63 uint8_t r =
static_cast<uint8_t
>( (rand () % 256));
64 uint8_t g =
static_cast<uint8_t
>( (rand () % 256));
65 uint8_t b =
static_cast<uint8_t
>( (rand () % 256));
66 label_colors_.push_back (static_cast<uint32_t>(r) << 16 | static_cast<uint32_t>(g) << 8 | static_cast<uint32_t>(b));
69 adjacency_octree_ = boost::make_shared <OctreeAdjacencyT> (resolution_);
70 if (use_single_camera_transform)
71 adjacency_octree_->setTransformFunction (boost::bind (&SupervoxelClustering::transformFunction,
this, _1));
75 template <
typename Po
intT>
82 template <
typename Po
intT>
void
85 if ( cloud->
size () == 0 )
87 PCL_ERROR (
"[pcl::SupervoxelClustering::setInputCloud] Empty cloud set, doing nothing \n");
92 adjacency_octree_->setInputCloud (cloud);
97 template <
typename Po
intT>
void
103 bool segmentation_is_possible = initCompute ();
104 if ( !segmentation_is_possible )
111 segmentation_is_possible = prepareForSegmentation ();
112 if ( !segmentation_is_possible )
120 std::vector<PointT, Eigen::aligned_allocator<PointT> > seed_points;
121 selectInitialSupervoxelSeeds (seed_points);
123 createSupervoxelHelpers (seed_points);
128 int max_depth =
static_cast<int> (1.8f*seed_resolution_/resolution_);
129 expandSupervoxels (max_depth);
133 makeSupervoxels (supervoxel_clusters);
149 template <
typename Po
intT>
void
152 if (supervoxel_helpers_.size () == 0)
154 PCL_ERROR (
"[pcl::SupervoxelClustering::refineVoxelNormals] Supervoxels not extracted, doing nothing - (Call extract first!) \n");
158 int max_depth =
static_cast<int> (1.8f*seed_resolution_/resolution_);
159 for (
int i = 0; i < num_itr; ++i)
161 for (
typename HelperListT::iterator sv_itr = supervoxel_helpers_.begin (); sv_itr != supervoxel_helpers_.end (); ++sv_itr)
163 sv_itr->refineNormals ();
166 reseedSupervoxels ();
167 expandSupervoxels (max_depth);
171 makeSupervoxels (supervoxel_clusters);
181 template <
typename Po
intT>
bool
186 if ( input_->points.size () == 0 )
192 adjacency_octree_->addPointsFromInputCloud ();
206 template <
typename Po
intT>
void
209 voxel_centroid_cloud_ = boost::make_shared<PointCloudT> ();
210 voxel_centroid_cloud_->resize (adjacency_octree_->getLeafCount ());
211 typename LeafVectorT::iterator leaf_itr = adjacency_octree_->begin ();
212 typename PointCloudT::iterator cent_cloud_itr = voxel_centroid_cloud_->begin ();
213 for (
int idx = 0 ; leaf_itr != adjacency_octree_->end (); ++leaf_itr, ++cent_cloud_itr, ++idx)
215 VoxelData& new_voxel_data = (*leaf_itr)->getData ();
217 new_voxel_data.getPoint (*cent_cloud_itr);
219 new_voxel_data.idx_ = idx;
223 for (leaf_itr = adjacency_octree_->begin (); leaf_itr != adjacency_octree_->end (); ++leaf_itr)
225 VoxelData& new_voxel_data = (*leaf_itr)->getData ();
227 std::vector<int> indices;
228 indices.reserve (81);
230 indices.push_back (new_voxel_data.idx_);
231 for (
typename LeafContainerT::iterator neighb_itr=(*leaf_itr)->begin (); neighb_itr!=(*leaf_itr)->end (); ++neighb_itr)
233 VoxelData& neighb_voxel_data = (*neighb_itr)->getData ();
235 indices.push_back (neighb_voxel_data.idx_);
237 for (
typename LeafContainerT::iterator neighb_neighb_itr=(*neighb_itr)->begin (); neighb_neighb_itr!=(*neighb_itr)->end (); ++neighb_neighb_itr)
239 VoxelData& neighb2_voxel_data = (*neighb_neighb_itr)->getData ();
240 indices.push_back (neighb2_voxel_data.idx_);
246 new_voxel_data.normal_[3] = 0.0f;
247 new_voxel_data.normal_.normalize ();
248 new_voxel_data.owner_ = 0;
249 new_voxel_data.distance_ = std::numeric_limits<float>::max ();
257 template <
typename Po
intT>
void
262 for (
int i = 1; i < depth; ++i)
265 for (
typename HelperListT::iterator sv_itr = supervoxel_helpers_.begin (); sv_itr != supervoxel_helpers_.end (); ++sv_itr)
271 for (
typename HelperListT::iterator sv_itr = supervoxel_helpers_.begin (); sv_itr != supervoxel_helpers_.end (); )
273 if (sv_itr->size () == 0)
275 sv_itr = supervoxel_helpers_.erase (sv_itr);
279 sv_itr->updateCentroid ();
289 template <
typename Po
intT>
void
292 supervoxel_clusters.clear ();
293 for (
typename HelperListT::iterator sv_itr = supervoxel_helpers_.begin (); sv_itr != supervoxel_helpers_.end (); ++sv_itr)
295 uint32_t label = sv_itr->getLabel ();
296 supervoxel_clusters[label] = boost::make_shared<Supervoxel<PointT> > ();
297 sv_itr->getXYZ (supervoxel_clusters[label]->centroid_.x,supervoxel_clusters[label]->centroid_.y,supervoxel_clusters[label]->centroid_.z);
298 sv_itr->getRGB (supervoxel_clusters[label]->centroid_.rgba);
299 sv_itr->getNormal (supervoxel_clusters[label]->normal_);
300 sv_itr->getVoxels (supervoxel_clusters[label]->voxels_);
301 sv_itr->getNormals (supervoxel_clusters[label]->normals_);
307 template <
typename Po
intT>
void
311 supervoxel_helpers_.clear ();
312 for (
int i = 0; i < seed_points.size (); ++i)
314 supervoxel_helpers_.push_back (
new SupervoxelHelper(i+1,
this));
316 LeafContainerT* seed_leaf = adjacency_octree_->getLeafContainerAtPoint (seed_points[i]);
319 supervoxel_helpers_.back ().addLeaf (seed_leaf);
323 PCL_WARN (
"Could not find leaf in pcl::SupervoxelClustering<PointT>::createSupervoxelHelpers - supervoxel will be deleted \n");
329 template <
typename Po
intT>
void
338 seed_octree.setInputCloud (voxel_centroid_cloud_);
339 seed_octree.addPointsFromInputCloud ();
341 std::vector<PointT, Eigen::aligned_allocator<PointT> > voxel_centers;
342 int num_seeds = seed_octree.getOccupiedVoxelCenters(voxel_centers);
345 std::vector<int> seed_indices_orig;
346 seed_indices_orig.resize (num_seeds, 0);
347 seed_points.clear ();
348 std::vector<int> closest_index;
350 closest_index.resize(1,0);
351 distance.resize(1,0);
352 if (voxel_kdtree_ == 0)
354 voxel_kdtree_ = boost::make_shared< pcl::search::KdTree<PointT> >();
355 voxel_kdtree_ ->setInputCloud (voxel_centroid_cloud_);
358 for (
int i = 0; i < num_seeds; ++i)
360 voxel_kdtree_->nearestKSearch (voxel_centers[i], 1, closest_index, distance);
361 seed_indices_orig[i] = closest_index[0];
364 std::vector<int> neighbors;
365 std::vector<float> sqr_distances;
366 seed_points.reserve (seed_indices_orig.size ());
367 float search_radius = 0.5f*seed_resolution_;
370 float min_points = 0.05f * (search_radius)*(search_radius) * 3.1415926536f / (resolution_*resolution_);
371 for (
int i = 0; i < seed_indices_orig.size (); ++i)
373 int num = voxel_kdtree_->radiusSearch (seed_indices_orig[i], search_radius , neighbors, sqr_distances);
374 int min_index = seed_indices_orig[i];
375 if ( num > min_points)
377 seed_points.push_back (voxel_centroid_cloud_->points[min_index]);
387 template <
typename Po
intT>
void
391 for (
typename HelperListT::iterator sv_itr = supervoxel_helpers_.begin (); sv_itr != supervoxel_helpers_.end (); ++sv_itr)
393 sv_itr->removeAllLeaves ();
396 std::vector<int> closest_index;
397 std::vector<float> distance;
399 for (
typename HelperListT::iterator sv_itr = supervoxel_helpers_.begin (); sv_itr != supervoxel_helpers_.end (); ++sv_itr)
402 sv_itr->getXYZ (point.x, point.y, point.z);
403 voxel_kdtree_->nearestKSearch (point, 1, closest_index, distance);
405 LeafContainerT* seed_leaf = adjacency_octree_->getLeafContainerAtPoint (voxel_centroid_cloud_->points[closest_index[0]]);
408 sv_itr->addLeaf (seed_leaf);
415 template <
typename Po
intT>
void
420 p.z = std::log (p.z);
424 template <
typename Po
intT>
float
428 float spatial_dist = (v1.xyz_ - v2.xyz_).norm () / seed_resolution_;
429 float color_dist = (v1.rgb_ - v2.rgb_).norm () / 255.0f;
430 float cos_angle_normal = 1.0f - std::abs (v1.normal_.dot (v2.normal_));
432 return cos_angle_normal * normal_importance_ + color_dist * color_importance_+ spatial_dist * spatial_importance_;
443 template <
typename Po
intT>
void
446 adjacency_list_arg.clear ();
448 std::map <uint32_t, VoxelID> label_ID_map;
449 for (
typename HelperListT::const_iterator sv_itr = supervoxel_helpers_.cbegin (); sv_itr != supervoxel_helpers_.cend (); ++sv_itr)
451 VoxelID node_id = add_vertex (adjacency_list_arg);
452 adjacency_list_arg[node_id] = (sv_itr->getLabel ());
453 label_ID_map.insert (std::make_pair (sv_itr->getLabel (), node_id));
456 for (
typename HelperListT::const_iterator sv_itr = supervoxel_helpers_.cbegin (); sv_itr != supervoxel_helpers_.cend (); ++sv_itr)
458 uint32_t label = sv_itr->getLabel ();
459 std::set<uint32_t> neighbor_labels;
460 sv_itr->getNeighborLabels (neighbor_labels);
461 for (std::set<uint32_t>::iterator label_itr = neighbor_labels.begin (); label_itr != neighbor_labels.end (); ++label_itr)
465 VoxelID u = (label_ID_map.find (label))->second;
466 VoxelID v = (label_ID_map.find (*label_itr))->second;
467 boost::tie (edge, edge_added) = add_edge (u,v,adjacency_list_arg);
471 VoxelData centroid_data = (sv_itr)->getCentroid ();
475 for (
typename HelperListT::const_iterator neighb_itr = supervoxel_helpers_.cbegin (); neighb_itr != supervoxel_helpers_.cend (); ++neighb_itr)
477 if (neighb_itr->getLabel () == (*label_itr))
479 neighb_centroid_data = neighb_itr->getCentroid ();
484 float length = voxelDataDistance (centroid_data, neighb_centroid_data);
485 adjacency_list_arg[edge] = length;
494 template <
typename Po
intT>
void
497 label_adjacency.clear ();
498 for (
typename HelperListT::const_iterator sv_itr = supervoxel_helpers_.cbegin (); sv_itr != supervoxel_helpers_.cend (); ++sv_itr)
500 uint32_t label = sv_itr->getLabel ();
501 std::set<uint32_t> neighbor_labels;
502 sv_itr->getNeighborLabels (neighbor_labels);
503 for (std::set<uint32_t>::iterator label_itr = neighbor_labels.begin (); label_itr != neighbor_labels.end (); ++label_itr)
504 label_adjacency.insert (std::pair<uint32_t,uint32_t> (label, *label_itr) );
522 std::vector <int> indices;
523 std::vector <float> sqr_distances;
524 for (i_colored = colored_cloud->
begin (); i_colored != colored_cloud->
end (); ++i_colored,++i_input)
526 if ( !pcl::isFinite<PointT> (*i_input))
531 LeafContainerT *leaf = adjacency_octree_->getLeafContainerAtPoint (*i_input);
532 VoxelData& voxel_data = leaf->getData ();
534 i_colored->rgba = label_colors_[voxel_data.
owner_->getLabel ()];
540 return (colored_cloud);
548 for (
typename HelperListT::const_iterator sv_itr = supervoxel_helpers_.cbegin (); sv_itr != supervoxel_helpers_.cend (); ++sv_itr)
551 sv_itr->getVoxels (voxels);
556 for ( ; rgb_copy_itr != rgb_copy.
end (); ++rgb_copy_itr)
557 rgb_copy_itr->rgba = label_colors_ [sv_itr->getLabel ()];
559 *colored_cloud += rgb_copy;
562 return colored_cloud;
569 typename PointCloudT::Ptr centroid_copy = boost::make_shared<PointCloudT> ();
571 return centroid_copy;
579 for (
typename HelperListT::const_iterator sv_itr = supervoxel_helpers_.cbegin (); sv_itr != supervoxel_helpers_.cend (); ++sv_itr)
582 sv_itr->getVoxels (voxels);
587 for ( ; xyzl_copy_itr != xyzl_copy.
end (); ++xyzl_copy_itr)
588 xyzl_copy_itr->label = sv_itr->getLabel ();
590 *labeled_voxel_cloud += xyzl_copy;
593 return labeled_voxel_cloud;
605 std::vector <int> indices;
606 std::vector <float> sqr_distances;
607 for (i_labeled = labeled_cloud->
begin (); i_labeled != labeled_cloud->
end (); ++i_labeled,++i_input)
609 if ( !pcl::isFinite<PointT> (*i_input))
610 i_labeled->label = 0;
613 i_labeled->label = 0;
614 LeafContainerT *leaf = adjacency_octree_->getLeafContainerAtPoint (*i_input);
615 VoxelData& voxel_data = leaf->getData ();
617 i_labeled->label = voxel_data.
owner_->getLabel ();
623 return (labeled_cloud);
631 normal_cloud->
resize (supervoxel_clusters.size ());
632 typename std::map <uint32_t, typename pcl::Supervoxel<PointT>::Ptr>::iterator sv_itr,sv_itr_end;
633 sv_itr = supervoxel_clusters.begin ();
634 sv_itr_end = supervoxel_clusters.end ();
636 for ( ; sv_itr != sv_itr_end; ++sv_itr, ++normal_cloud_itr)
638 (sv_itr->second)->getCentroidPointNormal (*normal_cloud_itr);
644 template <
typename Po
intT>
float
647 return (resolution_);
651 template <
typename Po
intT>
void
654 resolution_ = resolution;
659 template <
typename Po
intT>
float
662 return (resolution_);
666 template <
typename Po
intT>
void
669 seed_resolution_ = seed_resolution;
674 template <
typename Po
intT>
void
677 color_importance_ = val;
681 template <
typename Po
intT>
void
684 spatial_importance_ = val;
688 template <
typename Po
intT>
void
691 normal_importance_ = val;
708 data_.xyz_[0] += new_point.x;
709 data_.xyz_[1] += new_point.y;
710 data_.xyz_[2] += new_point.z;
712 data_.rgb_[0] +=
static_cast<float> (new_point.r);
713 data_.rgb_[1] +=
static_cast<float> (new_point.g);
714 data_.rgb_[2] +=
static_cast<float> (new_point.b);
723 data_.xyz_[0] += new_point.x;
724 data_.xyz_[1] += new_point.y;
725 data_.xyz_[2] += new_point.z;
727 data_.rgb_[0] +=
static_cast<float> (new_point.r);
728 data_.rgb_[1] +=
static_cast<float> (new_point.g);
729 data_.rgb_[2] +=
static_cast<float> (new_point.b);
738 data_.rgb_[0] /= (
static_cast<float> (num_points_));
739 data_.rgb_[1] /= (
static_cast<float> (num_points_));
740 data_.rgb_[2] /= (
static_cast<float> (num_points_));
741 data_.xyz_[0] /= (
static_cast<float> (num_points_));
742 data_.xyz_[1] /= (
static_cast<float> (num_points_));
743 data_.xyz_[2] /= (
static_cast<float> (num_points_));
749 data_.rgb_[0] /= (
static_cast<float> (num_points_));
750 data_.rgb_[1] /= (
static_cast<float> (num_points_));
751 data_.rgb_[2] /= (
static_cast<float> (num_points_));
752 data_.xyz_[0] /= (
static_cast<float> (num_points_));
753 data_.xyz_[1] /= (
static_cast<float> (num_points_));
754 data_.xyz_[2] /= (
static_cast<float> (num_points_));
768 point_arg.rgba =
static_cast<uint32_t
>(rgb_[0]) << 16 |
769 static_cast<uint32_t>(rgb_[1]) << 8 |
770 static_cast<uint32_t
>(rgb_[2]);
771 point_arg.x = xyz_[0];
772 point_arg.y = xyz_[1];
773 point_arg.z = xyz_[2];
779 point_arg.rgba =
static_cast<uint32_t
>(rgb_[0]) << 16 |
780 static_cast<uint32_t>(rgb_[1]) << 8 |
781 static_cast<uint32_t
>(rgb_[2]);
782 point_arg.x = xyz_[0];
783 point_arg.y = xyz_[1];
784 point_arg.z = xyz_[2];
787 template<
typename Po
intT>
void
791 point_arg.x = xyz_[0];
792 point_arg.y = xyz_[1];
793 point_arg.z = xyz_[2];
797 template <
typename Po
intT>
void
800 normal_arg.normal_x = normal_[0];
801 normal_arg.normal_y = normal_[1];
802 normal_arg.normal_z = normal_[2];
811 template <
typename Po
intT>
void
814 leaves_.insert (leaf_arg);
815 VoxelData& voxel_data = leaf_arg->getData ();
816 voxel_data.owner_ =
this;
820 template <
typename Po
intT>
void
823 leaves_.erase (leaf_arg);
827 template <
typename Po
intT>
void
830 typename std::set<LeafContainerT*>::iterator leaf_itr;
831 for (leaf_itr = leaves_.begin (); leaf_itr != leaves_.end (); ++leaf_itr)
833 VoxelData& voxel = ((*leaf_itr)->getData ());
835 voxel.distance_ = std::numeric_limits<float>::max ();
841 template <
typename Po
intT>
void
846 std::vector<LeafContainerT*> new_owned;
847 new_owned.reserve (leaves_.size () * 9);
849 typename std::set<LeafContainerT*>::iterator leaf_itr;
850 for (leaf_itr = leaves_.begin (); leaf_itr != leaves_.end (); ++leaf_itr)
853 for (
typename LeafContainerT::iterator neighb_itr=(*leaf_itr)->begin (); neighb_itr!=(*leaf_itr)->end (); ++neighb_itr)
856 VoxelData& neighbor_voxel = ((*neighb_itr)->getData ());
858 if(neighbor_voxel.owner_ ==
this)
861 float dist = parent_->voxelDataDistance (centroid_, neighbor_voxel);
864 if (dist < neighbor_voxel.distance_)
866 neighbor_voxel.distance_ = dist;
867 if (neighbor_voxel.owner_ !=
this)
869 if (neighbor_voxel.owner_)
870 (neighbor_voxel.owner_)->removeLeaf(*neighb_itr);
871 neighbor_voxel.owner_ =
this;
872 new_owned.push_back (*neighb_itr);
878 typename std::vector<LeafContainerT*>::iterator new_owned_itr;
879 for (new_owned_itr=new_owned.begin (); new_owned_itr!=new_owned.end (); ++new_owned_itr)
881 leaves_.insert (*new_owned_itr);
887 template <
typename Po
intT>
void
890 typename std::set<LeafContainerT*>::iterator leaf_itr;
892 for (leaf_itr = leaves_.begin (); leaf_itr != leaves_.end (); ++leaf_itr)
894 VoxelData& voxel_data = (*leaf_itr)->getData ();
895 std::vector<int> indices;
896 indices.reserve (81);
898 indices.push_back (voxel_data.idx_);
899 for (
typename LeafContainerT::iterator neighb_itr=(*leaf_itr)->begin (); neighb_itr!=(*leaf_itr)->end (); ++neighb_itr)
902 VoxelData& neighbor_voxel_data = ((*neighb_itr)->getData ());
904 if (neighbor_voxel_data.owner_ ==
this)
906 indices.push_back (neighbor_voxel_data.idx_);
908 for (
typename LeafContainerT::iterator neighb_neighb_itr=(*neighb_itr)->begin (); neighb_neighb_itr!=(*neighb_itr)->end (); ++neighb_neighb_itr)
910 VoxelData& neighb_neighb_voxel_data = (*neighb_neighb_itr)->getData ();
911 if (neighb_neighb_voxel_data.owner_ ==
this)
912 indices.push_back (neighb_neighb_voxel_data.idx_);
921 voxel_data.normal_[3] = 0.0f;
922 voxel_data.normal_.normalize ();
927 template <
typename Po
intT>
void
930 centroid_.normal_ = Eigen::Vector4f::Zero ();
931 centroid_.xyz_ = Eigen::Vector3f::Zero ();
932 centroid_.rgb_ = Eigen::Vector3f::Zero ();
933 typename std::set<LeafContainerT*>::iterator leaf_itr = leaves_.begin ();
934 if (leaves_.size () < 20)
936 for ( ; leaf_itr!= leaves_.end (); ++leaf_itr)
938 const VoxelData& leaf_data = (*leaf_itr)->getData ();
939 centroid_.normal_ += leaf_data.normal_;
940 centroid_.xyz_ += leaf_data.xyz_;
941 centroid_.rgb_ += leaf_data.rgb_;
943 centroid_.normal_.normalize ();
947 std::vector<int> indices;
948 indices.reserve (leaves_.size ());
949 for ( ; leaf_itr!= leaves_.end (); ++leaf_itr)
951 const VoxelData& leaf_data = (*leaf_itr)->getData ();
952 centroid_.xyz_ += leaf_data.xyz_;
953 centroid_.rgb_ += leaf_data.rgb_;
954 indices.push_back (leaf_data.idx_);
958 this->getXYZ (temp.x, temp.y, temp.z);
960 centroid_.normal_[3] = 0.0f;
961 centroid_.normal_.normalize ();
964 centroid_.xyz_ /=
static_cast<float> (leaves_.size ());
965 centroid_.rgb_ /=
static_cast<float> (leaves_.size ());
970 template <
typename Po
intT>
void
973 voxels = boost::make_shared<pcl::PointCloud<PointT> > ();
975 voxels->
resize (leaves_.size ());
977 typename std::set<LeafContainerT*>::iterator leaf_itr;
978 for (leaf_itr = leaves_.begin (); leaf_itr != leaves_.end (); ++leaf_itr, ++voxel_itr)
980 const VoxelData& leaf_data = (*leaf_itr)->getData ();
981 leaf_data.getPoint (*voxel_itr);
986 template <
typename Po
intT>
void
989 normals = boost::make_shared<pcl::PointCloud<Normal> > ();
991 normals->
resize (leaves_.size ());
992 typename std::set<LeafContainerT*>::iterator leaf_itr;
994 for (leaf_itr = leaves_.begin (); leaf_itr != leaves_.end (); ++leaf_itr, ++normal_itr)
996 const VoxelData& leaf_data = (*leaf_itr)->getData ();
997 leaf_data.getNormal (*normal_itr);
1002 template <
typename Po
intT>
void
1005 neighbor_labels.clear ();
1007 typename std::set<LeafContainerT*>::iterator leaf_itr;
1008 for (leaf_itr = leaves_.begin (); leaf_itr != leaves_.end (); ++leaf_itr)
1011 for (
typename LeafContainerT::iterator neighb_itr=(*leaf_itr)->begin (); neighb_itr!=(*leaf_itr)->end (); ++neighb_itr)
1014 VoxelData& neighbor_voxel = ((*neighb_itr)->getData ());
1016 if (neighbor_voxel.owner_ !=
this && neighbor_voxel.owner_)
1018 neighbor_labels.insert (neighbor_voxel.owner_->getLabel ());
1025 #endif // PCL_SUPERVOXEL_CLUSTERING_HPP_