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>
TrimapValue
User supplied Trimap values.
virtual ~GrabCut()
Desctructor.
Gaussian & operator[](std::size_t pos)
std::vector< float > soft_segmentation_
std::vector< vertex_descriptor > graph_nodes_
Graph nodes.
void computeNLinks()
Compute NLinks.
bool isActiveSetEmpty() const
PointCloud::ConstPtr PointCloudConstPtr
segmentation::grabcut::GMM foreground_GMM_
double flow_value_
current flow value (includes constant)
bool isActive(int u) const
active if head or previous node is not the terminal
void setEpsilon(float epsilon)
set epsilon which will be added to the covariance matrix diagonal which avoids singular covariance ma...
void markActive(int u)
mark vertex as active
boost::shared_ptr< pcl::search::Search< PointT > > Ptr
std::vector< double > target_edges_
edges entering the target
boost::shared_ptr< ::pcl::PointIndices const > PointIndicesConstPtr
std::vector< int > indices
std::vector< std::size_t > GMM_component_
void setLambda(float lambda)
Set lambda parameter to user given value.
bool inSourceTree(int u) const
return true if u is in the s-set after calling solve.
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.
float determinant
determinant of the covariance matrix
Color(const pcl::RGB &color)
void augmentPath(const std::pair< int, int > &path, std::deque< int > &orphans)
augment the path found by expandTrees; return orphaned subtrees
void setInputCloud(const PointCloudConstPtr &cloud)
Provide a pointer to the input dataset.
std::vector< unsigned char > cut_
identifies which side of the cut a node falls
boost::shared_ptr< PointIndices const > PointIndicesConstPtr
Eigen::Matrix3f inverse
inverse of the covariance matrix
boost::shared_ptr< PointCloud< PointT > > Ptr
void addConstant(double c)
add constant flow to graph
pcl::segmentation::grabcut::BoykovKolmogorov::vertex_descriptor vertex_descriptor
virtual void fitGMMs()
Fit Gaussian Multi Models.
void add(const Color &c)
Add a color sample.
pcl::PointCloud< Color > Image
An Image is a point cloud of Color.
boost implementation of Boykov and Kolmogorov's maxflow algorithm doesn't support negative flows whic...
std::vector< segmentation::grabcut::TrimapValue > trimap_
void resize(std::size_t K)
resize gaussians
bool inSinkTree(int u) const
return true if u is in the t-set after calling solve
void computeL()
Compute L parameter from given lambda.
void setTrimap(const PointIndicesConstPtr &indices, segmentation::grabcut::TrimapValue t)
Edit Trimap.
Helper class that fits a single Gaussian to color samples.
BoykovKolmogorov(std::size_t max_nodes=0)
construct a maxflow/mincut problem with estimated max_nodes
PointCloud::Ptr PointCloudPtr
Eigen::Matrix3f covariance
covariance matrix of the gaussian
void preAugmentPaths()
pre-augment s-u-t and s-u-v-t paths
uint32_t K_
Number of GMM components.
std::vector< float > weights
float eigenvalue
heighest eigenvalue of covariance matrix
pcl::search::Search< PointT > KdTree
Eigen::Vector3f eigenvector
eigenvector corresponding to the heighest eigenvector
GrabCut(uint32_t K=5, float lambda=50.f)
Constructor.
Color(float _r, float _g, float _b)
int updateHardSegmentation()
int getNumberOfNeighbours() const
Returns the number of neighbours to find.
std::vector< NLinks > n_links_
Precomputed N-link weights.
float pi
weighting of this gaussian in the GMM.
uint32_t height_
image height
KdTreePtr tree_
Pointer to the spatial search object.
float beta_
beta = 1/2 * average of the squared color distances between all pairs of 8-neighboring pixels...
std::vector< double > source_edges_
edges leaving the source
bool initialized_
is segmentation initialized
float lambda_
lambda = 50. This value was suggested the GrabCut paper.
double operator()(int u, int v) const
returns the residual capacity for an edge (use -1 for terminal (-1,-1) is the current flow ...
int nb_neighbours_
Number of neighbours.
std::map< int, double > capacitated_edge
capacitated edge
bool isSource(vertex_descriptor v)
double edge_capacity_type
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)
std::vector< float > dists
void extract(std::vector< pcl::PointIndices > &clusters)
This method launches the segmentation algorithm and returns the clusters that were obtained during th...
Color mu
mean of the gaussian
void fit(Gaussian &g, std::size_t total_count, bool compute_eigens=false) const
Build the gaussian out of all the added color samples.
void setSearchMethod(const KdTreePtr &tree)
Provide a pointer to the search object.
float L_
L = a large value to force a pixel to be foreground or background.
void clearActive()
clear active set
Implementation of the GrabCut segmentation in "GrabCut — Interactive Foreground Extraction using Iter...
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.
void setTerminalWeights(vertex_descriptor v, float source_capacity, float sink_capacity)
Set the weights of SOURCE –> v and v –> SINK.
PCLBase< PointT >::PointCloudConstPtr PointCloudConstPtr
void markInactive(int u)
mark vertex as inactive
void adoptOrphans(std::deque< int > &orphans)
adopt orphaned subtrees
float probabilityDensity(const Color &c)
segmentation::grabcut::GMM background_GMM_
segmentation::grabcut::Image::Ptr image_
Converted input.
void setNumberOfNeighbours(int nb_neighbours)
Allows to set the number of neighbours to find.
void initGraph()
Build the graph for GraphCut.
double solve()
solve the max-flow problem and return the flow
A point structure representing Euclidean xyz coordinates, and the RGB color.
void reset()
reset all edge capacities to zero (but don't free the graph)
SegmentationValue
Grabcut derived hard segementation values.
int addNodes(std::size_t n=1)
add nodes to the graph (returns the id of the first node added)
float computeNLink(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2)
Compute NLinks at a specific rectangular location.
std::pair< int, int > expandTrees()
expand trees until a path is found (or no path (-1, -1))
void setBackgroundPoints(const PointCloudConstPtr &background_points)
Set background points, foreground points = points \ background points.
virtual ~BoykovKolmogorov()
destructor
PointCloud represents the base class in PCL for storing collections of 3D points. ...
void initializeTrees()
initialize trees from source and target
PCLBase< PointT >::PointCloudPtr PointCloudPtr
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.
std::vector< segmentation::grabcut::SegmentationValue > hard_segmentation_
GMM()
Initialize GMM with ddesired number of gaussians.
void setBackgroundPointsIndices(int x1, int y1, int x2, int y2)
Set background indices, foreground indices = indices \ background indices.
virtual void refine()
Run Grabcut refinement on the hard segmentation.
A structure representing RGB color information.
GaussianFitter(float epsilon=0.0001)
pcl::segmentation::grabcut::BoykovKolmogorov graph_
Graph for Graphcut.
void computeBeta()
Update hard segmentation after running GraphCut,.
void setK(uint32_t K)
Set K parameter to user given value.
std::pair< capacitated_edge::iterator, capacitated_edge::iterator > edge_pair
edge pair
GMM(std::size_t K)
Initialize GMM with ddesired number of gaussians.
void addSourceEdge(int u, double cap)
add edge from s to nodeId
float colorDistance(const Color &c1, const Color &c2)
Compute squared distance between two colors.
KdTreePtr getSearchMethod()
Get a pointer to the search method used.
pcl::search::Search< PointT >::Ptr KdTreePtr
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
uint32_t width_
image width
std::vector< capacitated_edge > nodes_
nodes and their outgoing internal edges
Structure to save RGB colors into floats.