2 #ifndef OPENGM_GRAPHCUT_HXX 3 #define OPENGM_GRAPHCUT_HXX 17 template<
class GM,
class ACC,
class MINSTCUT>
26 template<
class _GM,
class _ACC>
55 std::string
name()
const;
57 template<
class FACTOR>
60 template<
class VISITOR>
65 void addEdgeCapacity(
const size_t,
const size_t,
const ValueType);
66 size_t tripleId(std::vector<size_t>&);
68 const GraphicalModelType* gm_;
70 MinStCutType* minStCut_;
73 std::vector<size_t> numFacDim_;
74 std::list<std::vector<size_t> > tripleList;
75 std::vector<bool> state_;
76 std::vector<typename MINSTCUT::ValueType> sEdges_;
77 std::vector<typename MINSTCUT::ValueType> tEdges_;
81 template<
class GM,
class ACC,
class MINSTCUT>
87 template<
class GM,
class ACC,
class MINSTCUT>
93 template<
class GM,
class ACC,
class MINSTCUT>
96 const size_t numVariables,
97 std::vector<size_t> numFacDim,
102 tolerance_(fabs(tolerance))
108 numVariables_ = numVariables;
109 numFacDim_ = numFacDim;
110 numFacDim_.resize(4);
111 minStCut_ =
new MinStCutType(2 + numVariables_ + numFacDim_[3], 2*numVariables_ + numFacDim_[2] + 3*numFacDim_[3]);
112 sEdges_.assign(numVariables_ + numFacDim_[3], 0);
113 tEdges_.assign(numVariables_ + numFacDim_[3], 0);
114 inferenceDone_=
false;
118 template<
class GM,
class ACC,
class MINSTCUT>
121 const GraphicalModelType& gm,
126 tolerance_(fabs(tolerance))
129 throw RuntimeError(
"This implementation of the graph cut optimizer supports as accumulator only opengm::Minimizer and opengm::Maximizer.");
131 for(
size_t j = 0; j < gm.numberOfVariables(); ++j) {
132 if(gm.numberOfLabels(j) != 2) {
133 throw RuntimeError(
"This implementation of the graph cut optimizer supports only binary variables.");
136 for(
size_t j = 0; j < gm.numberOfFactors(); ++j) {
137 if(gm[j].numberOfVariables() > 3) {
138 throw RuntimeError(
"This implementation of the graph cut optimizer supports only factors of order <= 3.");
143 numVariables_ = gm.numberOfVariables();
144 numFacDim_.resize(4, 0);
145 for(
size_t j = 0; j < gm.numberOfFactors(); ++j) {
146 ++numFacDim_[gm[j].numberOfVariables()];
149 minStCut_ =
new MinStCutType(2 + numVariables_ + numFacDim_[3], 2*numVariables_ + numFacDim_[2] + 3*numFacDim_[3]);
150 sEdges_.assign(numVariables_ + numFacDim_[3], 0);
151 tEdges_.assign(numVariables_ + numFacDim_[3], 0);
153 for(
size_t j = 0; j < gm.numberOfFactors(); ++j) {
156 inferenceDone_=
false;
160 template<
class GM,
class ACC,
class MINSTCUT>
167 template<
class GM,
class ACC,
class MINSTCUT>
168 template<
class FACTOR>
173 size_t numberOfVariables = factor.numberOfVariables();
174 for(
size_t i=0; i<numberOfVariables; ++i) {
178 if(numberOfVariables == 0) {
181 else if(numberOfVariables == 1) {
182 const size_t var = factor.variableIndex(0);
189 addEdgeCapacity(0, var + 2, v1 - v0);
192 addEdgeCapacity(var + 2, 1, v0 - v1);
197 addEdgeCapacity(0, var + 2, -v1 + v0);
200 addEdgeCapacity(var + 2, 1, -v0 + v1);
204 else if(numberOfVariables == 2) {
205 const size_t var0 = factor.variableIndex(0);
206 const size_t var1 = factor.variableIndex(1);
209 size_t i[] = {0, 0};
const ValueType A = factor(i);
210 i[0] = 0; i[1] = 1;
const ValueType B = factor(i);
211 i[0] = 1; i[1] = 0;
const ValueType C = factor(i);
212 i[0] = 1; i[1] = 1;
const ValueType D = factor(i);
216 addEdgeCapacity(0, var0 + 2, C - A);
218 addEdgeCapacity(var0 + 2, 1, A - C);
221 addEdgeCapacity(0, var1 + 2, D - C);
223 addEdgeCapacity(var1 + 2, 1, C - D);
226 if((term < 0) && (term >= -tolerance_))
231 addEdgeCapacity(var0 + 2, var1 + 2, term);
235 addEdgeCapacity(0, var0 + 2, -C + A);
237 addEdgeCapacity(var0 + 2, 1, -A + C);
240 addEdgeCapacity(0, var1 + 2, -D + C);
242 addEdgeCapacity(var1 + 2, 1, -C + D);
245 if((term > 0) && (term <= tolerance_))
247 addEdgeCapacity(var0 + 2, var1 + 2, -term);
253 else if(numberOfVariables == 3) {
254 const size_t var0 = factor.variableIndex(0);
255 const size_t var1 = factor.variableIndex(1);
256 const size_t var2 = factor.variableIndex(1);
260 size_t i[] = {0, 0, 0};
const ValueType A = factor(i);
261 i[0] = 0; i[1] = 0; i[2] = 1;
const ValueType B = factor(i);
262 i[0] = 0; i[1] = 1; i[2] = 0;
const ValueType C = factor(i);
263 i[0] = 0; i[1] = 1; i[2] = 1;
const ValueType D = factor(i);
264 i[0] = 1; i[1] = 0; i[2] = 0;
const ValueType E = factor(i);
265 i[0] = 1; i[1] = 0; i[2] = 1;
const ValueType F = factor(i);
266 i[0] = 1; i[1] = 1; i[2] = 0;
const ValueType G = factor(i);
267 i[0] = 1; i[1] = 1; i[2] = 1;
const ValueType H = factor(i);
270 std::vector<size_t> triple(3);
274 size_t id = tripleId(triple);
275 ValueType P = (A + D + F + G)-(B + C + E + H);
277 if(F-B>=0) addEdgeCapacity(0, var0+2, F - B);
278 else addEdgeCapacity(var0+2, 1, B - F);
279 if(G-E>=0) addEdgeCapacity(0, var1+2, G - E);
280 else addEdgeCapacity(var1+2, 1, E - G);
281 if(D-C>=0) addEdgeCapacity(0, var2+2, D - C);
282 else addEdgeCapacity(var2+2, 0, C - D);
284 addEdgeCapacity(var1+2, var2+2, B + C - A - D);
285 addEdgeCapacity(var2+2, var0+2, B + E - A - F);
286 addEdgeCapacity(var0+2, var1+2, C + E - A - G);
288 addEdgeCapacity(var0 + 2,
id + 2, P);
289 addEdgeCapacity(var1 + 2,
id + 2, P);
290 addEdgeCapacity(var2 + 2,
id + 2, P);
291 addEdgeCapacity(
id, 1, P);
294 if(C-G>=0) addEdgeCapacity(var0+2, 1, C - G);
295 else addEdgeCapacity(0, var0+2, G - C);
296 if(B-D>=0) addEdgeCapacity(var1+2, 1, B - D);
297 else addEdgeCapacity(0, var1+2, D - B);
298 if(E-F>=0) addEdgeCapacity(var2+2, 1, E - F);
299 else addEdgeCapacity(0, var2+2, F - E);
301 addEdgeCapacity(var2+2, var1+2, F + G - E - H);
302 addEdgeCapacity(var0+2, var2+2, D + G - C - H);
303 addEdgeCapacity(var1+2, var0+2, D + F - B - H);
305 addEdgeCapacity(
id + 2, var0 + 2, -P);
306 addEdgeCapacity(
id + 2, var1 + 2, -P);
307 addEdgeCapacity(
id + 2, var2 + 2, -P);
308 addEdgeCapacity(0,
id + 2, -P);
312 throw RuntimeError(
"This implementation of the graph cut optimizer support 3rd order factors only in connection with opengm::Maximizer.");
316 throw RuntimeError(
"This implementation of the graph cut optimizer does not support factors of order > 3.");
320 template<
class GM,
class ACC,
class MINSTCUT>
328 typedef typename MINSTCUT::ValueType VType;
329 typedef typename MINSTCUT::node_type NType;
330 const NType n1 =
static_cast<NType
>(v);
331 const NType n2 =
static_cast<NType
>(w);
332 const VType cost =
static_cast<VType
>(parameter_.scale_*val);
334 sEdges_[n2-2] += cost;
337 tEdges_[n1-2] += cost;
340 minStCut_->addEdge(n1, n2, cost);
344 template<
class GM,
class ACC,
class MINSTCUT>
348 std::vector<size_t>& triple
351 std::list<std::vector<size_t> >::iterator it;
352 size_t counter = numVariables_;
353 for(it = tripleList.begin(); it != tripleList.end(); it++) {
354 if(triple[0] == (*it)[0] && triple[1] == (*it)[1] && triple[2] == (*it)[2]) {
360 tripleList.push_back(triple);
365 template<
class GM,
class ACC,
class MINSTCUT>
372 template<
class GM,
class ACC,
class MINSTCUT>
373 template<
class VISITOR>
376 visitor.begin(*
this);
377 for(
size_t i=0; i<sEdges_.size(); ++i) {
378 minStCut_->addEdge(0, i+2, sEdges_[i]);
379 minStCut_->addEdge(i+2, 1, tEdges_[i]);
381 minStCut_->calculateCut(state_);
387 template<
class GM,
class ACC,
class MINSTCUT>
390 std::vector<LabelType>&
arg,
393 if(inferenceDone_==
false){
394 arg.resize(numVariables_,0);
402 if(state_.size() > 2 + numFacDim_[3]) {
403 arg.resize(state_.size() - 2 - numFacDim_[3]);
409 for(
size_t j = 0; j < arg.size(); ++j) {
410 arg[j] =
static_cast<LabelType>(state_[j + 2]);
418 #endif // #ifndef OPENGM_GRAPHCUT_HXX const GraphicalModelType & graphicalModel() const
GraphCut< _GM, ACC, MINSTCUT > type
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
visitors::VerboseVisitor< GraphCut< GM, ACC, MINSTCUT > > VerboseVisitorType
GraphicalModelType::ValueType ValueType
Inference algorithm interface.
InferenceTermination arg(std::vector< LabelType > &, const size_t=1) const
output a solution
void addFactor(const FACTOR &factor)
add a factor of the GraphicalModel to the min st-cut formulation of the solver MinStCutType ...
GraphCut< _GM, _ACC, MINSTCUT > type
GraphicalModelType::LabelType LabelType
Minimization as a unary accumulation.
Maximization as a unary accumulation.
Parameter(const ValueType scale=1)
A framework for min st-cut algorithms.