mirror of https://github.com/CGAL/cgal
Make Boost Alpha Expansion use BGL API
This commit is contained in:
parent
0dd30b1a68
commit
5ca8fcf47b
|
|
@ -75,6 +75,84 @@ namespace CGAL
|
||||||
namespace internal
|
namespace internal
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct Alpha_expansion_old_API_wrapper_graph
|
||||||
|
{
|
||||||
|
typedef std::size_t vertex_descriptor;
|
||||||
|
typedef std::size_t edge_descriptor;
|
||||||
|
typedef boost::directed_tag directed_category;
|
||||||
|
typedef boost::disallow_parallel_edge_tag edge_parallel_category;
|
||||||
|
typedef boost::edge_list_graph_tag traversal_category;
|
||||||
|
|
||||||
|
typedef boost::counting_iterator<std::size_t> counting_iterator;
|
||||||
|
typedef CGAL::Iterator_range<counting_iterator> counting_range;
|
||||||
|
|
||||||
|
typedef CGAL::Identity_property_map<std::size_t> Vertex_index_map;
|
||||||
|
typedef CGAL::Pointer_property_map<std::size_t>::type Vertex_label_map;
|
||||||
|
|
||||||
|
struct Vertex_label_probability_map
|
||||||
|
{
|
||||||
|
typedef std::size_t key_type;
|
||||||
|
typedef std::vector<double> value_type;
|
||||||
|
typedef value_type reference;
|
||||||
|
typedef boost::readable_property_map_tag category;
|
||||||
|
|
||||||
|
const std::vector<std::vector<double> >* probability_matrix;
|
||||||
|
|
||||||
|
Vertex_label_probability_map (const std::vector<std::vector<double> >* probability_matrix)
|
||||||
|
: probability_matrix (probability_matrix)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
friend reference get (const Vertex_label_probability_map& pmap, key_type idx)
|
||||||
|
{
|
||||||
|
std::vector<double> out;
|
||||||
|
out.reserve (pmap.probability_matrix->size());
|
||||||
|
for (std::size_t i = 0; i < pmap.probability_matrix->size(); ++ i)
|
||||||
|
out.push_back ((*pmap.probability_matrix)[i][idx]);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef CGAL::Pointer_property_map<double>::const_type Edge_weight_map;
|
||||||
|
|
||||||
|
const std::vector<std::pair<std::size_t, std::size_t> >& edges;
|
||||||
|
const std::vector<double>& edge_weights;
|
||||||
|
const std::vector<std::vector<double> >& probability_matrix;
|
||||||
|
std::vector<std::size_t>& labels;
|
||||||
|
|
||||||
|
Alpha_expansion_old_API_wrapper_graph (const std::vector<std::pair<std::size_t, std::size_t> >& edges,
|
||||||
|
const std::vector<double>& edge_weights,
|
||||||
|
const std::vector<std::vector<double> >& probability_matrix,
|
||||||
|
std::vector<std::size_t>& labels)
|
||||||
|
: edges (edges), edge_weights (edge_weights), probability_matrix (probability_matrix), labels (labels)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
friend counting_range vertices (const Alpha_expansion_old_API_wrapper_graph& graph)
|
||||||
|
{
|
||||||
|
return CGAL::make_range (boost::counting_iterator<std::size_t>(0),
|
||||||
|
boost::counting_iterator<std::size_t>(graph.labels.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend std::size_t num_vertices (const Alpha_expansion_old_API_wrapper_graph& graph) { return graph.labels.size(); }
|
||||||
|
|
||||||
|
friend counting_range edges (const Alpha_expansion_old_API_wrapper_graph& graph)
|
||||||
|
{
|
||||||
|
return CGAL::make_range (boost::counting_iterator<std::size_t>(0),
|
||||||
|
boost::counting_iterator<std::size_t>(graph.edges.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend vertex_descriptor source (edge_descriptor ed, const Alpha_expansion_old_API_wrapper_graph& graph)
|
||||||
|
{ return graph.edges[ed].first; }
|
||||||
|
friend vertex_descriptor target (edge_descriptor ed, const Alpha_expansion_old_API_wrapper_graph& graph)
|
||||||
|
{ return graph.edges[ed].second; }
|
||||||
|
|
||||||
|
Vertex_index_map vertex_index_map() const { return Vertex_index_map(); }
|
||||||
|
Vertex_label_map vertex_label_map() { return CGAL::make_property_map(labels); }
|
||||||
|
Vertex_label_probability_map vertex_label_probability_map() const
|
||||||
|
{ return Vertex_label_probability_map(&probability_matrix); }
|
||||||
|
Edge_weight_map edge_weight_map() const { return CGAL::make_property_map(edge_weights); }
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Comments about performance:
|
// Comments about performance:
|
||||||
//
|
//
|
||||||
|
|
@ -182,6 +260,8 @@ private:
|
||||||
return boost::make_tuple(v1_v2, v2_v1);
|
return boost::make_tuple(v1_v2, v2_v1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Applies alpha-expansion graph-cut for energy minimization.
|
* Applies alpha-expansion graph-cut for energy minimization.
|
||||||
|
|
@ -196,7 +276,33 @@ public:
|
||||||
edges,
|
edges,
|
||||||
const std::vector<double>& edge_weights,
|
const std::vector<double>& edge_weights,
|
||||||
const std::vector<std::vector<double> >& probability_matrix,
|
const std::vector<std::vector<double> >& probability_matrix,
|
||||||
std::vector<std::size_t>& labels) const {
|
std::vector<std::size_t>& labels) const
|
||||||
|
{
|
||||||
|
Alpha_expansion_old_API_wrapper_graph graph (edges, edge_weights, probability_matrix, labels);
|
||||||
|
|
||||||
|
return (*this)(graph,
|
||||||
|
graph.edge_weight_map(),
|
||||||
|
graph.vertex_index_map(),
|
||||||
|
graph.vertex_label_map(),
|
||||||
|
graph.vertex_label_probability_map());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename InputGraph,
|
||||||
|
typename Edge_weight_map,
|
||||||
|
typename Vertex_index_map,
|
||||||
|
typename Vertex_label_map,
|
||||||
|
typename Vertex_label_probability_map>
|
||||||
|
double operator()(const InputGraph& input_graph,
|
||||||
|
Edge_weight_map edge_weight_map,
|
||||||
|
Vertex_index_map vertex_index_map,
|
||||||
|
Vertex_label_map vertex_label_map,
|
||||||
|
Vertex_label_probability_map vertex_label_probability_map) const
|
||||||
|
{
|
||||||
|
typedef boost::graph_traits<InputGraph> GT;
|
||||||
|
typedef typename GT::edge_descriptor input_edge_descriptor;
|
||||||
|
typedef typename GT::vertex_descriptor input_vertex_descriptor;
|
||||||
|
|
||||||
|
// TODO: check this hardcoded parameter
|
||||||
const double tolerance = 1e-10;
|
const double tolerance = 1e-10;
|
||||||
|
|
||||||
double min_cut = (std::numeric_limits<double>::max)();
|
double min_cut = (std::numeric_limits<double>::max)();
|
||||||
|
|
@ -207,18 +313,18 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::vector<Vertex_descriptor> inserted_vertices;
|
std::vector<Vertex_descriptor> inserted_vertices;
|
||||||
inserted_vertices.resize(labels.size());
|
inserted_vertices.resize(num_vertices (input_graph));
|
||||||
|
|
||||||
|
std::size_t number_of_labels = get(vertex_label_probability_map, *std::begin(vertices(input_graph))).size();
|
||||||
|
|
||||||
Graph graph;
|
Graph graph;
|
||||||
|
|
||||||
bool success;
|
bool success;
|
||||||
do {
|
do {
|
||||||
success = false;
|
success = false;
|
||||||
std::size_t alpha = 0;
|
|
||||||
|
|
||||||
for(std::vector<std::vector<double> >::const_iterator it =
|
for (std::size_t alpha = 0; alpha < number_of_labels; ++ alpha)
|
||||||
probability_matrix.begin();
|
{
|
||||||
it != probability_matrix.end(); ++it, ++alpha) {
|
|
||||||
graph.clear();
|
graph.clear();
|
||||||
|
|
||||||
Vertex_descriptor cluster_source = boost::add_vertex(graph);
|
Vertex_descriptor cluster_source = boost::add_vertex(graph);
|
||||||
|
|
@ -230,16 +336,18 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// For E-Data
|
// For E-Data
|
||||||
// add every facet as a vertex to the graph, put edges to source & sink vertices
|
// add every input vertex as a vertex to the graph, put edges to source & sink vertices
|
||||||
for(std::size_t vertex_i = 0; vertex_i < labels.size(); ++vertex_i) {
|
for (input_vertex_descriptor vd : vertices(input_graph))
|
||||||
|
{
|
||||||
|
std::size_t vertex_i = get(vertex_index_map, vd);
|
||||||
Vertex_descriptor new_vertex = boost::add_vertex(graph);
|
Vertex_descriptor new_vertex = boost::add_vertex(graph);
|
||||||
inserted_vertices[vertex_i] = new_vertex;
|
inserted_vertices[vertex_i] = new_vertex;
|
||||||
double source_weight = probability_matrix[alpha][vertex_i];
|
double source_weight = get(vertex_label_probability_map, vd)[alpha];
|
||||||
// since it is expansion move, current alpha labeled vertices will be assigned to alpha again,
|
// since it is expansion move, current alpha labeled vertices will be assigned to alpha again,
|
||||||
// making sink_weight 'infinity' guarantee this.
|
// making sink_weight 'infinity' guarantee this.
|
||||||
double sink_weight = (labels[vertex_i] == alpha) ?
|
double sink_weight = (get(vertex_label_map, vd) == alpha ?
|
||||||
(std::numeric_limits<double>::max)()
|
(std::numeric_limits<double>::max)()
|
||||||
: probability_matrix[labels[vertex_i]][vertex_i];
|
: get(vertex_label_probability_map, vd)[get(vertex_label_map, vd)]);
|
||||||
|
|
||||||
add_edge_and_reverse(cluster_source, new_vertex, source_weight, 0.0, graph);
|
add_edge_and_reverse(cluster_source, new_vertex, source_weight, 0.0, graph);
|
||||||
add_edge_and_reverse(new_vertex, cluster_sink, sink_weight, 0.0, graph);
|
add_edge_and_reverse(new_vertex, cluster_sink, sink_weight, 0.0, graph);
|
||||||
|
|
@ -251,25 +359,32 @@ public:
|
||||||
|
|
||||||
// For E-Smooth
|
// For E-Smooth
|
||||||
// add edge between every vertex,
|
// add edge between every vertex,
|
||||||
std::vector<double>::const_iterator weight_it = edge_weights.begin();
|
for (input_edge_descriptor ed : edges(input_graph))
|
||||||
for(std::vector<std::pair<std::size_t, std::size_t> >::const_iterator edge_it =
|
{
|
||||||
edges.begin(); edge_it != edges.end();
|
input_vertex_descriptor vd1 = source(ed, input_graph);
|
||||||
++edge_it, ++weight_it) {
|
input_vertex_descriptor vd2 = target(ed, input_graph);
|
||||||
Vertex_descriptor v1 = inserted_vertices[edge_it->first],
|
std::size_t idx1 = get (vertex_index_map, vd1);
|
||||||
v2 = inserted_vertices[edge_it->second];
|
std::size_t idx2 = get (vertex_index_map, vd2);
|
||||||
std::size_t label_1 = labels[edge_it->first], label_2 = labels[edge_it->second];
|
|
||||||
|
double weight = get (edge_weight_map, ed);
|
||||||
|
|
||||||
|
Vertex_descriptor v1 = inserted_vertices[idx1],
|
||||||
|
v2 = inserted_vertices[idx2];
|
||||||
|
|
||||||
|
std::size_t label_1 = get (vertex_label_map, vd1);
|
||||||
|
std::size_t label_2 = get (vertex_label_map, vd2);
|
||||||
if(label_1 == label_2) {
|
if(label_1 == label_2) {
|
||||||
if(label_1 != alpha) {
|
if(label_1 != alpha) {
|
||||||
add_edge_and_reverse(v1, v2, *weight_it, *weight_it, graph);
|
add_edge_and_reverse(v1, v2, weight, weight, graph);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Vertex_descriptor inbetween = boost::add_vertex(graph);
|
Vertex_descriptor inbetween = boost::add_vertex(graph);
|
||||||
|
|
||||||
double w1 = (label_1 == alpha) ? 0 : *weight_it;
|
double w1 = (label_1 == alpha) ? 0 : weight;
|
||||||
double w2 = (label_2 == alpha) ? 0 : *weight_it;
|
double w2 = (label_2 == alpha) ? 0 : weight;
|
||||||
add_edge_and_reverse(inbetween, v1, w1, w1, graph);
|
add_edge_and_reverse(inbetween, v1, w1, w1, graph);
|
||||||
add_edge_and_reverse(inbetween, v2, w2, w2, graph);
|
add_edge_and_reverse(inbetween, v2, w2, w2, graph);
|
||||||
add_edge_and_reverse(inbetween, cluster_sink, *weight_it, 0.0, graph);
|
add_edge_and_reverse(inbetween, cluster_sink, weight, 0.0, graph);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef CGAL_SEGMENTATION_BENCH_GRAPHCUT
|
#ifdef CGAL_SEGMENTATION_BENCH_GRAPHCUT
|
||||||
|
|
@ -302,12 +417,14 @@ public:
|
||||||
min_cut = flow;
|
min_cut = flow;
|
||||||
success = true;
|
success = true;
|
||||||
//update labeling
|
//update labeling
|
||||||
for(std::size_t vertex_i = 0; vertex_i < inserted_vertices.size(); ++vertex_i) {
|
for (input_vertex_descriptor vd : vertices (input_graph))
|
||||||
|
{
|
||||||
|
std::size_t vertex_i = get (vertex_index_map, vd);
|
||||||
boost::default_color_type color = boost::get(boost::vertex_color, graph,
|
boost::default_color_type color = boost::get(boost::vertex_color, graph,
|
||||||
inserted_vertices[vertex_i]);
|
inserted_vertices[vertex_i]);
|
||||||
if(labels[vertex_i] != alpha
|
if(get (vertex_label_map, vd) != alpha
|
||||||
&& color == ColorTraits::white()) { //new comers (expansion occurs)
|
&& color == ColorTraits::white()) { //new comers (expansion occurs)
|
||||||
labels[vertex_i] = alpha;
|
put (vertex_label_map, vd, alpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue