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 (std::size_t i_point = 0; i_point < number_of_indices; i_point++)
337  {
338  index_t point_index = (*indices_)[i_point];
339  double source_weight = 0.0;
340  double sink_weight = 0.0;
341  calculateUnaryPotential (point_index, source_weight, sink_weight);
342  addEdge (static_cast<int> (source_), point_index, source_weight);
343  addEdge (point_index, static_cast<int> (sink_), sink_weight);
344  }
345 
346  std::vector<int> neighbours;
347  std::vector<float> distances;
348  search_->setInputCloud (input_, indices_);
349  for (std::size_t i_point = 0; i_point < number_of_indices; i_point++)
350  {
351  index_t point_index = (*indices_)[i_point];
352  search_->nearestKSearch (i_point, number_of_neighbours_, neighbours, distances);
353  for (std::size_t i_nghbr = 1; i_nghbr < neighbours.size (); i_nghbr++)
354  {
355  double weight = calculateBinaryPotential (point_index, neighbours[i_nghbr]);
356  addEdge (point_index, neighbours[i_nghbr], weight);
357  addEdge (neighbours[i_nghbr], point_index, weight);
358  }
359  neighbours.clear ();
360  distances.clear ();
361  }
362 
363  return (true);
364 }
365 
366 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
367 template <typename PointT> void
368 pcl::MinCutSegmentation<PointT>::calculateUnaryPotential (int point, double& source_weight, double& sink_weight) const
369 {
370  double min_dist_to_foreground = std::numeric_limits<double>::max ();
371  //double min_dist_to_background = std::numeric_limits<double>::max ();
372  //double closest_background_point[] = {0.0, 0.0};
373  double initial_point[] = {0.0, 0.0};
374 
375  initial_point[0] = (*input_)[point].x;
376  initial_point[1] = (*input_)[point].y;
377 
378  for (std::size_t i_point = 0; i_point < foreground_points_.size (); i_point++)
379  {
380  double dist = 0.0;
381  dist += (foreground_points_[i_point].x - initial_point[0]) * (foreground_points_[i_point].x - initial_point[0]);
382  dist += (foreground_points_[i_point].y - initial_point[1]) * (foreground_points_[i_point].y - initial_point[1]);
383  if (min_dist_to_foreground > dist)
384  {
385  min_dist_to_foreground = dist;
386  }
387  }
388 
389  sink_weight = pow (min_dist_to_foreground / radius_, 0.5);
390 
391  source_weight = source_weight_;
392  return;
393 /*
394  if (background_points_.size () == 0)
395  return;
396 
397  for (int i_point = 0; i_point < background_points_.size (); i_point++)
398  {
399  double dist = 0.0;
400  dist += (background_points_[i_point].x - initial_point[0]) * (background_points_[i_point].x - initial_point[0]);
401  dist += (background_points_[i_point].y - initial_point[1]) * (background_points_[i_point].y - initial_point[1]);
402  if (min_dist_to_background > dist)
403  {
404  min_dist_to_background = dist;
405  closest_background_point[0] = background_points_[i_point].x;
406  closest_background_point[1] = background_points_[i_point].y;
407  }
408  }
409 
410  if (min_dist_to_background <= epsilon_)
411  {
412  source_weight = 0.0;
413  sink_weight = 1.0;
414  return;
415  }
416 
417  source_weight = 1.0 / (1.0 + pow (min_dist_to_background / min_dist_to_foreground, 0.5));
418  sink_weight = 1 - source_weight;
419 */
420 }
421 
422 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
423 template <typename PointT> bool
424 pcl::MinCutSegmentation<PointT>::addEdge (int source, int target, double weight)
425 {
426  std::set<int>::iterator iter_out = edge_marker_[source].find (target);
427  if ( iter_out != edge_marker_[source].end () )
428  return (false);
429 
430  EdgeDescriptor edge;
431  EdgeDescriptor reverse_edge;
432  bool edge_was_added, reverse_edge_was_added;
433 
434  boost::tie (edge, edge_was_added) = boost::add_edge ( vertices_[source], vertices_[target], *graph_ );
435  boost::tie (reverse_edge, reverse_edge_was_added) = boost::add_edge ( vertices_[target], vertices_[source], *graph_ );
436  if ( !edge_was_added || !reverse_edge_was_added )
437  return (false);
438 
439  (*capacity_)[edge] = weight;
440  (*capacity_)[reverse_edge] = 0.0;
441  (*reverse_edges_)[edge] = reverse_edge;
442  (*reverse_edges_)[reverse_edge] = edge;
443  edge_marker_[source].insert (target);
444 
445  return (true);
446 }
447 
448 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
449 template <typename PointT> double
451 {
452  double weight = 0.0;
453  double distance = 0.0;
454  distance += ((*input_)[source].x - (*input_)[target].x) * ((*input_)[source].x - (*input_)[target].x);
455  distance += ((*input_)[source].y - (*input_)[target].y) * ((*input_)[source].y - (*input_)[target].y);
456  distance += ((*input_)[source].z - (*input_)[target].z) * ((*input_)[source].z - (*input_)[target].z);
457  distance *= inverse_sigma_;
458  weight = std::exp (-distance);
459 
460  return (weight);
461 }
462 
463 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
464 template <typename PointT> bool
466 {
467  OutEdgeIterator src_edge_iter;
468  OutEdgeIterator src_edge_end;
469  std::pair<EdgeDescriptor, bool> sink_edge;
470 
471  for (boost::tie (src_edge_iter, src_edge_end) = boost::out_edges (source_, *graph_); src_edge_iter != src_edge_end; src_edge_iter++)
472  {
473  double source_weight = 0.0;
474  double sink_weight = 0.0;
475  sink_edge.second = false;
476  calculateUnaryPotential (static_cast<int> (boost::target (*src_edge_iter, *graph_)), source_weight, sink_weight);
477  sink_edge = boost::lookup_edge (boost::target (*src_edge_iter, *graph_), sink_, *graph_);
478  if (!sink_edge.second)
479  return (false);
480 
481  (*capacity_)[*src_edge_iter] = source_weight;
482  (*capacity_)[sink_edge.first] = sink_weight;
483  }
484 
485  return (true);
486 }
487 
488 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
489 template <typename PointT> bool
491 {
492  VertexIterator vertex_iter;
493  VertexIterator vertex_end;
494  OutEdgeIterator edge_iter;
495  OutEdgeIterator edge_end;
496 
497  std::vector< std::set<VertexDescriptor> > edge_marker;
498  std::set<VertexDescriptor> out_edges_marker;
499  edge_marker.clear ();
500  edge_marker.resize (indices_->size () + 2, out_edges_marker);
501 
502  for (boost::tie (vertex_iter, vertex_end) = boost::vertices (*graph_); vertex_iter != vertex_end; vertex_iter++)
503  {
504  VertexDescriptor source_vertex = *vertex_iter;
505  if (source_vertex == source_ || source_vertex == sink_)
506  continue;
507  for (boost::tie (edge_iter, edge_end) = boost::out_edges (source_vertex, *graph_); edge_iter != edge_end; edge_iter++)
508  {
509  //If this is not the edge of the graph, but the reverse fictitious edge that is needed for the algorithm then continue
510  EdgeDescriptor reverse_edge = (*reverse_edges_)[*edge_iter];
511  if ((*capacity_)[reverse_edge] != 0.0)
512  continue;
513 
514  //If we already changed weight for this edge then continue
515  VertexDescriptor target_vertex = boost::target (*edge_iter, *graph_);
516  std::set<VertexDescriptor>::iterator iter_out = edge_marker[static_cast<int> (source_vertex)].find (target_vertex);
517  if ( iter_out != edge_marker[static_cast<int> (source_vertex)].end () )
518  continue;
519 
520  if (target_vertex != source_ && target_vertex != sink_)
521  {
522  //Change weight and remember that this edges were updated
523  double weight = calculateBinaryPotential (static_cast<int> (target_vertex), static_cast<int> (source_vertex));
524  (*capacity_)[*edge_iter] = weight;
525  edge_marker[static_cast<int> (source_vertex)].insert (target_vertex);
526  }
527  }
528  }
529 
530  return (true);
531 }
532 
533 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
534 template <typename PointT> void
536 {
537  std::vector<int> labels;
538  labels.resize (input_->size (), 0);
539  int number_of_indices = static_cast<int> (indices_->size ());
540  for (int i_point = 0; i_point < number_of_indices; i_point++)
541  labels[(*indices_)[i_point]] = 1;
542 
543  clusters_.clear ();
544 
545  pcl::PointIndices segment;
546  clusters_.resize (2, segment);
547 
548  OutEdgeIterator edge_iter, edge_end;
549  for ( boost::tie (edge_iter, edge_end) = boost::out_edges (source_, *graph_); edge_iter != edge_end; edge_iter++ )
550  {
551  if (labels[edge_iter->m_target] == 1)
552  {
553  if (residual_capacity[*edge_iter] > epsilon_)
554  clusters_[1].indices.push_back (static_cast<int> (edge_iter->m_target));
555  else
556  clusters_[0].indices.push_back (static_cast<int> (edge_iter->m_target));
557  }
558  }
559 }
560 
561 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
562 template <typename PointT> pcl::PointCloud<pcl::PointXYZRGB>::Ptr
564 {
566 
567  if (!clusters_.empty ())
568  {
569  int num_of_pts_in_first_cluster = static_cast<int> (clusters_[0].indices.size ());
570  int num_of_pts_in_second_cluster = static_cast<int> (clusters_[1].indices.size ());
571  colored_cloud = (new pcl::PointCloud<pcl::PointXYZRGB>)->makeShared ();
572  unsigned char foreground_color[3] = {255, 255, 255};
573  unsigned char background_color[3] = {255, 0, 0};
574  colored_cloud->width = (num_of_pts_in_first_cluster + num_of_pts_in_second_cluster);
575  colored_cloud->height = 1;
576  colored_cloud->is_dense = input_->is_dense;
577 
578  pcl::PointXYZRGB point;
579  for (int i_point = 0; i_point < num_of_pts_in_first_cluster; i_point++)
580  {
581  index_t point_index = clusters_[0].indices[i_point];
582  point.x = *((*input_)[point_index].data);
583  point.y = *((*input_)[point_index].data + 1);
584  point.z = *((*input_)[point_index].data + 2);
585  point.r = background_color[0];
586  point.g = background_color[1];
587  point.b = background_color[2];
588  colored_cloud->points.push_back (point);
589  }
590 
591  for (int i_point = 0; i_point < num_of_pts_in_second_cluster; i_point++)
592  {
593  index_t point_index = clusters_[1].indices[i_point];
594  point.x = *((*input_)[point_index].data);
595  point.y = *((*input_)[point_index].data + 1);
596  point.z = *((*input_)[point_index].data + 2);
597  point.r = foreground_color[0];
598  point.g = foreground_color[1];
599  point.b = foreground_color[2];
600  colored_cloud->points.push_back (point);
601  }
602  }
603 
604  return (colored_cloud);
605 }
606 
607 #define PCL_INSTANTIATE_MinCutSegmentation(T) template class pcl::MinCutSegmentation<T>;
608 
609 #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:465
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: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: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:427
pcl::MinCutSegmentation::getColoredCloud
pcl::PointCloud< pcl::PointXYZRGB >::Ptr getColoredCloud()
Returns the colored cloud.
Definition: min_cut_segmentation.hpp:563
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:424
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:450
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: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:368
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:396
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: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: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:490
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:535
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