38 #ifndef PCL_SEGMENTATION_IMPL_RANDOM_WALKER_HPP
39 #define PCL_SEGMENTATION_IMPL_RANDOM_WALKER_HPP
41 #include <boost/bimap.hpp>
43 #include <Eigen/Sparse>
48 namespace segmentation
64 template <
class Graph,
class EdgeWeightMap,
class VertexColorMap>
70 using Color =
typename boost::property_traits<VertexColorMap>::value_type;
71 using Weight =
typename boost::property_traits<EdgeWeightMap>::value_type;
78 using VertexIndexMap =
typename boost::property_map<Graph, boost::vertex_index_t>::type;
81 using Matrix = Eigen::Matrix<Weight, Eigen::Dynamic, Eigen::Dynamic>;
82 using Vector = Eigen::Matrix<Weight, Eigen::Dynamic, 1>;
84 RandomWalker (Graph& g, EdgeWeightMap weights, VertexColorMap colors)
105 using namespace boost;
107 for (tie (ei, e_end) = edges (
g_); ei != e_end; ++ei)
118 using namespace boost;
120 using T = Eigen::Triplet<float>;
121 using Triplets = std::vector<T>;
126 for (tie (vi, v_end) = vertices (
g_); vi != v_end; ++vi)
140 L_triplets.push_back (T (current_row, current_row,
degree_map_[*vi]));
143 for (tie (ei, e_end) = out_edges (*vi,
g_); ei != e_end; ++ei)
161 B_triplets.push_back (T (current_row, column, w));
169 L_triplets.push_back (T (current_row,
L_vertex_bimap.right.at (tgt), -w));
177 L.resize (num_equations, num_equations);
178 B.resize (num_equations, num_colors);
179 if (!L_triplets.empty ())
180 L.setFromTriplets(L_triplets.begin(), L_triplets.end());
181 if (!B_triplets.empty ())
182 B.setFromTriplets(B_triplets.begin(), B_triplets.end());
187 X.resize (
L.rows (),
B.cols ());
190 if (
L.rows () == 0 ||
B.cols () == 0)
193 Eigen::SimplicialCholesky<SparseMatrix, Eigen::Lower> cg;
195 bool succeeded =
true;
196 for (Eigen::Index i = 0; i <
B.cols (); ++i)
199 X.col (i) = cg.solve (b);
200 if (cg.info () != Eigen::Success)
211 using namespace boost;
213 for (Eigen::Index i = 0; i <
X.rows (); ++i)
215 std::size_t max_column;
216 X.row (i).maxCoeff (&max_column);
226 using namespace boost;
227 potentials = Matrix::Zero (num_vertices (
g_),
colors_.size ());
229 for (Eigen::Index i = 0; i <
X.rows (); ++i)
232 for (std::size_t i = 0; i <
seeds_.size (); ++i)
239 color_to_column_map.clear ();
240 for (Eigen::Index i = 0; i < potentials.cols (); ++i)
244 template <
typename T>
static inline std::size_t
247 if (bimap.right.count (value) != 0)
249 return bimap.right.at (value);
251 std::size_t s = bimap.size ();
252 bimap.insert (
typename boost::bimap<std::size_t, T>::value_type (s, value));
279 template <
class Graph>
bool
283 boost::get (boost::edge_weight, graph),
284 boost::get (boost::vertex_color, graph));
287 template <
class Graph,
class EdgeWeightMap,
class VertexColorMap>
bool
289 EdgeWeightMap weights,
290 VertexColorMap colors)
292 using namespace boost;
294 using EdgeDescriptor =
typename graph_traits<Graph>::edge_descriptor;
297 BOOST_CONCEPT_ASSERT ((VertexListGraphConcept<Graph>));
298 BOOST_CONCEPT_ASSERT ((EdgeListGraphConcept<Graph>));
299 BOOST_CONCEPT_ASSERT ((IncidenceGraphConcept<Graph>));
300 BOOST_CONCEPT_ASSERT ((ReadablePropertyMapConcept<EdgeWeightMap, EdgeDescriptor>));
301 BOOST_CONCEPT_ASSERT ((ReadWritePropertyMapConcept<VertexColorMap, VertexDescriptor>));
309 rw (graph, weights, colors);
310 return rw.segment ();
313 template <
class Graph,
class EdgeWeightMap,
class VertexColorMap>
bool
315 EdgeWeightMap weights,
316 VertexColorMap colors,
317 Eigen::Matrix<
typename boost::property_traits<EdgeWeightMap>::value_type, Eigen::Dynamic, Eigen::Dynamic>& potentials,
318 std::map<
typename boost::property_traits<VertexColorMap>::value_type, std::size_t>& colors_to_columns_map)
320 using namespace boost;
322 using EdgeDescriptor =
typename graph_traits<Graph>::edge_descriptor;
325 BOOST_CONCEPT_ASSERT ((VertexListGraphConcept<Graph>));
326 BOOST_CONCEPT_ASSERT ((EdgeListGraphConcept<Graph>));
327 BOOST_CONCEPT_ASSERT ((IncidenceGraphConcept<Graph>));
328 BOOST_CONCEPT_ASSERT ((ReadablePropertyMapConcept<EdgeWeightMap, EdgeDescriptor>));
329 BOOST_CONCEPT_ASSERT ((ReadWritePropertyMapConcept<VertexColorMap, VertexDescriptor>));
337 rw (graph, weights, colors);
338 bool result = rw.segment ();
339 rw.getPotentials (potentials, colors_to_columns_map);
Multilabel graph segmentation using random walks.
void computeVertexDegrees()
typename boost::property_map< Graph, boost::vertex_index_t >::type VertexIndexMap
boost::bimap< std::size_t, VertexDescriptor > L_vertex_bimap
typename boost::property_traits< VertexColorMap >::value_type Color
RandomWalker(Graph &g, EdgeWeightMap weights, VertexColorMap colors)
void getPotentials(Matrix &potentials, std::map< Color, std::size_t > &color_to_column_map)
std::vector< VertexDescriptor > seeds_
typename GraphTraits::out_edge_iterator OutEdgeIterator
Eigen::Matrix< Weight, Eigen::Dynamic, Eigen::Dynamic > Matrix
boost::graph_traits< Graph > GraphTraits
typename GraphTraits::edge_descriptor EdgeDescriptor
VertexIndexMap index_map_
typename boost::property_traits< EdgeWeightMap >::value_type Weight
VertexColorMap color_map_
typename GraphTraits::vertex_descriptor VertexDescriptor
static std::size_t insertInBimap(boost::bimap< std::size_t, T > &bimap, T value)
typename GraphTraits::edge_iterator EdgeIterator
std::vector< Weight > degree_storage_
EdgeWeightMap weight_map_
std::set< Color > colors_
VertexDegreeMap degree_map_
boost::iterator_property_map< typename std::vector< Weight >::iterator, VertexIndexMap > VertexDegreeMap
boost::bimap< std::size_t, Color > B_color_bimap
Eigen::Matrix< Weight, Eigen::Dynamic, 1 > Vector
Eigen::SparseMatrix< Weight > SparseMatrix
typename GraphTraits::vertex_iterator VertexIterator
bool randomWalker(Graph &graph)
Multilabel graph segmentation using random walks.