OpenGM  2.3.x
Discrete Graphical Model Library
minstcutboost.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_MINSTCUTBOOST_HXX
3 #define OPENGM_MINSTCUTBOOST_HXX
4 
5 #ifndef BOOST_DISABLE_ASSERTS
6 #define BOOST_DISABLE_ASSERTS
7 #define USED_BOOST_DISABLE_ASSERTS
8 #endif
9 
10 #include <queue>
11 #include <cassert>
12 
13 #include <boost/graph/graph_traits.hpp>
14 #include <boost/graph/one_bit_color_map.hpp>
15 #include <boost/property_map/property_map.hpp>
16 #include <boost/typeof/typeof.hpp>
17 
18 #include <boost/graph/adjacency_list.hpp>
19 #include <boost/graph/edmonds_karp_max_flow.hpp>
20 #include <boost/graph/push_relabel_max_flow.hpp>
21 #include <boost/graph/boykov_kolmogorov_max_flow.hpp>
22 
23 namespace opengm {
24 
27  };
28 
30  template<class NType, class VType, BoostMaxFlowAlgorithm mfalg>
31  class MinSTCutBoost {
32  public:
33  // Type-Definitions
34  typedef NType node_type;
35  typedef VType ValueType;
36  typedef boost::vecS OutEdgeList;
37  typedef boost::vecS VertexList;
38  typedef boost::adjacency_list_traits<OutEdgeList, VertexList, boost::directedS> graph_traits;
39  typedef graph_traits::edge_descriptor edge_descriptor;
40  typedef graph_traits::vertex_descriptor vertex_descriptor;
41 
43  struct Edge {
44  Edge() : capacity(ValueType()), residual(ValueType()), reverse(edge_descriptor())
45  {}
46  ValueType capacity;
47  ValueType residual;
48  edge_descriptor reverse;
49  };
51 
52  typedef boost::adjacency_list<OutEdgeList, VertexList, boost::directedS, size_t, Edge> graph_type;
53  typedef typename boost::graph_traits<graph_type>::edge_iterator edge_iterator;
54  typedef typename boost::graph_traits<graph_type>::out_edge_iterator out_edge_iterator;
55 
56  // Methods
57  MinSTCutBoost();
58  MinSTCutBoost(size_t numberOfNodes, size_t numberOfEdges);
59  void addEdge(node_type, node_type, ValueType);
60  void calculateCut(std::vector<bool>&);
61 
62  private:
63  // Members
64  graph_type graph_;
65  size_t numberOfNodes_;
66  size_t numberOfEdges_;
67  static const NType S = 0;
68  static const NType T = 1;
69  };
70 
71  //*********************
72  //** Implementation **
73  //*********************
74 
75  template<class NType, class VType, BoostMaxFlowAlgorithm mfalg>
77  numberOfNodes_ = 2;
78  numberOfEdges_ = 0;
79  }
80 
81  template<class NType, class VType, BoostMaxFlowAlgorithm mfalg>
82  MinSTCutBoost<NType, VType, mfalg>::MinSTCutBoost(size_t numberOfNodes, size_t numberOfEdges) {
83  numberOfNodes_ = numberOfNodes;
84  numberOfEdges_ = numberOfEdges;
85  graph_ = graph_type(numberOfNodes_);
86  //std::cout << "#nodes : " << numberOfNodes_ << std::endl;
87  }
88 
89  template<class NType, class VType, BoostMaxFlowAlgorithm mfalg>
91  assert(n1 < numberOfNodes_);
92  assert(n2 < numberOfNodes_);
93  assert(cost >= 0);
94  std::pair<edge_descriptor, bool> e = add_edge(n1, n2, graph_);
95  std::pair<edge_descriptor, bool> er = add_edge(n2, n1, graph_);
96  graph_[e.first].capacity += cost;
97  graph_[e.first].reverse = er.first;
98  graph_[er.first].reverse = e.first;
99  //std::cout << n1 << "->" << n2 << " : " << cost << std::endl;
100  }
101 
102  template<class NType, class VType, BoostMaxFlowAlgorithm mfalg>
103  void MinSTCutBoost<NType, VType, mfalg>::calculateCut(std::vector<bool>& segmentation) {
104  if (mfalg == KOLMOGOROV) {//Kolmogorov
105  std::vector<boost::default_color_type> color(num_vertices(graph_));
106  std::vector<edge_descriptor> pred(num_vertices(graph_));
107  std::vector<vertex_descriptor> dist(num_vertices(graph_));
108  boykov_kolmogorov_max_flow(graph_,
109  get(&Edge::capacity, graph_),
110  get(&Edge::residual, graph_),
111  get(&Edge::reverse, graph_),
112  &pred[0],
113  &color[0],
114  &dist[0],
115  get(boost::vertex_index, graph_),
116  S, T
117  );
118  // find (s,t)-cut set
119  segmentation.resize(num_vertices(graph_));
120  for (size_t j = 2; j < num_vertices(graph_); ++j) {
121  if (color[j] == boost::black_color || color[j] == boost::gray_color) {
122  segmentation[j] = false;
123  } else if (color[j] == boost::white_color) {
124  segmentation[j] = true;
125  }
126  }
127  }
128  else if (mfalg == PUSH_RELABEL) {// PushRelable
129 
130  push_relabel_max_flow(graph_, S, T,
131  get(&Edge::capacity, graph_),
132  get(&Edge::residual, graph_),
133  get(&Edge::reverse, graph_),
134  get(boost::vertex_index_t(), graph_)
135  );
136  // find (s,t)-cut set
137  segmentation.resize(num_vertices(graph_), true);
138  segmentation[S] = false; // source
139  segmentation[T] = false; // sink
140  typedef typename boost::property_map<graph_type, boost::vertex_index_t>::type VertexIndexMap;
141  VertexIndexMap vertexIndexMap = get(boost::vertex_index, graph_);
142  std::queue<vertex_descriptor> q;
143  q.push(*(vertices(graph_).first)); // source
144  while (!q.empty()) {
145  out_edge_iterator current, end;
146  tie(current, end) = out_edges(q.front(), graph_);
147  q.pop();
148  while (current != end) {
149  if (graph_[*current].residual > 0) {
150  vertex_descriptor v = target(*current, graph_);
151  if (vertexIndexMap[v] > 1 && segmentation[vertexIndexMap[v]] == true) {
152  segmentation[vertexIndexMap[v]] = false;
153  q.push(v);
154  }
155  }
156  ++current;
157  }
158  }
159  }
160  else if (mfalg == EDMONDS_KARP) {//EdmondsKarp
161  std::vector<boost::default_color_type> color(num_vertices(graph_));
162  std::vector<edge_descriptor> pred(num_vertices(graph_));
163  edmonds_karp_max_flow(graph_, S, T,
164  get(&Edge::capacity, graph_),
165  get(&Edge::residual, graph_),
166  get(&Edge::reverse, graph_),
167  &color[0], &pred[0]
168  );
169  // find (s,t)-cut set
170  segmentation.resize(num_vertices(graph_));
171  for (size_t j = 2; j < num_vertices(graph_); ++j) {
172  if (color[j] == boost::black_color) {
173  segmentation[j] = false;
174  } else if (color[j] == boost::white_color) {
175  segmentation[j] = true;
176  } else {
177  throw std::runtime_error("At least one vertex is labeled neither black nor white.");
178  }
179  }
180  }
181  else {//UNKNOWN MaxFlowalgorithm
182  throw std::runtime_error("Unknown MaxFlow-algorithm in MinSTCutBoost.hxx");
183  }
184  return;
185  }
186 
187 } // namespace opengm
188 
189 #ifdef USED_BOOST_DISABLE_ASSERTS
190 #undef BOOST_DISABLE_ASSERTS
191 #undef USED_BOOST_DISABLE_ASSERTS
192 #endif
193 
194 
195 #endif // #ifndef OPENGM_MINSTCUTBOOST_HXX
The OpenGM namespace.
Definition: config.hxx:43
Boost solvers for the min st-cut framework GraphCut.
boost::graph_traits< graph_type >::edge_iterator edge_iterator
graph_traits::edge_descriptor edge_descriptor
boost::graph_traits< graph_type >::out_edge_iterator out_edge_iterator
BoostMaxFlowAlgorithm
boost::adjacency_list< OutEdgeList, VertexList, boost::directedS, size_t, Edge > graph_type
void calculateCut(std::vector< bool > &)
boost::adjacency_list_traits< OutEdgeList, VertexList, boost::directedS > graph_traits
graph_traits::vertex_descriptor vertex_descriptor
void addEdge(node_type, node_type, ValueType)