MaxFlowSolver<T> is the interface between AlphaExpansion and the underlying graph-cut backend. Subclass it to plug in any max-flow library.
Interface
template <typename T>
public:
};
Abstract interface for a binary max-flow / QPBO solver.
Definition MaxFlowSolver.hpp:15
virtual void add_constant(T E)=0
Adds a constant term to the energy function.
virtual Var add_variable()=0
Introduces a new binary variable and returns its handle.
virtual void add_term1(Var x, T E0, T E1)=0
Adds a unary term E(x) where x ∈ {0, 1}.
virtual T minimize()=0
Minimizes the energy and returns the minimum value.
int Var
Integer handle identifying a binary variable.
Definition MaxFlowSolver.hpp:20
virtual ~MaxFlowSolver()=default
virtual void add_term2(Var x, Var y, T E00, T E01, T E10, T E11)=0
Adds a pairwise term E(x, y) where x, y ∈ {0, 1}.
virtual int get_var(Var x)=0
Returns the optimal value of variable x (0 or 1) after minimize().
Step-by-Step Example
The following example wraps a hypothetical LibFoo max-flow library.
1. Create the header
#pragma once
#include <libfoo/maxflow.h>
template <typename T>
libfoo::Graph graph_;
int num_vars_ = 0;
public:
FooSolver() = default;
graph_.add_node();
return num_vars_++;
}
}
graph_.add_tweights(x, E1, E0);
}
T E00, T E01, T E10, T E11) override {
graph_.add_edge(x, y, E01 - E00, E10 - E11);
}
return static_cast<T>(graph_.solve());
}
return graph_.what_segment(x);
}
};
2. Pass it via a factory lambda
#include "solvers/FooSolver.hpp"
auto factory = [](int v, int e) {
return std::make_unique<FooSolver<int>>();
};
strategy.execute(optimizer, model);
Performs alpha-expansion moves on an EnergyModel using a pluggable max-flow solver.
Definition AlphaExpansion.hpp:20
Stores the graph and energy costs for the Alpha-Expansion algorithm.
Definition EnergyModel.hpp:17
Expansion strategy that cycles through labels in fixed order 0, 1, …, K-1.
Definition SequentialStrategy.hpp:14
Conventions
- Variable 0 = alpha label, variable 1 = keep current label.
get_var() must return 0 for nodes that should switch to alpha.
- **
add_term2 receives a submodular matrix.** For Potts energies, E00 + E11 <= E01 + E10 always holds, so you do not need to handle the non-submodular case.
- The factory is called once per expansion move, so allocate per-move state in the constructor.