min_cut_segmentation.hpp
/*
* Software License Agreement (BSD License)
*
* Point Cloud Library (PCL) - www.pointclouds.org
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holder(s) nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $Id:$
*
*/
#ifndef PCL_SEGMENTATION_MIN_CUT_SEGMENTATION_HPP_
#define PCL_SEGMENTATION_MIN_CUT_SEGMENTATION_HPP_
#include <pcl/segmentation/boost.h>
#include <pcl/segmentation/min_cut_segmentation.h>
#include <pcl/search/search.h>
#include <pcl/search/kdtree.h>
#include <cstdlib>
#include <cmath>
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT>
pcl::MinCutSegmentation<PointT>::MinCutSegmentation () :
inverse_sigma_ (16.0),
binary_potentials_are_valid_ (false),
epsilon_ (0.0001),
radius_ (16.0),
unary_potentials_are_valid_ (false),
source_weight_ (0.8),
search_ (),
number_of_neighbours_ (14),
graph_is_valid_ (false),
foreground_points_ (0),
background_points_ (0),
clusters_ (0),
vertices_ (0),
edge_marker_ (0),
source_ (),/////////////////////////////////
sink_ (),///////////////////////////////////
max_flow_ (0.0)
{
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT>
pcl::MinCutSegmentation<PointT>::~MinCutSegmentation ()
{
foreground_points_.clear ();
background_points_.clear ();
clusters_.clear ();
vertices_.clear ();
edge_marker_.clear ();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::MinCutSegmentation<PointT>::setInputCloud (const PointCloudConstPtr &cloud)
{
input_ = cloud;
graph_is_valid_ = false;
unary_potentials_are_valid_ = false;
binary_potentials_are_valid_ = false;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> double
pcl::MinCutSegmentation<PointT>::getSigma () const
{
return (pow (1.0 / inverse_sigma_, 0.5));
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::MinCutSegmentation<PointT>::setSigma (double sigma)
{
if (sigma > epsilon_)
{
inverse_sigma_ = 1.0 / (sigma * sigma);
binary_potentials_are_valid_ = false;
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> double
pcl::MinCutSegmentation<PointT>::getRadius () const
{
return (pow (radius_, 0.5));
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::MinCutSegmentation<PointT>::setRadius (double radius)
{
if (radius > epsilon_)
{
radius_ = radius * radius;
unary_potentials_are_valid_ = false;
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> double
pcl::MinCutSegmentation<PointT>::getSourceWeight () const
{
return (source_weight_);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::MinCutSegmentation<PointT>::setSourceWeight (double weight)
{
if (weight > epsilon_)
{
source_weight_ = weight;
unary_potentials_are_valid_ = false;
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> typename pcl::MinCutSegmentation<PointT>::KdTreePtr
pcl::MinCutSegmentation<PointT>::getSearchMethod () const
{
return (search_);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::MinCutSegmentation<PointT>::setSearchMethod (const KdTreePtr& tree)
{
search_ = tree;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> unsigned int
pcl::MinCutSegmentation<PointT>::getNumberOfNeighbours () const
{
return (number_of_neighbours_);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::MinCutSegmentation<PointT>::setNumberOfNeighbours (unsigned int neighbour_number)
{
if (number_of_neighbours_ != neighbour_number && neighbour_number != 0)
{
number_of_neighbours_ = neighbour_number;
graph_is_valid_ = false;
unary_potentials_are_valid_ = false;
binary_potentials_are_valid_ = false;
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> std::vector<PointT, Eigen::aligned_allocator<PointT> >
pcl::MinCutSegmentation<PointT>::getForegroundPoints () const
{
return (foreground_points_);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::MinCutSegmentation<PointT>::setForegroundPoints (typename pcl::PointCloud<PointT>::Ptr foreground_points)
{
foreground_points_.clear ();
foreground_points_.reserve (foreground_points->points.size ());
for (std::size_t i_point = 0; i_point < foreground_points->points.size (); i_point++)
foreground_points_.push_back (foreground_points->points[i_point]);
unary_potentials_are_valid_ = false;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> std::vector<PointT, Eigen::aligned_allocator<PointT> >
pcl::MinCutSegmentation<PointT>::getBackgroundPoints () const
{
return (background_points_);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::MinCutSegmentation<PointT>::setBackgroundPoints (typename pcl::PointCloud<PointT>::Ptr background_points)
{
background_points_.clear ();
background_points_.reserve (background_points->points.size ());
for (std::size_t i_point = 0; i_point < background_points->points.size (); i_point++)
background_points_.push_back (background_points->points[i_point]);
unary_potentials_are_valid_ = false;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::MinCutSegmentation<PointT>::extract (std::vector <pcl::PointIndices>& clusters)
{
clusters.clear ();
bool segmentation_is_possible = initCompute ();
if ( !segmentation_is_possible )
{
deinitCompute ();
return;
}
if ( graph_is_valid_ && unary_potentials_are_valid_ && binary_potentials_are_valid_ )
{
clusters.reserve (clusters_.size ());
std::copy (clusters_.begin (), clusters_.end (), std::back_inserter (clusters));
deinitCompute ();
return;
}
clusters_.clear ();
bool success = true;
if ( !graph_is_valid_ )
{
success = buildGraph ();
if (!success)
{
deinitCompute ();
return;
}
graph_is_valid_ = true;
unary_potentials_are_valid_ = true;
binary_potentials_are_valid_ = true;
}
if ( !unary_potentials_are_valid_ )
{
success = recalculateUnaryPotentials ();
if (!success)
{
deinitCompute ();
return;
}
unary_potentials_are_valid_ = true;
}
if ( !binary_potentials_are_valid_ )
{
success = recalculateBinaryPotentials ();
if (!success)
{
deinitCompute ();
return;
}
binary_potentials_are_valid_ = true;
}
//IndexMap index_map = boost::get (boost::vertex_index, *graph_);
ResidualCapacityMap residual_capacity = boost::get (boost::edge_residual_capacity, *graph_);
max_flow_ = boost::boykov_kolmogorov_max_flow (*graph_, source_, sink_);
assembleLabels (residual_capacity);
clusters.reserve (clusters_.size ());
std::copy (clusters_.begin (), clusters_.end (), std::back_inserter (clusters));
deinitCompute ();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> double
pcl::MinCutSegmentation<PointT>::getMaxFlow () const
{
return (max_flow_);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> typename pcl::MinCutSegmentation<PointT>::mGraphPtr
pcl::MinCutSegmentation<PointT>::getGraph () const
{
return (graph_);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::MinCutSegmentation<PointT>::buildGraph ()
{
int number_of_points = static_cast<int> (input_->points.size ());
int number_of_indices = static_cast<int> (indices_->size ());
if (input_->points.empty () || number_of_points == 0 || foreground_points_.empty () == true )
return (false);
if (!search_)
search_.reset (new pcl::search::KdTree<PointT>);
graph_.reset (new mGraph);
capacity_.reset (new CapacityMap);
*capacity_ = boost::get (boost::edge_capacity, *graph_);
reverse_edges_.reset (new ReverseEdgeMap);
*reverse_edges_ = boost::get (boost::edge_reverse, *graph_);
VertexDescriptor vertex_descriptor(0);
vertices_.clear ();
vertices_.resize (number_of_points + 2, vertex_descriptor);
std::set<int> out_edges_marker;
edge_marker_.clear ();
edge_marker_.resize (number_of_points + 2, out_edges_marker);
for (int i_point = 0; i_point < number_of_points + 2; i_point++)
vertices_[i_point] = boost::add_vertex (*graph_);
source_ = vertices_[number_of_points];
sink_ = vertices_[number_of_points + 1];
for (int i_point = 0; i_point < number_of_indices; i_point++)
{
int point_index = (*indices_)[i_point];
double source_weight = 0.0;
double sink_weight = 0.0;
calculateUnaryPotential (point_index, source_weight, sink_weight);
addEdge (static_cast<int> (source_), point_index, source_weight);
addEdge (point_index, static_cast<int> (sink_), sink_weight);
}
std::vector<int> neighbours;
std::vector<float> distances;
search_->setInputCloud (input_, indices_);
for (int i_point = 0; i_point < number_of_indices; i_point++)
{
int point_index = (*indices_)[i_point];
search_->nearestKSearch (i_point, number_of_neighbours_, neighbours, distances);
for (std::size_t i_nghbr = 1; i_nghbr < neighbours.size (); i_nghbr++)
{
double weight = calculateBinaryPotential (point_index, neighbours[i_nghbr]);
addEdge (point_index, neighbours[i_nghbr], weight);
addEdge (neighbours[i_nghbr], point_index, weight);
}
neighbours.clear ();
distances.clear ();
}
return (true);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::MinCutSegmentation<PointT>::calculateUnaryPotential (int point, double& source_weight, double& sink_weight) const
{
double min_dist_to_foreground = std::numeric_limits<double>::max ();
//double min_dist_to_background = std::numeric_limits<double>::max ();
double closest_foreground_point[2];
closest_foreground_point[0] = closest_foreground_point[1] = 0;
//double closest_background_point[] = {0.0, 0.0};
double initial_point[] = {0.0, 0.0};
initial_point[0] = input_->points[point].x;
initial_point[1] = input_->points[point].y;
for (std::size_t i_point = 0; i_point < foreground_points_.size (); i_point++)
{
double dist = 0.0;
dist += (foreground_points_[i_point].x - initial_point[0]) * (foreground_points_[i_point].x - initial_point[0]);
dist += (foreground_points_[i_point].y - initial_point[1]) * (foreground_points_[i_point].y - initial_point[1]);
if (min_dist_to_foreground > dist)
{
min_dist_to_foreground = dist;
closest_foreground_point[0] = foreground_points_[i_point].x;
closest_foreground_point[1] = foreground_points_[i_point].y;
}
}
sink_weight = pow (min_dist_to_foreground / radius_, 0.5);
source_weight = source_weight_;
return;
/*
if (background_points_.size () == 0)
return;
for (int i_point = 0; i_point < background_points_.size (); i_point++)
{
double dist = 0.0;
dist += (background_points_[i_point].x - initial_point[0]) * (background_points_[i_point].x - initial_point[0]);
dist += (background_points_[i_point].y - initial_point[1]) * (background_points_[i_point].y - initial_point[1]);
if (min_dist_to_background > dist)
{
min_dist_to_background = dist;
closest_background_point[0] = background_points_[i_point].x;
closest_background_point[1] = background_points_[i_point].y;
}
}
if (min_dist_to_background <= epsilon_)
{
source_weight = 0.0;
sink_weight = 1.0;
return;
}
source_weight = 1.0 / (1.0 + pow (min_dist_to_background / min_dist_to_foreground, 0.5));
sink_weight = 1 - source_weight;
*/
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::MinCutSegmentation<PointT>::addEdge (int source, int target, double weight)
{
std::set<int>::iterator iter_out = edge_marker_[source].find (target);
if ( iter_out != edge_marker_[source].end () )
return (false);
EdgeDescriptor edge;
EdgeDescriptor reverse_edge;
bool edge_was_added, reverse_edge_was_added;
boost::tie (edge, edge_was_added) = boost::add_edge ( vertices_[source], vertices_[target], *graph_ );
boost::tie (reverse_edge, reverse_edge_was_added) = boost::add_edge ( vertices_[target], vertices_[source], *graph_ );
if ( !edge_was_added || !reverse_edge_was_added )
return (false);
(*capacity_)[edge] = weight;
(*capacity_)[reverse_edge] = 0.0;
(*reverse_edges_)[edge] = reverse_edge;
(*reverse_edges_)[reverse_edge] = edge;
edge_marker_[source].insert (target);
return (true);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> double
pcl::MinCutSegmentation<PointT>::calculateBinaryPotential (int source, int target) const
{
double weight = 0.0;
double distance = 0.0;
distance += (input_->points[source].x - input_->points[target].x) * (input_->points[source].x - input_->points[target].x);
distance += (input_->points[source].y - input_->points[target].y) * (input_->points[source].y - input_->points[target].y);
distance += (input_->points[source].z - input_->points[target].z) * (input_->points[source].z - input_->points[target].z);
distance *= inverse_sigma_;
weight = std::exp (-distance);
return (weight);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::MinCutSegmentation<PointT>::recalculateUnaryPotentials ()
{
OutEdgeIterator src_edge_iter;
OutEdgeIterator src_edge_end;
std::pair<EdgeDescriptor, bool> sink_edge;
for (boost::tie (src_edge_iter, src_edge_end) = boost::out_edges (source_, *graph_); src_edge_iter != src_edge_end; src_edge_iter++)
{
double source_weight = 0.0;
double sink_weight = 0.0;
sink_edge.second = false;
calculateUnaryPotential (static_cast<int> (boost::target (*src_edge_iter, *graph_)), source_weight, sink_weight);
sink_edge = boost::lookup_edge (boost::target (*src_edge_iter, *graph_), sink_, *graph_);
if (!sink_edge.second)
return (false);
(*capacity_)[*src_edge_iter] = source_weight;
(*capacity_)[sink_edge.first] = sink_weight;
}
return (true);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::MinCutSegmentation<PointT>::recalculateBinaryPotentials ()
{
int number_of_points = static_cast<int> (indices_->size ());
VertexIterator vertex_iter;
VertexIterator vertex_end;
OutEdgeIterator edge_iter;
OutEdgeIterator edge_end;
std::vector< std::set<VertexDescriptor> > edge_marker;
std::set<VertexDescriptor> out_edges_marker;
edge_marker.clear ();
edge_marker.resize (number_of_points + 2, out_edges_marker);
for (boost::tie (vertex_iter, vertex_end) = boost::vertices (*graph_); vertex_iter != vertex_end; vertex_iter++)
{
VertexDescriptor source_vertex = *vertex_iter;
if (source_vertex == source_ || source_vertex == sink_)
continue;
for (boost::tie (edge_iter, edge_end) = boost::out_edges (source_vertex, *graph_); edge_iter != edge_end; edge_iter++)
{
//If this is not the edge of the graph, but the reverse fictitious edge that is needed for the algorithm then continue
EdgeDescriptor reverse_edge = (*reverse_edges_)[*edge_iter];
if ((*capacity_)[reverse_edge] != 0.0)
continue;
//If we already changed weight for this edge then continue
VertexDescriptor target_vertex = boost::target (*edge_iter, *graph_);
std::set<VertexDescriptor>::iterator iter_out = edge_marker[static_cast<int> (source_vertex)].find (target_vertex);
if ( iter_out != edge_marker[static_cast<int> (source_vertex)].end () )
continue;
if (target_vertex != source_ && target_vertex != sink_)
{
//Change weight and remember that this edges were updated
double weight = calculateBinaryPotential (static_cast<int> (target_vertex), static_cast<int> (source_vertex));
(*capacity_)[*edge_iter] = weight;
edge_marker[static_cast<int> (source_vertex)].insert (target_vertex);
}
}
}
return (true);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::MinCutSegmentation<PointT>::assembleLabels (ResidualCapacityMap& residual_capacity)
{
std::vector<int> labels;
labels.resize (input_->points.size (), 0);
int number_of_indices = static_cast<int> (indices_->size ());
for (int i_point = 0; i_point < number_of_indices; i_point++)
labels[(*indices_)[i_point]] = 1;
clusters_.clear ();
pcl::PointIndices segment;
clusters_.resize (2, segment);
OutEdgeIterator edge_iter, edge_end;
for ( boost::tie (edge_iter, edge_end) = boost::out_edges (source_, *graph_); edge_iter != edge_end; edge_iter++ )
{
if (labels[edge_iter->m_target] == 1)
{
if (residual_capacity[*edge_iter] > epsilon_)
clusters_[1].indices.push_back (static_cast<int> (edge_iter->m_target));
else
clusters_[0].indices.push_back (static_cast<int> (edge_iter->m_target));
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> pcl::PointCloud<pcl::PointXYZRGB>::Ptr
pcl::MinCutSegmentation<PointT>::getColoredCloud ()
{
pcl::PointCloud<pcl::PointXYZRGB>::Ptr colored_cloud;
if (!clusters_.empty ())
{
int num_of_pts_in_first_cluster = static_cast<int> (clusters_[0].indices.size ());
int num_of_pts_in_second_cluster = static_cast<int> (clusters_[1].indices.size ());
int number_of_points = num_of_pts_in_first_cluster + num_of_pts_in_second_cluster;
colored_cloud = (new pcl::PointCloud<pcl::PointXYZRGB>)->makeShared ();
unsigned char foreground_color[3] = {255, 255, 255};
unsigned char background_color[3] = {255, 0, 0};
colored_cloud->width = number_of_points;
colored_cloud->height = 1;
colored_cloud->is_dense = input_->is_dense;
pcl::PointXYZRGB point;
int point_index = 0;
for (int i_point = 0; i_point < num_of_pts_in_first_cluster; i_point++)
{
point_index = clusters_[0].indices[i_point];
point.x = *(input_->points[point_index].data);
point.y = *(input_->points[point_index].data + 1);
point.z = *(input_->points[point_index].data + 2);
point.r = background_color[0];
point.g = background_color[1];
point.b = background_color[2];
colored_cloud->points.push_back (point);
}
for (int i_point = 0; i_point < num_of_pts_in_second_cluster; i_point++)
{
point_index = clusters_[1].indices[i_point];
point.x = *(input_->points[point_index].data);
point.y = *(input_->points[point_index].data + 1);
point.z = *(input_->points[point_index].data + 2);
point.r = foreground_color[0];
point.g = foreground_color[1];
point.b = foreground_color[2];
colored_cloud->points.push_back (point);
}
}
return (colored_cloud);
}
#define PCL_INSTANTIATE_MinCutSegmentation(T) template class pcl::MinCutSegmentation<T>;
#endif // PCL_SEGMENTATION_MIN_CUT_SEGMENTATION_HPP_
pcl::MinCutSegmentation::mGraphPtr
shared_ptr< mGraph > mGraphPtr
Definition: min_cut_segmentation.h:104
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:473
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:402
pcl::MinCutSegmentation::ResidualCapacityMap
boost::property_map< mGraph, boost::edge_residual_capacity_t >::type ResidualCapacityMap
Definition: min_cut_segmentation.h:98
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::points
std::vector< PointT, Eigen::aligned_allocator< PointT > > points
The point data.
Definition: point_cloud.h:397
pcl::MinCutSegmentation::buildGraph
bool buildGraph()
This method simply builds the graph that will be used during the segmentation.
Definition: min_cut_segmentation.hpp:307
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::MinCutSegmentation::getColoredCloud
pcl::PointCloud< pcl::PointXYZRGB >::Ptr getColoredCloud()
Returns the colored cloud.
Definition: min_cut_segmentation.hpp:573
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:88
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:84
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:432
pcl::PointCloud< pcl::PointXYZRGB >
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:623
pcl::MinCutSegmentation::getGraph
mGraphPtr getGraph() const
Returns the graph that was build for finding the minimum cut.
Definition: min_cut_segmentation.hpp:300
pcl::MinCutSegmentation::VertexIterator
boost::graph_traits< mGraph >::vertex_iterator VertexIterator
Definition: min_cut_segmentation.h:96
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:458
pcl::PointCloud::width
std::uint32_t width
The point cloud width (if organized as an image-structure).
Definition: point_cloud.h:400
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:293
pcl::MinCutSegmentation::KdTreePtr
typename KdTree::Ptr KdTreePtr
Definition: min_cut_segmentation.h:63
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:221
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:372
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::PointIndices::indices
std::vector< int > indices
Definition: PointIndices.h:19
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:405
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:12
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:209
pcl::PointCloud::Ptr
shared_ptr< PointCloud< PointT > > Ptr
Definition: point_cloud.h:415
pcl::MinCutSegmentation::CapacityMap
boost::property_map< mGraph, boost::edge_capacity_t >::type CapacityMap
Definition: min_cut_segmentation.h:86
pcl::MinCutSegmentation::OutEdgeIterator
boost::graph_traits< mGraph >::out_edge_iterator OutEdgeIterator
Definition: min_cut_segmentation.h:94
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:202
pcl::MinCutSegmentation::recalculateBinaryPotentials
bool recalculateBinaryPotentials()
This method recalculates binary potentials(smooth cost) if some changes were made,...
Definition: min_cut_segmentation.hpp:498
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:545
pcl::MinCutSegmentation::EdgeDescriptor
boost::graph_traits< mGraph >::edge_descriptor EdgeDescriptor
Definition: min_cut_segmentation.h:92
pcl::MinCutSegmentation::VertexDescriptor
Traits::vertex_descriptor VertexDescriptor
Definition: min_cut_segmentation.h:90