Point Cloud Library (PCL) 1.15.1
Loading...
Searching...
No Matches
min_cut_segmentation.h
1/*
2 * Software License Agreement (BSD License)
3 *
4 * Point Cloud Library (PCL) - www.pointclouds.org
5 *
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer in the documentation and/or other materials provided
17 * with the distribution.
18 * * Neither the name of the copyright holder(s) nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 *
35 * $Id:$
36 *
37 */
38
39#pragma once
40
41#include <pcl/memory.h>
42#include <pcl/pcl_base.h>
43#include <pcl/pcl_macros.h>
44#include <pcl/point_cloud.h>
45#include <pcl/point_types.h>
46#include <pcl/search/search.h>
47#include <string>
48#include <set>
49#include <boost/graph/adjacency_list.hpp> // for adjacency_list
50
51namespace pcl
52{
53 /** \brief This class implements the segmentation algorithm based on minimal cut of the graph.
54 * The description can be found in the article:
55 * "Min-Cut Based Segmentation of Point Clouds"
56 * \author: Aleksey Golovinskiy and Thomas Funkhouser.
57 * \ingroup segmentation
58 */
59 template <typename PointT>
60 class PCL_EXPORTS MinCutSegmentation : public pcl::PCLBase<PointT>
61 {
62 public:
63
65 using KdTreePtr = typename KdTree::Ptr;
68
69 using PCLBase <PointT>::input_;
70 using PCLBase <PointT>::indices_;
71 using PCLBase <PointT>::initCompute;
72 using PCLBase <PointT>::deinitCompute;
73
74 public:
75
76 using Traits = boost::adjacency_list_traits< boost::vecS, boost::vecS, boost::directedS >;
77
78 using mGraph = boost::adjacency_list< boost::vecS, boost::vecS, boost::directedS,
79 boost::property< boost::vertex_name_t, std::string,
80 boost::property< boost::vertex_index_t, long,
81 boost::property< boost::vertex_color_t, boost::default_color_type,
82 boost::property< boost::vertex_distance_t, long,
83 boost::property< boost::vertex_predecessor_t, Traits::edge_descriptor > > > > >,
84 boost::property< boost::edge_capacity_t, double,
85 boost::property< boost::edge_residual_capacity_t, double,
86 boost::property< boost::edge_reverse_t, Traits::edge_descriptor > > > >;
87
88 using CapacityMap = boost::property_map< mGraph, boost::edge_capacity_t >::type;
89
90 using ReverseEdgeMap = boost::property_map< mGraph, boost::edge_reverse_t>::type;
91
92 using VertexDescriptor = Traits::vertex_descriptor;
93
94 using EdgeDescriptor = boost::graph_traits<mGraph>::edge_descriptor;
95
96 using OutEdgeIterator = boost::graph_traits<mGraph>::out_edge_iterator;
97
98 using VertexIterator = boost::graph_traits<mGraph>::vertex_iterator;
99
100 using ResidualCapacityMap = boost::property_map< mGraph, boost::edge_residual_capacity_t >::type;
101
102 using IndexMap = boost::property_map< mGraph, boost::vertex_index_t >::type;
103
104 using InEdgeIterator = boost::graph_traits<mGraph>::in_edge_iterator;
105
106 using mGraphPtr = shared_ptr<mGraph>;
107
108 public:
109
110 /** \brief Constructor that sets default values for member variables. */
112
113 /** \brief Destructor that frees memory. */
114
115 ~MinCutSegmentation () override;
116
117 /** \brief This method simply sets the input point cloud.
118 * \param[in] cloud the const boost shared pointer to a PointCloud
119 */
120 void
121 setInputCloud (const PointCloudConstPtr &cloud) override;
122
123 /** \brief Returns normalization value for binary potentials. For more information see the article. */
124 double
125 getSigma () const;
126
127 /** \brief Allows to set the normalization value for the binary potentials as described in the article.
128 * \param[in] sigma new normalization value
129 */
130 void
131 setSigma (double sigma);
132
133 /** \brief Returns radius to the background. */
134 double
135 getRadius () const;
136
137 /** \brief Allows to set the radius to the background.
138 * \param[in] radius new radius to the background
139 */
140 void
141 setRadius (double radius);
142
143 /** \brief Returns weight that every edge from the source point has. */
144 double
145 getSourceWeight () const;
146
147 /** \brief Allows to set weight for source edges. Every edge that comes from the source point will have that weight.
148 * \param[in] weight new weight
149 */
150 void
151 setSourceWeight (double weight);
152
153 /** \brief Returns search method that is used for finding KNN.
154 * The graph is build such way that it contains the edges that connect point and its KNN.
155 */
157 getSearchMethod () const;
158
159 /** \brief Allows to set search method for finding KNN.
160 * The graph is build such way that it contains the edges that connect point and its KNN.
161 * \param[in] tree search method that will be used for finding KNN.
162 */
163 void
164 setSearchMethod (const KdTreePtr& tree);
165
166 /** \brief Returns the number of neighbours to find. */
167 unsigned int
168 getNumberOfNeighbours () const;
169
170 /** \brief Allows to set the number of neighbours to find.
171 * \param[in] neighbour_number new number of neighbours
172 */
173 void
174 setNumberOfNeighbours (unsigned int neighbour_number);
175
176 /** \brief Returns the points that must belong to foreground. */
177 std::vector<PointT, Eigen::aligned_allocator<PointT> >
178 getForegroundPoints () const;
179
180 /** \brief Allows to specify points which are known to be the points of the object.
181 * \param[in] foreground_points point cloud that contains foreground points. At least one point must be specified.
182 */
183 void
184 setForegroundPoints (typename pcl::PointCloud<PointT>::Ptr foreground_points);
185
186 /** \brief Returns the points that must belong to background. */
187 std::vector<PointT, Eigen::aligned_allocator<PointT> >
188 getBackgroundPoints () const;
189
190 /** \brief Allows to specify points which are known to be the points of the background.
191 * \param[in] background_points point cloud that contains background points.
192 */
193 void
194 setBackgroundPoints (typename pcl::PointCloud<PointT>::Ptr background_points);
195
196 /** \brief This method launches the segmentation algorithm and returns the clusters that were
197 * obtained during the segmentation. The indices of points that belong to the object will be stored
198 * in the cluster with index 1, other indices will be stored in the cluster with index 0.
199 * \param[out] clusters clusters that were obtained. Each cluster is an array of point indices.
200 */
201 void
202 extract (std::vector <pcl::PointIndices>& clusters);
203
204 /** \brief Returns that flow value that was calculated during the segmentation. */
205 double
206 getMaxFlow () const;
207
208 /** \brief Returns the graph that was build for finding the minimum cut. */
210 getGraph () const;
211
212 /** \brief Returns the colored cloud. Points that belong to the object have the same color. */
215
216 protected:
217
218 /** \brief This method simply builds the graph that will be used during the segmentation. */
219 bool
220 buildGraph ();
221
222 /** \brief Returns unary potential(data cost) for the given point index.
223 * In other words it calculates weights for (source, point) and (point, sink) edges.
224 * \param[in] point index of the point for which weights will be calculated
225 * \param[out] source_weight calculated weight for the (source, point) edge
226 * \param[out] sink_weight calculated weight for the (point, sink) edge
227 */
228 void
229 calculateUnaryPotential (int point, double& source_weight, double& sink_weight) const;
230
231 /** \brief This method simply adds the edge from the source point to the target point with a given weight.
232 * \param[in] source index of the source point of the edge
233 * \param[in] target index of the target point of the edge
234 * \param[in] weight weight that will be assigned to the (source, target) edge
235 */
236 bool
237 addEdge (int source, int target, double weight);
238
239 /** \brief Returns the binary potential(smooth cost) for the given indices of points.
240 * In other words it returns weight that must be assigned to the edge from source to target point.
241 * \param[in] source index of the source point of the edge
242 * \param[in] target index of the target point of the edge
243 */
244 double
245 calculateBinaryPotential (int source, int target) const;
246
247 /** \brief This method recalculates unary potentials(data cost) if some changes were made, instead of creating new graph. */
248 bool
250
251 /** \brief This method recalculates binary potentials(smooth cost) if some changes were made, instead of creating new graph. */
252 bool
254
255 /** \brief This method analyzes the residual network and assigns a label to every point in the cloud.
256 * \param[in] residual_capacity residual network that was obtained during the segmentation
257 */
258 void
259 assembleLabels (ResidualCapacityMap& residual_capacity);
260
261 protected:
262
263 /** \brief Stores the sigma coefficient. It is used for finding smooth costs. More information can be found in the article. */
264 double inverse_sigma_{16.0};
265
266 /** \brief Signalizes if the binary potentials are valid. */
268
269 /** \brief Used for comparison of the floating point numbers. */
270 double epsilon_{0.0001};
271
272 /** \brief Stores the distance to the background. */
273 double radius_{16.0};
274
275 /** \brief Signalizes if the unary potentials are valid. */
277
278 /** \brief Stores the weight for every edge that comes from source point. */
279 double source_weight_{0.8};
280
281 /** \brief Stores the search method that will be used for finding K nearest neighbors. Neighbours are used for building the graph. */
283
284 /** \brief Stores the number of neighbors to find. */
285 unsigned int number_of_neighbours_{14};
286
287 /** \brief Signalizes if the graph is valid. */
288 bool graph_is_valid_{false};
289
290 /** \brief Stores the points that are known to be in the foreground. */
291 std::vector<PointT, Eigen::aligned_allocator<PointT> > foreground_points_{};
292
293 /** \brief Stores the points that are known to be in the background. */
294 std::vector<PointT, Eigen::aligned_allocator<PointT> > background_points_{};
295
296 /** \brief After the segmentation it will contain the segments. */
297 std::vector <pcl::PointIndices> clusters_{};
298
299 /** \brief Stores the graph for finding the maximum flow. */
301
302 /** \brief Stores the capacity of every edge in the graph. */
303 std::shared_ptr<CapacityMap> capacity_{nullptr};
304
305 /** \brief Stores reverse edges for every edge in the graph. */
306 std::shared_ptr<ReverseEdgeMap> reverse_edges_{nullptr};
307
308 /** \brief Stores the vertices of the graph. */
309 std::vector< VertexDescriptor > vertices_{};
310
311 /** \brief Stores the information about the edges that were added to the graph. It is used to avoid the duplicate edges. */
312 std::vector< std::set<int> > edge_marker_{};
313
314 /** \brief Stores the vertex that serves as source. */
316
317 /** \brief Stores the vertex that serves as sink. */
319
320 /** \brief Stores the maximum flow value that was calculated during the segmentation. */
321 double max_flow_{0.0};
322
323 public:
325 };
326}
327
328#ifdef PCL_NO_PRECOMPILE
329#include <pcl/segmentation/impl/min_cut_segmentation.hpp>
330#endif
KdTreePtr getSearchMethod() const
Returns search method that is used for finding KNN.
std::shared_ptr< ReverseEdgeMap > reverse_edges_
Stores reverse edges for every edge in the graph.
double max_flow_
Stores the maximum flow value that was calculated during the segmentation.
double inverse_sigma_
Stores the sigma coefficient.
unsigned int number_of_neighbours_
Stores the number of neighbors to find.
double source_weight_
Stores the weight for every edge that comes from source point.
void calculateUnaryPotential(int point, double &source_weight, double &sink_weight) const
Returns unary potential(data cost) for the given point index.
boost::property_map< mGraph, boost::vertex_index_t >::type IndexMap
void setSigma(double sigma)
Allows to set the normalization value for the binary potentials as described in the article.
std::vector< pcl::PointIndices > clusters_
After the segmentation it will contain the segments.
mGraphPtr graph_
Stores the graph for finding the maximum flow.
double getSigma() const
Returns normalization value for binary potentials.
pcl::PointCloud< PointT > PointCloud
MinCutSegmentation()
Constructor that sets default values for member variables.
void setRadius(double radius)
Allows to set the radius to the background.
void extract(std::vector< pcl::PointIndices > &clusters)
This method launches the segmentation algorithm and returns the clusters that were obtained during th...
double epsilon_
Used for comparison of the floating point numbers.
double getSourceWeight() const
Returns weight that every edge from the source point has.
mGraphPtr getGraph() const
Returns the graph that was build for finding the minimum cut.
void setInputCloud(const PointCloudConstPtr &cloud) override
This method simply sets the input point cloud.
std::vector< PointT, Eigen::aligned_allocator< PointT > > foreground_points_
Stores the points that are known to be in the foreground.
void setSourceWeight(double weight)
Allows to set weight for source edges.
void setBackgroundPoints(typename pcl::PointCloud< PointT >::Ptr background_points)
Allows to specify points which are known to be the points of the background.
boost::graph_traits< mGraph >::out_edge_iterator OutEdgeIterator
VertexDescriptor sink_
Stores the vertex that serves as sink.
bool unary_potentials_are_valid_
Signalizes if the unary potentials are valid.
KdTreePtr search_
Stores the search method that will be used for finding K nearest neighbors.
boost::adjacency_list< boost::vecS, boost::vecS, boost::directedS, boost::property< boost::vertex_name_t, std::string, boost::property< boost::vertex_index_t, long, boost::property< boost::vertex_color_t, boost::default_color_type, boost::property< boost::vertex_distance_t, long, boost::property< boost::vertex_predecessor_t, Traits::edge_descriptor > > > > >, boost::property< boost::edge_capacity_t, double, boost::property< boost::edge_residual_capacity_t, double, boost::property< boost::edge_reverse_t, Traits::edge_descriptor > > > > mGraph
unsigned int getNumberOfNeighbours() const
Returns the number of neighbours to find.
bool buildGraph()
This method simply builds the graph that will be used during the segmentation.
std::shared_ptr< CapacityMap > capacity_
Stores the capacity of every edge in the graph.
boost::property_map< mGraph, boost::edge_capacity_t >::type CapacityMap
double getMaxFlow() const
Returns that flow value that was calculated during the segmentation.
VertexDescriptor source_
Stores the vertex that serves as source.
bool graph_is_valid_
Signalizes if the graph is valid.
bool recalculateUnaryPotentials()
This method recalculates unary potentials(data cost) if some changes were made, instead of creating n...
pcl::search::Search< PointT > KdTree
boost::property_map< mGraph, boost::edge_reverse_t >::type ReverseEdgeMap
shared_ptr< mGraph > mGraphPtr
void setSearchMethod(const KdTreePtr &tree)
Allows to set search method for finding KNN.
double getRadius() const
Returns radius to the background.
double calculateBinaryPotential(int source, int target) const
Returns the binary potential(smooth cost) for the given indices of points.
bool recalculateBinaryPotentials()
This method recalculates binary potentials(smooth cost) if some changes were made,...
std::vector< PointT, Eigen::aligned_allocator< PointT > > getBackgroundPoints() const
Returns the points that must belong to background.
bool addEdge(int source, int target, double weight)
This method simply adds the edge from the source point to the target point with a given weight.
Traits::vertex_descriptor VertexDescriptor
void setNumberOfNeighbours(unsigned int neighbour_number)
Allows to set the number of neighbours to find.
std::vector< VertexDescriptor > vertices_
Stores the vertices of the graph.
typename PointCloud::ConstPtr PointCloudConstPtr
boost::graph_traits< mGraph >::vertex_iterator VertexIterator
std::vector< PointT, Eigen::aligned_allocator< PointT > > background_points_
Stores the points that are known to be in the background.
std::vector< std::set< int > > edge_marker_
Stores the information about the edges that were added to the graph.
typename KdTree::Ptr KdTreePtr
std::vector< PointT, Eigen::aligned_allocator< PointT > > getForegroundPoints() const
Returns the points that must belong to foreground.
bool binary_potentials_are_valid_
Signalizes if the binary potentials are valid.
boost::graph_traits< mGraph >::edge_descriptor EdgeDescriptor
boost::graph_traits< mGraph >::in_edge_iterator InEdgeIterator
boost::property_map< mGraph, boost::edge_residual_capacity_t >::type ResidualCapacityMap
void setForegroundPoints(typename pcl::PointCloud< PointT >::Ptr foreground_points)
Allows to specify points which are known to be the points of the object.
pcl::PointCloud< pcl::PointXYZRGB >::Ptr getColoredCloud()
Returns the colored cloud.
boost::adjacency_list_traits< boost::vecS, boost::vecS, boost::directedS > Traits
void assembleLabels(ResidualCapacityMap &residual_capacity)
This method analyzes the residual network and assigns a label to every point in the cloud.
double radius_
Stores the distance to the background.
PCL base class.
Definition pcl_base.h:70
PointCloudConstPtr input_
The input point cloud dataset.
Definition pcl_base.h:147
IndicesPtr indices_
A pointer to the vector of point indices to use.
Definition pcl_base.h:150
bool initCompute()
This method should get called before starting the actual computation.
Definition pcl_base.hpp:138
PCLBase()
Empty constructor.
Definition pcl_base.hpp:46
bool deinitCompute()
This method should get called after finishing the actual computation.
Definition pcl_base.hpp:175
PointCloud represents the base class in PCL for storing collections of 3D points.
shared_ptr< PointCloud< PointT > > Ptr
shared_ptr< const PointCloud< PointT > > ConstPtr
Generic search class.
Definition search.h:75
shared_ptr< pcl::search::Search< PointT > > Ptr
Definition search.h:81
Defines all the PCL implemented PointT point type structures.
#define PCL_MAKE_ALIGNED_OPERATOR_NEW
Macro to signal a class requires a custom allocator.
Definition memory.h:86
Defines functions, macros and traits for allocating and using memory.
Defines all the PCL and non-PCL macros used.