Point Cloud Library (PCL)  1.9.1-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/segmentation/boost.h>
42 #if (BOOST_VERSION >= 104400)
43 #include <pcl/pcl_base.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 
50 namespace pcl
51 {
52  /** \brief This class implements the segmentation algorithm based on minimal cut of the graph.
53  * The description can be found in the article:
54  * "Min-Cut Based Segmentation of Point Clouds"
55  * \author: Aleksey Golovinskiy and Thomas Funkhouser.
56  */
57  template <typename PointT>
58  class PCL_EXPORTS MinCutSegmentation : public pcl::PCLBase<PointT>
59  {
60  public:
61 
62  typedef pcl::search::Search <PointT> KdTree;
63  typedef typename KdTree::Ptr KdTreePtr;
65  typedef typename PointCloud::ConstPtr PointCloudConstPtr;
66 
71 
72  public:
73 
74  typedef boost::adjacency_list_traits< boost::vecS, boost::vecS, boost::directedS > Traits;
75 
76  typedef boost::adjacency_list< boost::vecS, boost::vecS, boost::directedS,
77  boost::property< boost::vertex_name_t, std::string,
78  boost::property< boost::vertex_index_t, long,
79  boost::property< boost::vertex_color_t, boost::default_color_type,
80  boost::property< boost::vertex_distance_t, long,
81  boost::property< boost::vertex_predecessor_t, Traits::edge_descriptor > > > > >,
82  boost::property< boost::edge_capacity_t, double,
83  boost::property< boost::edge_residual_capacity_t, double,
84  boost::property< boost::edge_reverse_t, Traits::edge_descriptor > > > > mGraph;
85 
86  typedef boost::property_map< mGraph, boost::edge_capacity_t >::type CapacityMap;
87 
88  typedef boost::property_map< mGraph, boost::edge_reverse_t>::type ReverseEdgeMap;
89 
90  typedef Traits::vertex_descriptor VertexDescriptor;
91 
92  typedef boost::graph_traits< mGraph >::edge_descriptor EdgeDescriptor;
93 
94  typedef boost::graph_traits< mGraph >::out_edge_iterator OutEdgeIterator;
95 
96  typedef boost::graph_traits< mGraph >::vertex_iterator VertexIterator;
97 
98  typedef boost::property_map< mGraph, boost::edge_residual_capacity_t >::type ResidualCapacityMap;
99 
100  typedef boost::property_map< mGraph, boost::vertex_index_t >::type IndexMap;
101 
102  typedef boost::graph_traits< mGraph >::in_edge_iterator InEdgeIterator;
103 
104  public:
105 
106  /** \brief Constructor that sets default values for member variables. */
107  MinCutSegmentation ();
108 
109  /** \brief Destructor that frees memory. */
110  virtual
111  ~MinCutSegmentation ();
112 
113  /** \brief This method simply sets the input point cloud.
114  * \param[in] cloud the const boost shared pointer to a PointCloud
115  */
116  virtual void
117  setInputCloud (const PointCloudConstPtr &cloud);
118 
119  /** \brief Returns normalization value for binary potentials. For more information see the article. */
120  double
121  getSigma () const;
122 
123  /** \brief Allows to set the normalization value for the binary potentials as described in the article.
124  * \param[in] sigma new normalization value
125  */
126  void
127  setSigma (double sigma);
128 
129  /** \brief Returns radius to the background. */
130  double
131  getRadius () const;
132 
133  /** \brief Allows to set the radius to the background.
134  * \param[in] radius new radius to the background
135  */
136  void
137  setRadius (double radius);
138 
139  /** \brief Returns weight that every edge from the source point has. */
140  double
141  getSourceWeight () const;
142 
143  /** \brief Allows to set weight for source edges. Every edge that comes from the source point will have that weight.
144  * \param[in] weight new weight
145  */
146  void
147  setSourceWeight (double weight);
148 
149  /** \brief Returns search method that is used for finding KNN.
150  * The graph is build such way that it contains the edges that connect point and its KNN.
151  */
152  KdTreePtr
153  getSearchMethod () const;
154 
155  /** \brief Allows to set search method for finding KNN.
156  * The graph is build such way that it contains the edges that connect point and its KNN.
157  * \param[in] search search method that will be used for finding KNN.
158  */
159  void
160  setSearchMethod (const KdTreePtr& tree);
161 
162  /** \brief Returns the number of neighbours to find. */
163  unsigned int
164  getNumberOfNeighbours () const;
165 
166  /** \brief Allows to set the number of neighbours to find.
167  * \param[in] number_of_neighbours new number of neighbours
168  */
169  void
170  setNumberOfNeighbours (unsigned int neighbour_number);
171 
172  /** \brief Returns the points that must belong to foreground. */
173  std::vector<PointT, Eigen::aligned_allocator<PointT> >
174  getForegroundPoints () const;
175 
176  /** \brief Allows to specify points which are known to be the points of the object.
177  * \param[in] foreground_points point cloud that contains foreground points. At least one point must be specified.
178  */
179  void
180  setForegroundPoints (typename pcl::PointCloud<PointT>::Ptr foreground_points);
181 
182  /** \brief Returns the points that must belong to background. */
183  std::vector<PointT, Eigen::aligned_allocator<PointT> >
184  getBackgroundPoints () const;
185 
186  /** \brief Allows to specify points which are known to be the points of the background.
187  * \param[in] background_points point cloud that contains background points.
188  */
189  void
190  setBackgroundPoints (typename pcl::PointCloud<PointT>::Ptr background_points);
191 
192  /** \brief This method launches the segmentation algorithm and returns the clusters that were
193  * obtained during the segmentation. The indices of points that belong to the object will be stored
194  * in the cluster with index 1, other indices will be stored in the cluster with index 0.
195  * \param[out] clusters clusters that were obtained. Each cluster is an array of point indices.
196  */
197  void
198  extract (std::vector <pcl::PointIndices>& clusters);
199 
200  /** \brief Returns that flow value that was calculated during the segmentation. */
201  double
202  getMaxFlow () const;
203 
204  /** \brief Returns the graph that was build for finding the minimum cut. */
205  typename boost::shared_ptr<typename pcl::MinCutSegmentation<PointT>::mGraph>
206  getGraph () const;
207 
208  /** \brief Returns the colored cloud. Points that belong to the object have the same color. */
210  getColoredCloud ();
211 
212  protected:
213 
214  /** \brief This method simply builds the graph that will be used during the segmentation. */
215  bool
216  buildGraph ();
217 
218  /** \brief Returns unary potential(data cost) for the given point index.
219  * In other words it calculates weights for (source, point) and (point, sink) edges.
220  * \param[in] point index of the point for which weights will be calculated
221  * \param[out] source_weight calculated weight for the (source, point) edge
222  * \param[out] sink_weight calculated weight for the (point, sink) edge
223  */
224  void
225  calculateUnaryPotential (int point, double& source_weight, double& sink_weight) const;
226 
227  /** \brief This method simply adds the edge from the source point to the target point with a given weight.
228  * \param[in] source index of the source point of the edge
229  * \param[in] target index of the target point of the edge
230  * \param[in] weight weight that will be assigned to the (source, target) edge
231  */
232  bool
233  addEdge (int source, int target, double weight);
234 
235  /** \brief Returns the binary potential(smooth cost) for the given indices of points.
236  * In other words it returns weight that must be assigned to the edge from source to target point.
237  * \param[in] source index of the source point of the edge
238  * \param[in] target index of the target point of the edge
239  */
240  double
241  calculateBinaryPotential (int source, int target) const;
242 
243  /** \brief This method recalculates unary potentials(data cost) if some changes were made, instead of creating new graph. */
244  bool
245  recalculateUnaryPotentials ();
246 
247  /** \brief This method recalculates binary potentials(smooth cost) if some changes were made, instead of creating new graph. */
248  bool
249  recalculateBinaryPotentials ();
250 
251  /** \brief This method analyzes the residual network and assigns a label to every point in the cloud.
252  * \param[in] residual_capacity residual network that was obtained during the segmentation
253  */
254  void
255  assembleLabels (ResidualCapacityMap& residual_capacity);
256 
257  protected:
258 
259  /** \brief Stores the sigma coefficient. It is used for finding smooth costs. More information can be found in the article. */
260  double inverse_sigma_;
261 
262  /** \brief Signalizes if the binary potentials are valid. */
263  bool binary_potentials_are_valid_;
264 
265  /** \brief Used for comparison of the floating point numbers. */
266  double epsilon_;
267 
268  /** \brief Stores the distance to the background. */
269  double radius_;
270 
271  /** \brief Signalizes if the unary potentials are valid. */
272  bool unary_potentials_are_valid_;
273 
274  /** \brief Stores the weight for every edge that comes from source point. */
275  double source_weight_;
276 
277  /** \brief Stores the search method that will be used for finding K nearest neighbors. Neighbours are used for building the graph. */
278  KdTreePtr search_;
279 
280  /** \brief Stores the number of neighbors to find. */
281  unsigned int number_of_neighbours_;
282 
283  /** \brief Signalizes if the graph is valid. */
284  bool graph_is_valid_;
285 
286  /** \brief Stores the points that are known to be in the foreground. */
287  std::vector<PointT, Eigen::aligned_allocator<PointT> > foreground_points_;
288 
289  /** \brief Stores the points that are known to be in the background. */
290  std::vector<PointT, Eigen::aligned_allocator<PointT> > background_points_;
291 
292  /** \brief After the segmentation it will contain the segments. */
293  std::vector <pcl::PointIndices> clusters_;
294 
295  /** \brief Stores the graph for finding the maximum flow. */
296  boost::shared_ptr<mGraph> graph_;
297 
298  /** \brief Stores the capacity of every edge in the graph. */
299  boost::shared_ptr<CapacityMap> capacity_;
300 
301  /** \brief Stores reverse edges for every edge in the graph. */
302  boost::shared_ptr<ReverseEdgeMap> reverse_edges_;
303 
304  /** \brief Stores the vertices of the graph. */
305  std::vector< VertexDescriptor > vertices_;
306 
307  /** \brief Stores the information about the edges that were added to the graph. It is used to avoid the duplicate edges. */
308  std::vector< std::set<int> > edge_marker_;
309 
310  /** \brief Stores the vertex that serves as source. */
311  VertexDescriptor source_;
312 
313  /** \brief Stores the vertex that serves as sink. */
314  VertexDescriptor sink_;
315 
316  /** \brief Stores the maximum flow value that was calculated during the segmentation. */
317  double max_flow_;
318 
319  public:
320  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
321  };
322 }
323 
324 #ifdef PCL_NO_PRECOMPILE
325 #include <pcl/segmentation/impl/min_cut_segmentation.hpp>
326 #endif
327 
328 #endif
This file defines compatibility wrappers for low level I/O functions.
Definition: convolution.h:44
IndicesPtr indices_
A pointer to the vector of point indices to use.
Definition: pcl_base.h:153
boost::shared_ptr< KdTree< PointT > > Ptr
Definition: kdtree.h:70
bool initCompute()
This method should get called before starting the actual computation.
Definition: pcl_base.hpp:139
boost::shared_ptr< PointCloud< PointT > > Ptr
Definition: point_cloud.h:427
PCL base class.
Definition: pcl_base.h:68
boost::shared_ptr< const PointCloud< PointT > > ConstPtr
Definition: point_cloud.h:428
bool deinitCompute()
This method should get called after finishing the actual computation.
Definition: pcl_base.hpp:174
PointCloud represents the base class in PCL for storing collections of 3D points. ...
PointCloudConstPtr input_
The input point cloud dataset.
Definition: pcl_base.h:150
Generic search class.
Definition: search.h:73