40 #ifndef PCL_SEGMENTATION_GRABCUT
41 #define PCL_SEGMENTATION_GRABCUT
43 #include <pcl/point_cloud.h>
44 #include <pcl/pcl_base.h>
45 #include <pcl/point_types.h>
46 #include <pcl/segmentation/boost.h>
47 #include <pcl/search/search.h>
51 namespace segmentation
95 addEdge (
int u,
int v,
double cap_uv,
double cap_vu = 0.0);
115 typedef std::pair<capacitated_edge::iterator, capacitated_edge::iterator>
edge_pair;
127 augmentPath (
const std::pair<int, int>& path, std::deque<int>& orphans);
138 isActive (
int u)
const {
return ((u == active_head_) || (active_list_[u].first != TERMINAL)); }
154 std::vector<unsigned char>
cut_;
158 static const int TERMINAL = -1;
160 std::vector<std::pair<int, edge_pair> > parents_;
162 std::vector<std::pair<int, int> > active_list_;
163 int active_head_, active_tail_;
170 Color (
float _r,
float _g,
float _b) :
r(_r),
g(_g),
b(_b) {}
173 template<
typename Po
intT>
176 r =
static_cast<float> (p.r);
177 g =
static_cast<float> (p.g);
178 b =
static_cast<float> (p.b);
181 template<
typename Po
intT>
185 p.r =
static_cast<uint32_t
> (
r);
186 p.g =
static_cast<uint32_t
> (
g);
187 p.b =
static_cast<uint32_t
> (
b);
230 GMM () : gaussians_ (0) {}
232 GMM (std::size_t
K) : gaussians_ (K) {}
237 getK ()
const {
return gaussians_.size (); }
240 resize (std::size_t
K) { gaussians_.resize (K); }
246 operator[] (std::size_t pos)
const {
return (gaussians_[pos]); }
256 std::vector<Gaussian> gaussians_;
264 : sum_ (Eigen::Vector3f::Zero ())
265 , accumulator_ (Eigen::Matrix3f::Zero ())
275 fit (
Gaussian& g, std::size_t total_count,
bool compute_eigens =
false)
const;
288 Eigen::Vector3f sum_;
290 Eigen::Matrix3f accumulator_;
300 const std::vector<int>& indices,
301 const std::vector<SegmentationValue> &hardSegmentation,
302 std::vector<std::size_t> &components,
303 GMM &background_GMM, GMM &foreground_GMM);
307 const std::vector<int>& indices,
308 const std::vector<SegmentationValue>& hard_segmentation,
309 std::vector<std::size_t>& components,
310 GMM& background_GMM, GMM& foreground_GMM);
322 template <
typename Po
intT>
399 extract (std::vector<pcl::PointIndices>& clusters);
431 computeNLink (uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2);
475 std::vector<segmentation::grabcut::TrimapValue>
trimap_;
489 #include <pcl/segmentation/impl/grabcut.hpp>
Eigen::Matrix3f inverse
inverse of the covariance matrix
segmentation::grabcut::GMM background_GMM_
void setLambda(float lambda)
Set lambda parameter to user given value.
void learnGMMs(const Image &image, const std::vector< int > &indices, const std::vector< SegmentationValue > &hard_segmentation, std::vector< std::size_t > &components, GMM &background_GMM, GMM &foreground_GMM)
Iteratively learn GMMs using GrabCut updating algorithm.
segmentation::grabcut::Image::Ptr image_
Converted input.
void setInputCloud(const PointCloudConstPtr &cloud)
Provide a pointer to the input dataset.
void computeBeta()
Update hard segmentation after running GraphCut,.
void computeL()
Compute L parameter from given lambda.
KdTreePtr getSearchMethod()
Get a pointer to the search method used.
bool isActiveSetEmpty() const
Color(const pcl::RGB &color)
float computeNLink(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2)
Compute NLinks at a specific rectangular location.
double flow_value_
current flow value (includes constant)
bool isActive(int u) const
active if head or previous node is not the terminal
std::vector< segmentation::grabcut::SegmentationValue > hard_segmentation_
void markActive(int u)
mark vertex as active
PointCloud::Ptr PointCloudPtr
virtual void refine()
Run Grabcut refinement on the hard segmentation.
virtual ~GrabCut()
Desctructor.
PointCloud represents the base class in PCL for storing collections of 3D points. ...
std::vector< double > target_edges_
edges entering the target
pcl::PointCloud< Color > Image
An Image is a point cloud of Color.
std::vector< vertex_descriptor > graph_nodes_
Graph nodes.
Helper class that fits a single Gaussian to color samples.
pcl::segmentation::grabcut::BoykovKolmogorov::vertex_descriptor vertex_descriptor
void addEdge(vertex_descriptor v1, vertex_descriptor v2, float capacity, float rev_capacity)
Add an edge to the graph, graph must be oriented so we add the edge and its reverse.
std::vector< int > indices
PCLBase< PointT >::PointCloudPtr PointCloudPtr
PCLBase< PointT >::PointCloudConstPtr PointCloudConstPtr
std::vector< NLinks > n_links_
Precomputed N-link weights.
bool inSourceTree(int u) const
return true if u is in the s-set after calling solve.
float probabilityDensity(const Color &c)
uint32_t height_
image height
void augmentPath(const std::pair< int, int > &path, std::deque< int > &orphans)
augment the path found by expandTrees; return orphaned subtrees
std::vector< unsigned char > cut_
identifies which side of the cut a node falls
Eigen::Vector3f eigenvector
eigenvector corresponding to the heighest eigenvector
GaussianFitter(float epsilon=0.0001)
void addConstant(double c)
add constant flow to graph
pcl::search::Search< PointT >::Ptr KdTreePtr
float beta_
beta = 1/2 * average of the squared color distances between all pairs of 8-neighboring pixels...
boost implementation of Boykov and Kolmogorov's maxflow algorithm doesn't support negative flows whic...
void resize(std::size_t K)
resize gaussians
int getNumberOfNeighbours() const
Returns the number of neighbours to find.
bool inSinkTree(int u) const
return true if u is in the t-set after calling solve
TrimapValue
User supplied Trimap values.
void fit(Gaussian &g, std::size_t total_count, bool compute_eigens=false) const
Build the gaussian out of all the added color samples.
float pi
weighting of this gaussian in the GMM.
std::vector< float > soft_segmentation_
GMM(std::size_t K)
Initialize GMM with ddesired number of gaussians.
float determinant
determinant of the covariance matrix
std::vector< float > dists
BoykovKolmogorov(std::size_t max_nodes=0)
construct a maxflow/mincut problem with estimated max_nodes
void preAugmentPaths()
pre-augment s-u-t and s-u-v-t paths
void setSearchMethod(const KdTreePtr &tree)
Provide a pointer to the search object.
KdTreePtr tree_
Pointer to the spatial search object.
std::vector< segmentation::grabcut::TrimapValue > trimap_
float lambda_
lambda = 50. This value was suggested the GrabCut paper.
void extract(std::vector< pcl::PointIndices > &clusters)
This method launches the segmentation algorithm and returns the clusters that were obtained during th...
void initGraph()
Build the graph for GraphCut.
void setK(uint32_t K)
Set K parameter to user given value.
GrabCut(uint32_t K=5, float lambda=50.f)
Constructor.
std::vector< double > source_edges_
edges leaving the source
double operator()(int u, int v) const
returns the residual capacity for an edge (use -1 for terminal (-1,-1) is the current flow ...
A structure representing RGB color information.
std::map< int, double > capacitated_edge
capacitated edge
boost::shared_ptr< pcl::search::Search< PointT > > Ptr
Color mu
mean of the gaussian
boost::shared_ptr< PointCloud< PointT > > Ptr
double edge_capacity_type
boost::shared_ptr< ::pcl::PointIndices const > PointIndicesConstPtr
void setTerminalWeights(vertex_descriptor v, float source_capacity, float sink_capacity)
Set the weights of SOURCE –> v and v –> SINK.
void addEdge(int u, int v, double cap_uv, double cap_vu=0.0)
add edge from u to v and edge from v to u (requires cap_uv + cap_vu >= 0)
Color(float _r, float _g, float _b)
float colorDistance(const Color &c1, const Color &c2)
Compute squared distance between two colors.
Implementation of the GrabCut segmentation in "GrabCut — Interactive Foreground Extraction using Iter...
uint32_t K_
Number of GMM components.
SegmentationValue
Grabcut derived hard segementation values.
pcl::search::Search< PointT > KdTree
bool isSource(vertex_descriptor v)
PointCloud::ConstPtr PointCloudConstPtr
void clearActive()
clear active set
std::vector< float > weights
int updateHardSegmentation()
void markInactive(int u)
mark vertex as inactive
void adoptOrphans(std::deque< int > &orphans)
adopt orphaned subtrees
int nb_neighbours_
Number of neighbours.
pcl::segmentation::grabcut::BoykovKolmogorov graph_
Graph for Graphcut.
double solve()
solve the max-flow problem and return the flow
void add(const Color &c)
Add a color sample.
Structure to save RGB colors into floats.
void reset()
reset all edge capacities to zero (but don't free the graph)
int addNodes(std::size_t n=1)
add nodes to the graph (returns the id of the first node added)
void buildGMMs(const Image &image, const std::vector< int > &indices, const std::vector< SegmentationValue > &hardSegmentation, std::vector< std::size_t > &components, GMM &background_GMM, GMM &foreground_GMM)
Build the initial GMMs using the Orchard and Bouman color clustering algorithm.
uint32_t width_
image width
segmentation::grabcut::GMM foreground_GMM_
bool initialized_
is segmentation initialized
std::pair< int, int > expandTrees()
expand trees until a path is found (or no path (-1, -1))
void setBackgroundPointsIndices(int x1, int y1, int x2, int y2)
Set background indices, foreground indices = indices \ background indices.
virtual ~BoykovKolmogorov()
destructor
void setTrimap(const PointIndicesConstPtr &indices, segmentation::grabcut::TrimapValue t)
Edit Trimap.
float eigenvalue
heighest eigenvalue of covariance matrix
void computeNLinks()
Compute NLinks.
boost::shared_ptr< PointIndices const > PointIndicesConstPtr
void initializeTrees()
initialize trees from source and target
void setEpsilon(float epsilon)
set epsilon which will be added to the covariance matrix diagonal which avoids singular covariance ma...
GMM()
Initialize GMM with ddesired number of gaussians.
std::vector< std::size_t > GMM_component_
Eigen::Matrix3f covariance
covariance matrix of the gaussian
void setBackgroundPoints(const PointCloudConstPtr &background_points)
Set background points, foreground points = points \ background points.
A point structure representing Euclidean xyz coordinates, and the RGB color.
void setNumberOfNeighbours(int nb_neighbours)
Allows to set the number of neighbours to find.
float L_
L = a large value to force a pixel to be foreground or background.
Gaussian & operator[](std::size_t pos)
std::pair< capacitated_edge::iterator, capacitated_edge::iterator > edge_pair
edge pair
void addSourceEdge(int u, double cap)
add edge from s to nodeId
virtual void fitGMMs()
Fit Gaussian Multi Models.
void addTargetEdge(int u, double cap)
add edge from nodeId to t
void clear()
clear the graph and internal datastructures
size_t numNodes() const
get number of nodes in the graph
std::vector< capacitated_edge > nodes_
nodes and their outgoing internal edges