Point Cloud Library (PCL)  1.11.1-dev
min_cut_segmentation.hpp
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 #ifndef PCL_SEGMENTATION_MIN_CUT_SEGMENTATION_HPP_
40 #define PCL_SEGMENTATION_MIN_CUT_SEGMENTATION_HPP_
41 
42 #include <pcl/segmentation/boost.h>
43 #include <pcl/segmentation/min_cut_segmentation.h>
44 #include <pcl/search/search.h>
45 #include <pcl/search/kdtree.h>
46 #include <cmath>
47 
48 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
49 template <typename PointT>
51  inverse_sigma_ (16.0),
52  binary_potentials_are_valid_ (false),
53  epsilon_ (0.0001),
54  radius_ (16.0),
55  unary_potentials_are_valid_ (false),
56  source_weight_ (0.8),
57  search_ (),
58  number_of_neighbours_ (14),
59  graph_is_valid_ (false),
60  foreground_points_ (0),
61  background_points_ (0),
62  clusters_ (0),
63  vertices_ (0),
64  edge_marker_ (0),
65  source_ (),/////////////////////////////////
66  sink_ (),///////////////////////////////////
67  max_flow_ (0.0)
68 {
69 }
70 
71 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
72 template <typename PointT>
74 {
75  foreground_points_.clear ();
76  background_points_.clear ();
77  clusters_.clear ();
78  vertices_.clear ();
79  edge_marker_.clear ();
80 }
81 
82 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
83 template <typename PointT> void
85 {
86  input_ = cloud;
87  graph_is_valid_ = false;
88  unary_potentials_are_valid_ = false;
89  binary_potentials_are_valid_ = false;
90 }
91 
92 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
93 template <typename PointT> double
95 {
96  return (pow (1.0 / inverse_sigma_, 0.5));
97 }
98 
99 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
100 template <typename PointT> void
102 {
103  if (sigma > epsilon_)
104  {
105  inverse_sigma_ = 1.0 / (sigma * sigma);
106  binary_potentials_are_valid_ = false;
107  }
108 }
109 
110 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
111 template <typename PointT> double
113 {
114  return (pow (radius_, 0.5));
115 }
116 
117 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
118 template <typename PointT> void
120 {
121  if (radius > epsilon_)
122  {
123  radius_ = radius * radius;
124  unary_potentials_are_valid_ = false;
125  }
126 }
127 
128 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
129 template <typename PointT> double
131 {
132  return (source_weight_);
133 }
134 
135 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
136 template <typename PointT> void
138 {
139  if (weight > epsilon_)
140  {
141  source_weight_ = weight;
142  unary_potentials_are_valid_ = false;
143  }
144 }
145 
146 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
147 template <typename PointT> typename pcl::MinCutSegmentation<PointT>::KdTreePtr
149 {
150  return (search_);
151 }
152 
153 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
154 template <typename PointT> void
156 {
157  search_ = tree;
158 }
159 
160 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
161 template <typename PointT> unsigned int
163 {
164  return (number_of_neighbours_);
165 }
166 
167 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
168 template <typename PointT> void
170 {
171  if (number_of_neighbours_ != neighbour_number && neighbour_number != 0)
172  {
173  number_of_neighbours_ = neighbour_number;
174  graph_is_valid_ = false;
175  unary_potentials_are_valid_ = false;
176  binary_potentials_are_valid_ = false;
177  }
178 }
179 
180 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
181 template <typename PointT> std::vector<PointT, Eigen::aligned_allocator<PointT> >
183 {
184  return (foreground_points_);
185 }
186 
187 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
188 template <typename PointT> void
190 {
191  foreground_points_.clear ();
192  foreground_points_.insert(
193  foreground_points_.end(), foreground_points->cbegin(), foreground_points->cend());
194 
195  unary_potentials_are_valid_ = false;
196 }
197 
198 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
199 template <typename PointT> std::vector<PointT, Eigen::aligned_allocator<PointT> >
201 {
202  return (background_points_);
203 }
204 
205 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
206 template <typename PointT> void
208 {
209  background_points_.clear ();
210  background_points_.insert(
211  background_points_.end(), background_points->cbegin(), background_points->cend());
212 
213  unary_potentials_are_valid_ = false;
214 }
215 
216 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
217 template <typename PointT> void
218 pcl::MinCutSegmentation<PointT>::extract (std::vector <pcl::PointIndices>& clusters)
219 {
220  clusters.clear ();
221 
222  bool segmentation_is_possible = initCompute ();
223  if ( !segmentation_is_possible )
224  {
225  deinitCompute ();
226  return;
227  }
228 
229  if ( graph_is_valid_ && unary_potentials_are_valid_ && binary_potentials_are_valid_ )
230  {
231  clusters.reserve (clusters_.size ());
232  std::copy (clusters_.begin (), clusters_.end (), std::back_inserter (clusters));
233  deinitCompute ();
234  return;
235  }
236 
237  clusters_.clear ();
238 
239  if ( !graph_is_valid_ )
240  {
241  bool success = buildGraph ();
242  if (!success)
243  {
244  deinitCompute ();
245  return;
246  }
247  graph_is_valid_ = true;
248  unary_potentials_are_valid_ = true;
249  binary_potentials_are_valid_ = true;
250  }
251 
252  if ( !unary_potentials_are_valid_ )
253  {
254  bool success = recalculateUnaryPotentials ();
255  if (!success)
256  {
257  deinitCompute ();
258  return;
259  }
260  unary_potentials_are_valid_ = true;
261  }
262 
263  if ( !binary_potentials_are_valid_ )
264  {
265  bool success = recalculateBinaryPotentials ();
266  if (!success)
267  {
268  deinitCompute ();
269  return;
270  }
271  binary_potentials_are_valid_ = true;
272  }
273 
274  //IndexMap index_map = boost::get (boost::vertex_index, *graph_);
275  ResidualCapacityMap residual_capacity = boost::get (boost::edge_residual_capacity, *graph_);
276 
277  max_flow_ = boost::boykov_kolmogorov_max_flow (*graph_, source_, sink_);
278 
279  assembleLabels (residual_capacity);
280 
281  clusters.reserve (clusters_.size ());
282  std::copy (clusters_.begin (), clusters_.end (), std::back_inserter (clusters));
283 
284  deinitCompute ();
285 }
286 
287 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
288 template <typename PointT> double
290 {
291  return (max_flow_);
292 }
293 
294 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
295 template <typename PointT> typename pcl::MinCutSegmentation<PointT>::mGraphPtr
297 {
298  return (graph_);
299 }
300 
301 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
302 template <typename PointT> bool
304 {
305  const auto number_of_points = input_->size ();
306  const auto number_of_indices = indices_->size ();
307 
308  if (input_->points.empty () || number_of_points == 0 || foreground_points_.empty () == true )
309  return (false);
310 
311  if (!search_)
312  search_.reset (new pcl::search::KdTree<PointT>);
313 
314  graph_.reset (new mGraph);
315 
316  capacity_.reset (new CapacityMap);
317  *capacity_ = boost::get (boost::edge_capacity, *graph_);
318 
319  reverse_edges_.reset (new ReverseEdgeMap);
320  *reverse_edges_ = boost::get (boost::edge_reverse, *graph_);
321 
322  VertexDescriptor vertex_descriptor(0);
323  vertices_.clear ();
324  vertices_.resize (number_of_points + 2, vertex_descriptor);
325 
326  std::set<int> out_edges_marker;
327  edge_marker_.clear ();
328  edge_marker_.resize (number_of_points + 2, out_edges_marker);
329 
330  for (std::size_t i_point = 0; i_point < number_of_points + 2; i_point++)
331  vertices_[i_point] = boost::add_vertex (*graph_);
332 
333  source_ = vertices_[number_of_points];
334  sink_ = vertices_[number_of_points + 1];
335 
336  for (const auto& point_index : (*indices_))
337  {
338  double source_weight = 0.0;
339  double sink_weight = 0.0;
340  calculateUnaryPotential (point_index, source_weight, sink_weight);
341  addEdge (static_cast<int> (source_), point_index, source_weight);
342  addEdge (point_index, static_cast<int> (sink_), sink_weight);
343  }
344 
345  std::vector<int> neighbours;
346  std::vector<float> distances;
347  search_->setInputCloud (input_, indices_);
348  for (std::size_t i_point = 0; i_point < number_of_indices; i_point++)
349  {
350  index_t point_index = (*indices_)[i_point];
351  search_->nearestKSearch (i_point, number_of_neighbours_, neighbours, distances);
352  for (std::size_t i_nghbr = 1; i_nghbr < neighbours.size (); i_nghbr++)
353  {
354  double weight = calculateBinaryPotential (point_index, neighbours[i_nghbr]);
355  addEdge (point_index, neighbours[i_nghbr], weight);
356  addEdge (neighbours[i_nghbr], point_index, weight);
357  }
358  neighbours.clear ();
359  distances.clear ();
360  }
361 
362  return (true);
363 }
364 
365 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
366 template <typename PointT> void
367 pcl::MinCutSegmentation<PointT>::calculateUnaryPotential (int point, double& source_weight, double& sink_weight) const
368 {
369  double min_dist_to_foreground = std::numeric_limits<double>::max ();
370  //double min_dist_to_background = std::numeric_limits<double>::max ();
371  //double closest_background_point[] = {0.0, 0.0};
372  double initial_point[] = {0.0, 0.0};
373 
374  initial_point[0] = (*input_)[point].x;
375  initial_point[1] = (*input_)[point].y;
376 
377  for (const auto& fg_point : foreground_points_)
378  {
379  double dist = 0.0;
380  dist += (fg_point.x - initial_point[0]) * (fg_point.x - initial_point[0]);
381  dist += (fg_point.y - initial_point[1]) * (fg_point.y - initial_point[1]);
382  if (min_dist_to_foreground > dist)
383  {
384  min_dist_to_foreground = dist;
385  }
386  }
387 
388  sink_weight = pow (min_dist_to_foreground / radius_, 0.5);
389 
390  source_weight = source_weight_;
391  return;
392 /*
393  if (background_points_.size () == 0)
394  return;
395 
396  for (const auto& bg_point : background_points_)
397  {
398  double dist = 0.0;
399  dist += (bg_point.x - initial_point[0]) * (bg_point.x - initial_point[0]);
400  dist += (bg_point.y - initial_point[1]) * (bg_point.y - initial_point[1]);
401  if (min_dist_to_background > dist)
402  {
403  min_dist_to_background = dist;
404  closest_background_point[0] = bg_point.x;
405  closest_background_point[1] = bg_point.y;
406  }
407  }
408 
409  if (min_dist_to_background <= epsilon_)
410  {
411  source_weight = 0.0;
412  sink_weight = 1.0;
413  return;
414  }
415 
416  source_weight = 1.0 / (1.0 + pow (min_dist_to_background / min_dist_to_foreground, 0.5));
417  sink_weight = 1 - source_weight;
418 */
419 }
420 
421 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
422 template <typename PointT> bool
423 pcl::MinCutSegmentation<PointT>::addEdge (int source, int target, double weight)
424 {
425  std::set<int>::iterator iter_out = edge_marker_[source].find (target);
426  if ( iter_out != edge_marker_[source].end () )
427  return (false);
428 
429  EdgeDescriptor edge;
430  EdgeDescriptor reverse_edge;
431  bool edge_was_added, reverse_edge_was_added;
432 
433  boost::tie (edge, edge_was_added) = boost::add_edge ( vertices_[source], vertices_[target], *graph_ );
434  boost::tie (reverse_edge, reverse_edge_was_added) = boost::add_edge ( vertices_[target], vertices_[source], *graph_ );
435  if ( !edge_was_added || !reverse_edge_was_added )
436  return (false);
437 
438  (*capacity_)[edge] = weight;
439  (*capacity_)[reverse_edge] = 0.0;
440  (*reverse_edges_)[edge] = reverse_edge;
441  (*reverse_edges_)[reverse_edge] = edge;
442  edge_marker_[source].insert (target);
443 
444  return (true);
445 }
446 
447 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
448 template <typename PointT> double
450 {
451  double weight = 0.0;
452  double distance = 0.0;
453  distance += ((*input_)[source].x - (*input_)[target].x) * ((*input_)[source].x - (*input_)[target].x);
454  distance += ((*input_)[source].y - (*input_)[target].y) * ((*input_)[source].y - (*input_)[target].y);
455  distance += ((*input_)[source].z - (*input_)[target].z) * ((*input_)[source].z - (*input_)[target].z);
456  distance *= inverse_sigma_;
457  weight = std::exp (-distance);
458 
459  return (weight);
460 }
461 
462 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
463 template <typename PointT> bool
465 {
466  OutEdgeIterator src_edge_iter;
467  OutEdgeIterator src_edge_end;
468  std::pair<EdgeDescriptor, bool> sink_edge;
469 
470  for (boost::tie (src_edge_iter, src_edge_end) = boost::out_edges (source_, *graph_); src_edge_iter != src_edge_end; src_edge_iter++)
471  {
472  double source_weight = 0.0;
473  double sink_weight = 0.0;
474  sink_edge.second = false;
475  calculateUnaryPotential (static_cast<int> (boost::target (*src_edge_iter, *graph_)), source_weight, sink_weight);
476  sink_edge = boost::lookup_edge (boost::target (*src_edge_iter, *graph_), sink_, *graph_);
477  if (!sink_edge.second)
478  return (false);
479 
480  (*capacity_)[*src_edge_iter] = source_weight;
481  (*capacity_)[sink_edge.first] = sink_weight;
482  }
483 
484  return (true);
485 }
486 
487 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
488 template <typename PointT> bool
490 {
491  VertexIterator vertex_iter;
492  VertexIterator vertex_end;
493  OutEdgeIterator edge_iter;
494  OutEdgeIterator edge_end;
495 
496  std::vector< std::set<VertexDescriptor> > edge_marker;
497  std::set<VertexDescriptor> out_edges_marker;
498  edge_marker.clear ();
499  edge_marker.resize (indices_->size () + 2, out_edges_marker);
500 
501  for (boost::tie (vertex_iter, vertex_end) = boost::vertices (*graph_); vertex_iter != vertex_end; vertex_iter++)
502  {
503  VertexDescriptor source_vertex = *vertex_iter;
504  if (source_vertex == source_ || source_vertex == sink_)
505  continue;
506  for (boost::tie (edge_iter, edge_end) = boost::out_edges (source_vertex, *graph_); edge_iter != edge_end; edge_iter++)
507  {
508  //If this is not the edge of the graph, but the reverse fictitious edge that is needed for the algorithm then continue
509  EdgeDescriptor reverse_edge = (*reverse_edges_)[*edge_iter];
510  if ((*capacity_)[reverse_edge] != 0.0)
511  continue;
512 
513  //If we already changed weight for this edge then continue
514  VertexDescriptor target_vertex = boost::target (*edge_iter, *graph_);
515  std::set<VertexDescriptor>::iterator iter_out = edge_marker[static_cast<int> (source_vertex)].find (target_vertex);
516  if ( iter_out != edge_marker[static_cast<int> (source_vertex)].end () )
517  continue;
518 
519  if (target_vertex != source_ && target_vertex != sink_)
520  {
521  //Change weight and remember that this edges were updated
522  double weight = calculateBinaryPotential (static_cast<int> (target_vertex), static_cast<int> (source_vertex));
523  (*capacity_)[*edge_iter] = weight;
524  edge_marker[static_cast<int> (source_vertex)].insert (target_vertex);
525  }
526  }
527  }
528 
529  return (true);
530 }
531 
532 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
533 template <typename PointT> void
535 {
536  std::vector<int> labels;
537  labels.resize (input_->size (), 0);
538  for (const auto& i_point : (*indices_))
539  labels[i_point] = 1;
540 
541  clusters_.clear ();
542 
543  pcl::PointIndices segment;
544  clusters_.resize (2, segment);
545 
546  OutEdgeIterator edge_iter, edge_end;
547  for ( boost::tie (edge_iter, edge_end) = boost::out_edges (source_, *graph_); edge_iter != edge_end; edge_iter++ )
548  {
549  if (labels[edge_iter->m_target] == 1)
550  {
551  if (residual_capacity[*edge_iter] > epsilon_)
552  clusters_[1].indices.push_back (static_cast<int> (edge_iter->m_target));
553  else
554  clusters_[0].indices.push_back (static_cast<int> (edge_iter->m_target));
555  }
556  }
557 }
558 
559 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
560 template <typename PointT> pcl::PointCloud<pcl::PointXYZRGB>::Ptr
562 {
564 
565  if (!clusters_.empty ())
566  {
567  colored_cloud = (new pcl::PointCloud<pcl::PointXYZRGB>)->makeShared ();
568  unsigned char foreground_color[3] = {255, 255, 255};
569  unsigned char background_color[3] = {255, 0, 0};
570  colored_cloud->width = (clusters_[0].indices.size () + clusters_[1].indices.size ());
571  colored_cloud->height = 1;
572  colored_cloud->is_dense = input_->is_dense;
573 
574  pcl::PointXYZRGB point;
575  for (const auto& point_index : (clusters_[0].indices))
576  {
577  point.x = *((*input_)[point_index].data);
578  point.y = *((*input_)[point_index].data + 1);
579  point.z = *((*input_)[point_index].data + 2);
580  point.r = background_color[0];
581  point.g = background_color[1];
582  point.b = background_color[2];
583  colored_cloud->points.push_back (point);
584  }
585 
586  for (const auto& point_index : (clusters_[1].indices))
587  {
588  point.x = *((*input_)[point_index].data);
589  point.y = *((*input_)[point_index].data + 1);
590  point.z = *((*input_)[point_index].data + 2);
591  point.r = foreground_color[0];
592  point.g = foreground_color[1];
593  point.b = foreground_color[2];
594  colored_cloud->points.push_back (point);
595  }
596  }
597 
598  return (colored_cloud);
599 }
600 
601 #define PCL_INSTANTIATE_MinCutSegmentation(T) template class pcl::MinCutSegmentation<T>;
602 
603 #endif // PCL_SEGMENTATION_MIN_CUT_SEGMENTATION_HPP_
pcl::MinCutSegmentation::mGraphPtr
shared_ptr< mGraph > mGraphPtr
Definition: min_cut_segmentation.h:105
pcl::MinCutSegmentation::recalculateUnaryPotentials
bool recalculateUnaryPotentials()
This method recalculates unary potentials(data cost) if some changes were made, instead of creating n...
Definition: min_cut_segmentation.hpp:464
pcl::MinCutSegmentation::setSigma
void setSigma(double sigma)
Allows to set the normalization value for the binary potentials as described in the article.
Definition: min_cut_segmentation.hpp:101
pcl::PointCloud::height
std::uint32_t height
The point cloud height (if organized as an image-structure).
Definition: point_cloud.h:394
pcl::MinCutSegmentation::ResidualCapacityMap
boost::property_map< mGraph, boost::edge_residual_capacity_t >::type ResidualCapacityMap
Definition: min_cut_segmentation.h:99
pcl::geometry::distance
float distance(const PointT &p1, const PointT &p2)
Definition: geometry.h:60
pcl::PCLBase::PointCloudConstPtr
typename PointCloud::ConstPtr PointCloudConstPtr
Definition: pcl_base.h:74
pcl::PointCloud::cbegin
const_iterator cbegin() const noexcept
Definition: point_cloud.h:427
pcl::PointCloud::points
std::vector< PointT, Eigen::aligned_allocator< PointT > > points
The point data.
Definition: point_cloud.h:389
pcl::MinCutSegmentation::buildGraph
bool buildGraph()
This method simply builds the graph that will be used during the segmentation.
Definition: min_cut_segmentation.hpp:303
pcl::MinCutSegmentation::setSearchMethod
void setSearchMethod(const KdTreePtr &tree)
Allows to set search method for finding KNN.
Definition: min_cut_segmentation.hpp:155
pcl::MinCutSegmentation::getSigma
double getSigma() const
Returns normalization value for binary potentials.
Definition: min_cut_segmentation.hpp:94
pcl::PointIndices::indices
Indices indices
Definition: PointIndices.h:21
pcl::PointCloud::cend
const_iterator cend() const noexcept
Definition: point_cloud.h:428
pcl::MinCutSegmentation::getColoredCloud
pcl::PointCloud< pcl::PointXYZRGB >::Ptr getColoredCloud()
Returns the colored cloud.
Definition: min_cut_segmentation.hpp:561
pcl::MinCutSegmentation::setSourceWeight
void setSourceWeight(double weight)
Allows to set weight for source edges.
Definition: min_cut_segmentation.hpp:137
pcl::MinCutSegmentation::ReverseEdgeMap
boost::property_map< mGraph, boost::edge_reverse_t >::type ReverseEdgeMap
Definition: min_cut_segmentation.h:89
pcl::MinCutSegmentation::MinCutSegmentation
MinCutSegmentation()
Constructor that sets default values for member variables.
Definition: min_cut_segmentation.hpp:50
pcl::MinCutSegmentation::mGraph
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
Definition: min_cut_segmentation.h:85
pcl::MinCutSegmentation::addEdge
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.
Definition: min_cut_segmentation.hpp:423
pcl::PointCloud< pcl::PointXYZRGB >
pcl::index_t
detail::int_type_t< detail::index_type_size, detail::index_type_signed > index_t
Type used for an index in PCL.
Definition: types.h:110
pcl::MinCutSegmentation::setNumberOfNeighbours
void setNumberOfNeighbours(unsigned int neighbour_number)
Allows to set the number of neighbours to find.
Definition: min_cut_segmentation.hpp:169
pcl::PointXYZRGB
A point structure representing Euclidean xyz coordinates, and the RGB color.
Definition: point_types.hpp:628
pcl::MinCutSegmentation::getGraph
mGraphPtr getGraph() const
Returns the graph that was build for finding the minimum cut.
Definition: min_cut_segmentation.hpp:296
pcl::MinCutSegmentation::VertexIterator
boost::graph_traits< mGraph >::vertex_iterator VertexIterator
Definition: min_cut_segmentation.h:97
pcl::MinCutSegmentation::getSourceWeight
double getSourceWeight() const
Returns weight that every edge from the source point has.
Definition: min_cut_segmentation.hpp:130
pcl::MinCutSegmentation::getForegroundPoints
std::vector< PointT, Eigen::aligned_allocator< PointT > > getForegroundPoints() const
Returns the points that must belong to foreground.
Definition: min_cut_segmentation.hpp:182
pcl::MinCutSegmentation::calculateBinaryPotential
double calculateBinaryPotential(int source, int target) const
Returns the binary potential(smooth cost) for the given indices of points.
Definition: min_cut_segmentation.hpp:449
pcl::PointCloud::width
std::uint32_t width
The point cloud width (if organized as an image-structure).
Definition: point_cloud.h:392
pcl::MinCutSegmentation::getSearchMethod
KdTreePtr getSearchMethod() const
Returns search method that is used for finding KNN.
Definition: min_cut_segmentation.hpp:148
pcl::MinCutSegmentation::getNumberOfNeighbours
unsigned int getNumberOfNeighbours() const
Returns the number of neighbours to find.
Definition: min_cut_segmentation.hpp:162
pcl::MinCutSegmentation::getMaxFlow
double getMaxFlow() const
Returns that flow value that was calculated during the segmentation.
Definition: min_cut_segmentation.hpp:289
pcl::MinCutSegmentation::KdTreePtr
typename KdTree::Ptr KdTreePtr
Definition: min_cut_segmentation.h:64
pcl::MinCutSegmentation::extract
void extract(std::vector< pcl::PointIndices > &clusters)
This method launches the segmentation algorithm and returns the clusters that were obtained during th...
Definition: min_cut_segmentation.hpp:218
pcl::search::KdTree< PointT >
pcl::MinCutSegmentation::calculateUnaryPotential
void calculateUnaryPotential(int point, double &source_weight, double &sink_weight) const
Returns unary potential(data cost) for the given point index.
Definition: min_cut_segmentation.hpp:367
pcl::MinCutSegmentation::setForegroundPoints
void setForegroundPoints(typename pcl::PointCloud< PointT >::Ptr foreground_points)
Allows to specify points which are known to be the points of the object.
Definition: min_cut_segmentation.hpp:189
pcl::MinCutSegmentation::~MinCutSegmentation
~MinCutSegmentation()
Destructor that frees memory.
Definition: min_cut_segmentation.hpp:73
pcl::PointCloud::is_dense
bool is_dense
True if no points are invalid (e.g., have NaN or Inf values in any of their floating point fields).
Definition: point_cloud.h:397
pcl::MinCutSegmentation::setRadius
void setRadius(double radius)
Allows to set the radius to the background.
Definition: min_cut_segmentation.hpp:119
pcl::PointIndices
Definition: PointIndices.h:11
pcl::MinCutSegmentation::setBackgroundPoints
void setBackgroundPoints(typename pcl::PointCloud< PointT >::Ptr background_points)
Allows to specify points which are known to be the points of the background.
Definition: min_cut_segmentation.hpp:207
pcl::PointCloud::Ptr
shared_ptr< PointCloud< PointT > > Ptr
Definition: point_cloud.h:407
pcl::MinCutSegmentation::CapacityMap
boost::property_map< mGraph, boost::edge_capacity_t >::type CapacityMap
Definition: min_cut_segmentation.h:87
pcl::MinCutSegmentation::OutEdgeIterator
boost::graph_traits< mGraph >::out_edge_iterator OutEdgeIterator
Definition: min_cut_segmentation.h:95
pcl::MinCutSegmentation::getRadius
double getRadius() const
Returns radius to the background.
Definition: min_cut_segmentation.hpp:112
pcl::MinCutSegmentation::getBackgroundPoints
std::vector< PointT, Eigen::aligned_allocator< PointT > > getBackgroundPoints() const
Returns the points that must belong to background.
Definition: min_cut_segmentation.hpp:200
pcl::MinCutSegmentation::recalculateBinaryPotentials
bool recalculateBinaryPotentials()
This method recalculates binary potentials(smooth cost) if some changes were made,...
Definition: min_cut_segmentation.hpp:489
pcl::MinCutSegmentation::setInputCloud
void setInputCloud(const PointCloudConstPtr &cloud) override
This method simply sets the input point cloud.
Definition: min_cut_segmentation.hpp:84
pcl::MinCutSegmentation::assembleLabels
void assembleLabels(ResidualCapacityMap &residual_capacity)
This method analyzes the residual network and assigns a label to every point in the cloud.
Definition: min_cut_segmentation.hpp:534
pcl::MinCutSegmentation::EdgeDescriptor
boost::graph_traits< mGraph >::edge_descriptor EdgeDescriptor
Definition: min_cut_segmentation.h:93
pcl::MinCutSegmentation::VertexDescriptor
Traits::vertex_descriptor VertexDescriptor
Definition: min_cut_segmentation.h:91