Point Cloud Library (PCL)  1.14.0-dev
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 
51 namespace 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>
61  {
62  public:
63 
65  using KdTreePtr = typename KdTree::Ptr;
68 
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  */
156  KdTreePtr
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. */
209  mGraphPtr
210  getGraph () const;
211 
212  /** \brief Returns the colored cloud. Points that belong to the object have the same color. */
214  getColoredCloud ();
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
249  recalculateUnaryPotentials ();
250 
251  /** \brief This method recalculates binary potentials(smooth cost) if some changes were made, instead of creating new graph. */
252  bool
253  recalculateBinaryPotentials ();
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. */
267  bool binary_potentials_are_valid_{false};
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. */
276  bool unary_potentials_are_valid_{false};
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. */
282  KdTreePtr search_{nullptr};
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. */
300  mGraphPtr graph_{nullptr};
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. */
315  VertexDescriptor 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
shared_ptr< KdTree< PointT > > Ptr
Definition: kdtree.h:69
This class implements the segmentation algorithm based on minimal cut of the graph.
boost::property_map< mGraph, boost::vertex_index_t >::type IndexMap
MinCutSegmentation()
Constructor that sets default values for member variables.
boost::graph_traits< mGraph >::out_edge_iterator OutEdgeIterator
boost::property_map< mGraph, boost::edge_capacity_t >::type CapacityMap
boost::property_map< mGraph, boost::edge_reverse_t >::type ReverseEdgeMap
shared_ptr< mGraph > mGraphPtr
Traits::vertex_descriptor VertexDescriptor
boost::graph_traits< mGraph >::vertex_iterator VertexIterator
typename KdTree::Ptr KdTreePtr
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
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
boost::adjacency_list_traits< boost::vecS, boost::vecS, boost::directedS > Traits
PCL base class.
Definition: pcl_base.h:70
typename PointCloud::ConstPtr PointCloudConstPtr
Definition: pcl_base.h:74
PointCloud represents the base class in PCL for storing collections of 3D points.
Definition: point_cloud.h:173
shared_ptr< PointCloud< PointT > > Ptr
Definition: point_cloud.h:413
shared_ptr< const PointCloud< PointT > > ConstPtr
Definition: point_cloud.h:414
Generic search class.
Definition: search.h:75
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:63
Defines functions, macros and traits for allocating and using memory.
Defines all the PCL and non-PCL macros used.
#define PCL_EXPORTS
Definition: pcl_macros.h:323