Skip to content

Commit

Permalink
Merge pull request PointCloudLibrary#1183 from mschoeler/LCCP_RemoveS…
Browse files Browse the repository at this point in the history
…mallSegmentsFix

removeSmallSegments -> mergeSmallSegments + fixes
  • Loading branch information
taketwo committed Mar 23, 2015
2 parents 73f2930 + b5e5398 commit 140da8e
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 26 deletions.
4 changes: 2 additions & 2 deletions examples/segmentation/example_lccp_segmentation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,8 @@ LCCPSegmentation Parameters: \n\

if (min_segment_size > 0)
{
PCL_INFO ("Removing small segments\n");
lccp.removeSmallSegments (min_segment_size);
PCL_INFO ("Merging small segments\n");
lccp.mergeSmallSegments (min_segment_size);
}

PCL_INFO ("Interpolation voxel cloud -> input cloud and relabeling\n");
Expand Down
26 changes: 13 additions & 13 deletions segmentation/include/pcl/segmentation/impl/lccp_segmentation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ pcl::LCCPSegmentation<PointT>::computeSegmentAdjacency ()
}

template <typename PointT> void
pcl::LCCPSegmentation<PointT>::removeSmallSegments (uint32_t min_segment_size_arg)
pcl::LCCPSegmentation<PointT>::mergeSmallSegments (uint32_t min_segment_size_arg)
{
if (min_segment_size_arg == 0)
return;
Expand Down Expand Up @@ -194,11 +194,11 @@ pcl::LCCPSegmentation<PointT>::removeSmallSegments (uint32_t min_segment_size_ar
filteredSegLabels.insert (current_seg_label);

// Assign SuperVoxel labels of filtered segment to new owner
std::vector<uint32_t>::iterator sv_ID_itr = seg_label_to_sv_list_map_[current_seg_label].begin ();
std::set<uint32_t>::iterator sv_ID_itr = seg_label_to_sv_list_map_[current_seg_label].begin ();
sv_ID_itr = seg_label_to_sv_list_map_[current_seg_label].begin ();
for (; sv_ID_itr != seg_label_to_sv_list_map_[current_seg_label].end (); ++sv_ID_itr)
{
seg_label_to_sv_list_map_[largest_neigh_seg_label].push_back (*sv_ID_itr);
seg_label_to_sv_list_map_[largest_neigh_seg_label].insert (*sv_ID_itr);
}
}
}
Expand All @@ -211,23 +211,21 @@ pcl::LCCPSegmentation<PointT>::removeSmallSegments (uint32_t min_segment_size_ar
seg_label_to_sv_list_map_.erase (*filtered_ID_itr);
}

//After filtered Segments are deleted, compute completely new adjacency map
// After filtered Segments are deleted, compute completely new adjacency map
// NOTE Recomputing the adjacency of every segment in every iteration is an easy but inefficient solution.
// Because the number of segments in an average scene is usually well below 1000, the time spend for noise filtering is still neglible in most cases
computeSegmentAdjacency ();

// std::cout << "Filtered " << nr_filtered << " segments." << std::endl;
} // End while (Filtering)
}
else
{
PCL_WARN ("[pcl::LCCPSegmentation::removeNoise] WARNING: Call function segment first. Nothing has been done. \n");
PCL_WARN ("[pcl::LCCPSegmentation::mergeSmallSegments] WARNING: Call function segment first. Nothing has been done. \n");
}
}

