2 #ifndef OPENGM_GRAPHCUT_HXX
3 #define OPENGM_GRAPHCUT_HXX
17 template<
class GM,
class ACC,
class MINSTCUT>
38 std::string
name()
const;
40 template<
class FACTOR>
43 template<
class VISITOR>
48 void addEdgeCapacity(
const size_t,
const size_t,
const ValueType);
49 size_t tripleId(std::vector<size_t>&);
51 const GraphicalModelType* gm_;
53 MinStCutType* minStCut_;
56 std::vector<size_t> numFacDim_;
57 std::list<std::vector<size_t> > tripleList;
58 std::vector<bool> state_;
59 std::vector<typename MINSTCUT::ValueType> sEdges_;
60 std::vector<typename MINSTCUT::ValueType> tEdges_;
64 template<
class GM,
class ACC,
class MINSTCUT>
70 template<
class GM,
class ACC,
class MINSTCUT>
76 template<
class GM,
class ACC,
class MINSTCUT>
79 const size_t numVariables,
80 std::vector<size_t> numFacDim,
85 tolerance_(fabs(tolerance))
91 numVariables_ = numVariables;
92 numFacDim_ = numFacDim;
94 minStCut_ =
new MinStCutType(2 + numVariables_ + numFacDim_[3], 2*numVariables_ + numFacDim_[2] + 3*numFacDim_[3]);
95 sEdges_.assign(numVariables_ + numFacDim_[3], 0);
96 tEdges_.assign(numVariables_ + numFacDim_[3], 0);
101 template<
class GM,
class ACC,
class MINSTCUT>
104 const GraphicalModelType& gm,
109 tolerance_(fabs(tolerance))
112 throw RuntimeError(
"This implementation of the graph cut optimizer supports as accumulator only opengm::Minimizer and opengm::Maximizer.");
114 for(
size_t j = 0; j < gm.numberOfVariables(); ++j) {
115 if(gm.numberOfLabels(j) != 2) {
116 throw RuntimeError(
"This implementation of the graph cut optimizer supports only binary variables.");
119 for(
size_t j = 0; j < gm.numberOfFactors(); ++j) {
120 if(gm[j].numberOfVariables() > 3) {
121 throw RuntimeError(
"This implementation of the graph cut optimizer supports only factors of order <= 3.");
126 numVariables_ = gm.numberOfVariables();
127 numFacDim_.resize(4, 0);
128 for(
size_t j = 0; j < gm.numberOfFactors(); ++j) {
129 ++numFacDim_[gm[j].numberOfVariables()];
132 minStCut_ =
new MinStCutType(2 + numVariables_ + numFacDim_[3], 2*numVariables_ + numFacDim_[2] + 3*numFacDim_[3]);
133 sEdges_.assign(numVariables_ + numFacDim_[3], 0);
134 tEdges_.assign(numVariables_ + numFacDim_[3], 0);
136 for(
size_t j = 0; j < gm.numberOfFactors(); ++j) {
139 inferenceDone_=
false;
143 template<
class GM,
class ACC,
class MINSTCUT>
150 template<
class GM,
class ACC,
class MINSTCUT>
151 template<
class FACTOR>
156 size_t numberOfVariables = factor.numberOfVariables();
157 for(
size_t i=0; i<numberOfVariables; ++i) {
161 if(numberOfVariables == 0) {
164 else if(numberOfVariables == 1) {
165 const size_t var = factor.variableIndex(0);
172 addEdgeCapacity(0, var + 2, v1 - v0);
175 addEdgeCapacity(var + 2, 1, v0 - v1);
180 addEdgeCapacity(0, var + 2, -v1 + v0);
183 addEdgeCapacity(var + 2, 1, -v0 + v1);
187 else if(numberOfVariables == 2) {
188 const size_t var0 = factor.variableIndex(0);
189 const size_t var1 = factor.variableIndex(1);
192 size_t i[] = {0, 0};
const ValueType A = factor(i);
193 i[0] = 0; i[1] = 1;
const ValueType B = factor(i);
194 i[0] = 1; i[1] = 0;
const ValueType C = factor(i);
195 i[0] = 1; i[1] = 1;
const ValueType D = factor(i);
199 addEdgeCapacity(0, var0 + 2, C - A);
201 addEdgeCapacity(var0 + 2, 1, A - C);
204 addEdgeCapacity(0, var1 + 2, D - C);
206 addEdgeCapacity(var1 + 2, 1, C - D);
209 if((term < 0) && (term >= -tolerance_))
214 addEdgeCapacity(var0 + 2, var1 + 2, term);
218 addEdgeCapacity(0, var0 + 2, -C + A);
220 addEdgeCapacity(var0 + 2, 1, -A + C);
223 addEdgeCapacity(0, var1 + 2, -D + C);
225 addEdgeCapacity(var1 + 2, 1, -C + D);
228 if((term > 0) && (term <= tolerance_))
230 addEdgeCapacity(var0 + 2, var1 + 2, -term);
236 else if(numberOfVariables == 3) {
237 const size_t var0 = factor.variableIndex(0);
238 const size_t var1 = factor.variableIndex(1);
239 const size_t var2 = factor.variableIndex(1);
243 size_t i[] = {0, 0, 0};
const ValueType A = factor(i);
244 i[0] = 0; i[1] = 0; i[2] = 1;
const ValueType B = factor(i);
245 i[0] = 0; i[1] = 1; i[2] = 0;
const ValueType C = factor(i);
246 i[0] = 0; i[1] = 1; i[2] = 1;
const ValueType D = factor(i);
247 i[0] = 1; i[1] = 0; i[2] = 0;
const ValueType E = factor(i);
248 i[0] = 1; i[1] = 0; i[2] = 1;
const ValueType F = factor(i);
249 i[0] = 1; i[1] = 1; i[2] = 0;
const ValueType G = factor(i);
250 i[0] = 1; i[1] = 1; i[2] = 1;
const ValueType H = factor(i);
253 std::vector<size_t> triple(3);
257 size_t id = tripleId(triple);
258 ValueType P = (A + D + F + G)-(B + C + E + H);
260 if(F-B>=0) addEdgeCapacity(0, var0+2, F - B);
261 else addEdgeCapacity(var0+2, 1, B - F);
262 if(G-E>=0) addEdgeCapacity(0, var1+2, G - E);
263 else addEdgeCapacity(var1+2, 1, E - G);
264 if(D-C>=0) addEdgeCapacity(0, var2+2, D - C);
265 else addEdgeCapacity(var2+2, 0, C - D);
267 addEdgeCapacity(var1+2, var2+2, B + C - A - D);
268 addEdgeCapacity(var2+2, var0+2, B + E - A - F);
269 addEdgeCapacity(var0+2, var1+2, C + E - A - G);
271 addEdgeCapacity(var0 + 2,
id + 2, P);
272 addEdgeCapacity(var1 + 2,
id + 2, P);
273 addEdgeCapacity(var2 + 2,
id + 2, P);
274 addEdgeCapacity(
id, 1, P);
277 if(C-G>=0) addEdgeCapacity(var0+2, 1, C - G);
278 else addEdgeCapacity(0, var0+2, G - C);
279 if(B-D>=0) addEdgeCapacity(var1+2, 1, B - D);
280 else addEdgeCapacity(0, var1+2, D - B);
281 if(E-F>=0) addEdgeCapacity(var2+2, 1, E - F);
282 else addEdgeCapacity(0, var2+2, F - E);
284 addEdgeCapacity(var2+2, var1+2, F + G - E - H);
285 addEdgeCapacity(var0+2, var2+2, D + G - C - H);
286 addEdgeCapacity(var1+2, var0+2, D + F - B - H);
288 addEdgeCapacity(
id + 2, var0 + 2, -P);
289 addEdgeCapacity(
id + 2, var1 + 2, -P);
290 addEdgeCapacity(
id + 2, var2 + 2, -P);
291 addEdgeCapacity(0,
id + 2, -P);
295 throw RuntimeError(
"This implementation of the graph cut optimizer support 3rd order factors only in connection with opengm::Maximizer.");
299 throw RuntimeError(
"This implementation of the graph cut optimizer does not support factors of order > 3.");
303 template<
class GM,
class ACC,
class MINSTCUT>
311 typedef typename MINSTCUT::ValueType VType;
312 typedef typename MINSTCUT::node_type NType;
313 const NType n1 =
static_cast<NType
>(v);
314 const NType n2 =
static_cast<NType
>(w);
315 const VType cost =
static_cast<VType
>(parameter_.scale_*val);
317 sEdges_[n2-2] += cost;
320 tEdges_[n1-2] += cost;
323 minStCut_->addEdge(n1, n2, cost);
327 template<
class GM,
class ACC,
class MINSTCUT>
329 GraphCut<GM, ACC, MINSTCUT>::tripleId
331 std::vector<size_t>& triple
334 std::list<std::vector<size_t> >::iterator it;
335 size_t counter = numVariables_;
336 for(it = tripleList.begin(); it != tripleList.end(); it++) {
337 if(triple[0] == (*it)[0] && triple[1] == (*it)[1] && triple[2] == (*it)[2]) {
343 tripleList.push_back(triple);
348 template<
class GM,
class ACC,
class MINSTCUT>
355 template<
class GM,
class ACC,
class MINSTCUT>
356 template<
class VISITOR>
359 visitor.begin(*
this);
360 for(
size_t i=0; i<sEdges_.size(); ++i) {
361 minStCut_->addEdge(0, i+2, sEdges_[i]);
362 minStCut_->addEdge(i+2, 1, tEdges_[i]);
364 minStCut_->calculateCut(state_);
370 template<
class GM,
class ACC,
class MINSTCUT>
373 std::vector<LabelType>& arg,
376 if(inferenceDone_==
false){
377 arg.resize(numVariables_,0);
385 if(state_.size() > 2 + numFacDim_[3]) {
386 arg.resize(state_.size() - 2 - numFacDim_[3]);
392 for(
size_t j = 0; j < arg.size(); ++j) {
393 arg[j] =
static_cast<LabelType>(state_[j + 2]);
401 #endif // #ifndef OPENGM_GRAPHCUT_HXX
GraphCut(const GraphicalModelType &, const Parameter &=Parameter(), ValueType=static_cast< ValueType >(0.0))
Addition as a binary operation.
InferenceTermination infer()
visitors::EmptyVisitor< GraphCut< GM, ACC, MINSTCUT > > EmptyVisitorType
#define OPENGM_ASSERT(expression)
visitors::TimingVisitor< GraphCut< GM, ACC, MINSTCUT > > TimingVisitorType
const GraphicalModelType & graphicalModel() const
visitors::VerboseVisitor< GraphCut< GM, ACC, MINSTCUT > > VerboseVisitorType
GraphicalModelType::ValueType ValueType
Inference algorithm interface.
void addFactor(const FACTOR &factor)
add a factor of the GraphicalModel to the min st-cut formulation of the solver MinStCutType ...
GraphicalModelType::LabelType LabelType
Minimization as a unary accumulation.
InferenceTermination arg(std::vector< LabelType > &, const size_t=1) const
output a solution
Maximization as a unary accumulation.
Parameter(const ValueType scale=1)
A framework for min st-cut algorithms.