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