template <typename PointT> void
pcl::LCCPSegmentation<PointT>::prepareSegmentation (const std::map<uint32_t, typename pcl::Supervoxel<PointT>::Ptr>& supervoxel_clusters_arg,
const std::multimap<boost::uint32_t, boost::uint32_t>& label_adjaceny_arg)
const std::multimap<uint32_t, uint32_t>& label_adjaceny_arg)
{
// Clear internal data
reset ();
Expand All @@ -242,10 +240,10 @@ pcl::LCCPSegmentation<PointT>::prepareSegmentation (const std::map<uint32_t, typ
for (typename std::map<uint32_t, typename pcl::Supervoxel<PointT>::Ptr>::iterator svlabel_itr = sv_label_to_supervoxel_map_.begin ();
svlabel_itr != sv_label_to_supervoxel_map_.end (); ++svlabel_itr)
{
const uint32_t SV_LABEL = svlabel_itr->first;
const uint32_t sv_label = svlabel_itr->first;
VertexID node_id = boost::add_vertex (sv_adjacency_list_);
sv_adjacency_list_[node_id] = SV_LABEL;
label_ID_map[SV_LABEL] = node_id;
sv_adjacency_list_[node_id] = sv_label;
label_ID_map[sv_label] = node_id;
}

// Add all edges
Expand All @@ -262,6 +260,8 @@ pcl::LCCPSegmentation<PointT>::prepareSegmentation (const std::map<uint32_t, typ
}

// Initialization
// clear the processed_ map
seg_label_to_sv_list_map_.clear ();
for (typename std::map<uint32_t, typename pcl::Supervoxel<PointT>::Ptr>::iterator svlabel_itr = sv_label_to_supervoxel_map_.begin ();
svlabel_itr != sv_label_to_supervoxel_map_.end (); ++svlabel_itr)
{
Expand All @@ -273,7 +273,7 @@ pcl::LCCPSegmentation<PointT>::prepareSegmentation (const std::map<uint32_t, typ

template <typename PointT> void
pcl::LCCPSegmentation<PointT>::segment (std::map<uint32_t, typename pcl::Supervoxel<PointT>::Ptr>& supervoxel_clusters_arg,
std::multimap<boost::uint32_t, boost::uint32_t>& label_adjacency_arg)
std::multimap<uint32_t, uint32_t>& label_adjacency_arg)
{
// Initialization
prepareSegmentation (supervoxel_clusters_arg, label_adjacency_arg); // after this, sv_adjacency_list_ can be used to access adjacency list
Expand Down Expand Up @@ -316,7 +316,7 @@ pcl::LCCPSegmentation<PointT>::recursiveGrouping (VertexID const &query_point_id

// The next two lines add the supervoxel to the segment
sv_label_to_seg_label_map_[sv_label] = segment_label;
seg_label_to_sv_list_map_[segment_label].push_back (sv_label);
seg_label_to_sv_list_map_[segment_label].insert (sv_label);

// Iterate through all neighbors of this supervoxel and check wether they should be merged with the current SuperVoxel
std::pair<OutEdgeIterator, OutEdgeIterator> out_edge_iterator_range;
Expand Down
21 changes: 10 additions & 11 deletions segmentation/include/pcl/segmentation/lccp_segmentation.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,15 @@ namespace pcl
void
relabelCloud (pcl::PointCloud<pcl::PointXYZL> &labeled_cloud_arg);

/** \brief Segments smaller than segment_size are assigned to label of largest neighbor.
* \param[in] min_segment_size_arg Segments smaller than this size will be filtered
* \note Currently this runs multiple times, until no segment < min_segment_size is found. Could be faster. */
/** \brief Segments smaller than segment_size are merged to the label of largest neighbor.
* \param[in] min_segment_size_arg Segments smaller than this size will be merged */
void
removeSmallSegments (uint32_t min_segment_size_arg);
mergeSmallSegments (uint32_t min_segment_size_arg);

/** \brief Get map<SegmentID, std::vector<SuperVoxel IDs> >
/** \brief Get map<SegmentID, std::set<SuperVoxel IDs> >
* \param[out] segment_supervoxel_map_arg The output container. On error the map is empty. */
inline void
getSegmentSupervoxelMap (std::map<uint32_t, std::vector<uint32_t> >& segment_supervoxel_map_arg) const
getSegmentSupervoxelMap (std::map<uint32_t, std::set<uint32_t> >& segment_supervoxel_map_arg) const
{
if (grouping_data_valid_)
{
Expand All @@ -118,7 +117,7 @@ namespace pcl
else
{
PCL_WARN ("[pcl::LCCPSegmentation::getSegmentMap] WARNING: Call function segment first. Nothing has been done. \n");
segment_supervoxel_map_arg = std::map<boost::uint32_t, std::vector<boost::uint32_t> > ();
segment_supervoxel_map_arg = std::map<uint32_t, std::set<uint32_t> > ();
}
}

Expand All @@ -136,7 +135,7 @@ namespace pcl
else
{
PCL_WARN ("[pcl::LCCPSegmentation::getSegmentAdjacencyMap] WARNING: Call function segment first. Nothing has been done. \n");
segment_adjacency_map_arg = std::map<boost::uint32_t, std::set<boost::uint32_t> > ();
segment_adjacency_map_arg = std::map<uint32_t, std::set<uint32_t> > ();
}
}

Expand Down Expand Up @@ -281,10 +280,10 @@ namespace pcl
/** \brief Storing relation between original SuperVoxel Labels and new segmantion labels. svLabel_segLabel_map_[old_labelID] = new_labelID */
std::map<uint32_t, uint32_t> sv_label_to_seg_label_map_;

/** \brief map < Segment Label, std::vector< SuperVoxel Labels> > */
std::map<uint32_t, std::vector<uint32_t> > seg_label_to_sv_list_map_;
/** \brief map <Segment Label, std::set <SuperVoxel Labels> > */
std::map<uint32_t, std::set<uint32_t> > seg_label_to_sv_list_map_;

/** \brief map < SegmentID, std::vector< Neighboring segment labels> > */
/** \brief map <SegmentID, std::vector <Neighboring segment labels> > */
std::map<uint32_t, std::set<uint32_t> > seg_label_to_neighbor_set_map_;

};
Expand Down

0 comments on commit 140da8e

Please sign in to comment.