1 #ifndef OPENGM_PERMUTABLE_LABEL_FUSION_MOVER_HXX
2 #define OPENGM_PERMUTABLE_LABEL_FUSION_MOVER_HXX
21 #ifndef WITH_BOOST_GRAPH
22 #define WITH_BOOST_GRAPH
26 #include <vigra/adjacency_list_graph.hxx>
27 #include <vigra/merge_graph_adaptor.hxx>
28 #include <vigra/hierarchical_clustering.hxx>
29 #include <vigra/priority_queue.hxx>
30 #include <vigra/random.hxx>
31 #include <vigra/graph_algorithms.hxx>
44 template<
class GM,
class ACC >
51 typedef vigra::AdjacencyListGraph
Graph;
55 typedef typename MergeGraph::Edge
Edge;
64 const float stopWeight = 0.0
74 MergeGraph & mergegraph,
76 std::vector<ValueType> & weights
85 for(
size_t i=0; i<
graph_.edgeNum(); ++i){
102 index_type minLabel =
pq_.top();
104 pq_.deleteItem(minLabel);
105 minLabel =
pq_.top();
107 return Edge(minLabel);
112 index_type minLabel =
pq_.top();
114 pq_.deleteItem(minLabel);
115 minLabel =
pq_.top();
117 return pq_.topPriority();
133 pq_.deleteItem(b.id());
137 pq_.deleteItem(edge.id());
142 vigra::ChangeablePriorityQueue< ValueType ,std::greater<ValueType> >
pq_;
154 template<
class GM,
class ACC>
162 typedef std::map<UInt64Type, ValueType>
MapType;
182 const bool planar =
false,
183 const std::string workflow = std::string(),
184 const int nThreads = 1,
185 const bool decompose =
false,
186 const std::vector<bool> & allowCutsWithin = std::vector<bool>()
244 throw RuntimeError(
"WITH_CPLEX or WITH_QPBO or WITH_ISINF must be enabled");
254 const size_t numberOfLabels = nx*ny;
257 for(
size_t y = 0; y < ny; ++y){
259 for(
size_t x = 0; x < nx; ++x) {
260 std::cout<<arg[i]<<
" ";
270 const std::vector<LabelType> & a,
271 const std::vector<LabelType> & b,
272 std::vector<LabelType> & res
275 for(
size_t fi=0; fi< gm_.numberOfFactors(); ++fi){
276 if(gm_[fi].numberOfVariables()==2){
278 const size_t vi0 = gm_[fi].variableIndex(0);
279 const size_t vi1 = gm_[fi].variableIndex(1);
283 if(a[vi0] == a[vi1] && b[vi0] == b[vi1]){
287 else if(gm_[fi].numberOfVariables()==1){
291 throw RuntimeError(
"only implemented for second order");
294 std::map<LabelType, LabelType> repr;
295 ufd.representativeLabeling(repr);
296 for(
size_t vi=0; vi<gm_.numberOfVariables(); ++vi){
297 res[vi]=repr[ufd.find(vi)];
306 return ufd.numberOfSets();
310 const std::vector<LabelType> & a,
311 const std::vector<LabelType> & b,
312 std::vector<LabelType> & res,
313 const ValueType valA,
314 const ValueType valB,
321 std::vector<LabelType> ab(gm_.numberOfVariables());
322 IndexType numNewVar = this->
intersect(a, b, ab);
329 const ValueType intersectedVal = gm_.evaluate(ab);
337 size_t erasedEdges = 0;
338 size_t notErasedEdges = 0;
347 for(
size_t fi=0; fi< gm_.numberOfFactors(); ++fi){
348 if(gm_[fi].numberOfVariables()==2){
349 const size_t vi0 = gm_[fi].variableIndex(0);
350 const size_t vi1 = gm_[fi].variableIndex(1);
352 const size_t cVi0 = ab[vi0] < ab[vi1] ? ab[vi0] : ab[vi1];
353 const size_t cVi1 = ab[vi0] < ab[vi1] ? ab[vi1] : ab[vi0];
366 ValueType val00 = gm_[fi](lAA);
367 ValueType val01 = gm_[fi](lAB);
368 ValueType weight = val01 - val00;
376 MapIter iter = accWeights.find(key);
379 if(iter == accWeights.end()){
380 accWeights[key] = weight;
384 iter->second += weight;
391 OPENGM_CHECK_OP(erasedEdges+notErasedEdges, == , gm_.numberOfFactors(),
"something wrong");
401 return doMoveCgc(accWeights,ab,numNewVar, a, b, res, valA, valB, valRes);
404 return doMoveMulticut(accWeights,ab,numNewVar, a, b, res, valA, valB, valRes);
413 return doMoveBase(accWeights,ab,numNewVar, a, b, res, valA, valB, valRes);
424 const std::vector<LabelType> & a,
425 const std::vector<LabelType> & b,
426 std::vector<LabelType> & res,
427 const ValueType valA,
428 const ValueType valB,
431 LabelType maxL = *std::max_element(a.begin(), a.end());
432 std::vector<LabelType> bb = b;
433 for(
size_t i=0; i<bb.size(); ++i){
438 hlf.
fuse(a,b,res, valA, valB, valRes);
440 std::map<LabelType, LabelType> mdense;
443 for(
size_t i=0;i<res.size(); ++i){
445 if(mdense.find(resL) == mdense.end()){
450 res[i] = mdense[res[i]];
453 valRes = gm_.evaluate(res);
454 if(valRes< std::min(valA,valB)){
456 std::map<LabelType, LabelType> mdense;
459 for(
size_t i=0;i<res.size(); ++i){
461 if(mdense.find(resL) == mdense.end()){
466 res[i] = mdense[res[i]];
470 else if(valA<valRes){
481 const std::vector<LabelType> & a,
482 const std::vector<LabelType> & b,
483 std::vector<LabelType> & res,
484 const ValueType valA,
485 const ValueType valB,
488 std::vector<LabelType> ab(gm_.numberOfVariables());
489 IndexType numNewVar = this->
intersect(a, b, ab);
495 const ValueType intersectedVal = gm_.evaluate(ab);
503 size_t erasedEdges = 0;
504 size_t notErasedEdges = 0;
510 size_t ushape[] = {
size_t(numNewVar),
size_t(gm_.maxNumberOfLabels()) };
514 for(
size_t fi=0; fi< gm_.numberOfFactors(); ++fi){
515 if(gm_[fi].numberOfVariables()==2){
516 const size_t vi0 = gm_[fi].variableIndex(0);
517 const size_t vi1 = gm_[fi].variableIndex(1);
519 const size_t cVi0 = ab[vi0] < ab[vi1] ? ab[vi0] : ab[vi1];
520 const size_t cVi1 = ab[vi0] < ab[vi1] ? ab[vi1] : ab[vi0];
533 ValueType val00 = gm_[fi](lAA);
534 ValueType val01 = gm_[fi](lAB);
535 ValueType weight = val01 - val00;
543 MapIter iter = accWeights.find(key);
546 if(iter == accWeights.end()){
547 accWeights[key] = weight;
551 iter->second += weight;
557 if(gm_[fi].numberOfVariables()==1){
558 const IndexType cVi = ab[gm_[fi].numberOfVariables()];
560 accUnaries(cVi,l)+=gm_[fi](&l);
567 OPENGM_CHECK_OP(erasedEdges+notErasedEdges, == , gm_.numberOfFactors(),
"something wrong");
572 return doMoveMmcw(accWeights,accUnaries,ab,numNewVar, a, b, res, valA, valB, valRes);
577 const MapType & accWeights,
579 const std::vector<LabelType> & ab,
580 const IndexType numNewVar,
581 const std::vector<LabelType> & a,
582 const std::vector<LabelType> & b,
583 std::vector<LabelType> & res,
584 const ValueType valA,
585 const ValueType valB,
589 SubSpace subSpace(numNewVar, 2);
590 SubModel subGm(subSpace);
593 subGm.
template reserveFunctions<PFunction>(accWeights.size());
594 subGm.
template reserveFunctions<EFunction>(numNewVar);
598 size_t efshape[] = {accUnaries.
shape(1)};
599 EFunction ef(efshape,efshape+1);
602 for(IndexType vi=0; vi<numNewVar; ++vi){
604 ef(&l) = accUnaries(vi, l);
610 for(MapCIter i = accWeights.begin(); i!=accWeights.end(); ++i){
612 const ValueType weight = i->second;
618 PFunction pf(numNewVar, numNewVar, 0.0, weight);
622 std::vector<LabelType> subArg;
627 typedef typename Inf::Parameter Param;
644 std::vector<size_t> oarg = inf.getSegmentation();
648 for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
649 res[vi] = oarg[ab[vi]];
652 ValueType resultVal = subGm.
evaluate(subArg);
658 if(gm_.numberOfFactors()==1){
659 IndexType vi0 = subGm[f].variableIndex(0);
660 IndexType vi1 = subGm[f].variableIndex(1);
662 if(subArg[vi0] == subArg[vi1] && oarg[vi0] != oarg[vi1]){
663 resultVal+=gm_[f](lAB);
672 const MapType & accWeights,
673 const std::vector<LabelType> & ab,
674 const IndexType numNewVar,
675 const std::vector<LabelType> & a,
676 const std::vector<LabelType> & b,
677 std::vector<LabelType> & res,
678 const ValueType valA,
679 const ValueType valB,
685 SubSpace subSpace(numNewVar, numNewVar);
686 SubModel subGm(subSpace);
689 subGm.
template reserveFunctions<PFunction>(accWeights.size());
693 for(MapCIter i = accWeights.begin(); i!=accWeights.end(); ++i){
695 const ValueType weight = i->second;
701 PFunction pf(numNewVar, numNewVar, 0.0, weight);
705 std::vector<LabelType> subArg;
709 typedef typename Inf::Parameter Param;
718 for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
719 res[vi] = subArg[ab[vi]];
721 const ValueType resultVal = subGm.
evaluate(subArg);
722 const ValueType projectedResultVal = gm_.evaluate(res);
723 const std::vector<LabelType> & bestArg = valA < valB ? a : b;
724 const ValueType bestProposalVal = valA < valB ? valA : valB;
726 valRes = bestProposalVal < projectedResultVal ? bestProposalVal : projectedResultVal;
727 if(projectedResultVal < bestProposalVal){
733 for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
734 res[vi] = bestArg[vi];
742 const MapType & accWeights,
743 const std::vector<LabelType> & ab,
744 const IndexType numNewVar,
745 const std::vector<LabelType> & a,
746 const std::vector<LabelType> & b,
747 std::vector<LabelType> & res,
748 const ValueType valA,
749 const ValueType valB,
752 const std::vector<LabelType> & bestArg = valA < valB ? a : b;
753 valRes = valA < valB ? valA : valB;
754 for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
755 res[vi] = bestArg[vi];
761 const MapType & accWeights,
762 const std::vector<LabelType> & ab,
763 const IndexType numNewVar,
764 const std::vector<LabelType> & a,
765 const std::vector<LabelType> & b,
766 std::vector<LabelType> & res,
767 const ValueType valA,
768 const ValueType valB,
772 SubSpace subSpace(numNewVar, numNewVar);
773 SubModel subGm(subSpace);
776 subGm.
template reserveFunctions<PFunction>(accWeights.size());
780 for(MapCIter i = accWeights.begin(); i!=accWeights.end(); ++i){
782 const ValueType weight = i->second;
788 PFunction pf(numNewVar, numNewVar, 0.0, weight);
792 std::vector<LabelType> subArg;
797 typedef typename McInf::Parameter McParam;
810 McInf inf(subGm,pmc);
816 typedef typename DmcInf::Parameter DmcParam;
817 typedef typename DmcInf::InfParam DmcInfParam;
819 DmcInfParam dmcInfParam(pmc);
821 dmcParam.infParam_ = dmcInfParam;
823 DmcInf inf(subGm, dmcParam);
832 for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
833 res[vi] = subArg[ab[vi]];
835 const ValueType resultVal = subGm.
evaluate(subArg);
836 const ValueType projectedResultVal = gm_.evaluate(res);
837 const std::vector<LabelType> & bestArg = valA < valB ? a : b;
838 const ValueType bestProposalVal = valA < valB ? valA : valB;
840 valRes = bestProposalVal < projectedResultVal ? bestProposalVal : projectedResultVal;
841 if(projectedResultVal < bestProposalVal){
847 for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
848 res[vi] = bestArg[vi];
856 const MapType & accWeights,
857 const std::vector<LabelType> & ab,
858 const IndexType numNewVar,
859 const std::vector<LabelType> & a,
860 const std::vector<LabelType> & b,
861 std::vector<LabelType> & res,
862 const ValueType valA,
863 const ValueType valB,
867 std::vector<LabelType> subArg;
871 typedef typename Inf::Parameter Param;
882 Inf inf(numNewVar, accWeights, p);
888 for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
889 res[vi] = subArg[ab[vi]];
892 const ValueType projectedResultVal = gm_.evaluate(res);
893 const std::vector<LabelType> & bestArg = valA < valB ? a : b;
894 const ValueType bestProposalVal = valA < valB ? valA : valB;
896 valRes = bestProposalVal < projectedResultVal ? bestProposalVal : projectedResultVal;
897 if(projectedResultVal < bestProposalVal){
903 for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
904 res[vi] = bestArg[vi];
911 const MapType & accWeights,
912 const std::vector<LabelType> & ab,
913 const IndexType numNewVar,
914 const std::vector<LabelType> & a,
915 const std::vector<LabelType> & b,
916 std::vector<LabelType> & res,
917 const ValueType valA,
918 const ValueType valB,
922 typedef vigra::AdjacencyListGraph Graph;
923 typedef typename Graph::Edge Edge;
924 typedef vigra::MergeGraphAdaptor< Graph > MergeGraph;
926 typedef typename ClusterOp::Parameter ClusterOpParam;
927 typedef vigra::HierarchicalClustering< ClusterOp > HC;
928 typedef typename HC::Parameter HcParam;
930 std::vector<ValueType> weights(accWeights.size(),0.0);
932 Graph graph(numNewVar, accWeights.size());
933 for(MapCIter i = accWeights.begin(); i!=accWeights.end(); ++i){
935 const ValueType weight = i->second;
940 const Edge e = graph.addEdge(cVi0, cVi1);
941 weights[graph.id(e)] = weight;
944 MergeGraph mg(graph);
949 const ClusterOpParam clusterOpParam;
950 ClusterOp clusterOp(graph, mg, clusterOpParam, weights);
963 for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
964 res[vi] = hc.reprNodeId(ab[vi]);
967 const ValueType projectedResultVal = gm_.evaluate(res);
968 const std::vector<LabelType> & bestArg = valA < valB ? a : b;
969 const ValueType bestProposalVal = valA < valB ? valA : valB;
971 valRes = bestProposalVal < projectedResultVal ? bestProposalVal : projectedResultVal;
972 if(projectedResultVal < bestProposalVal){
978 for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
979 res[vi] = bestArg[vi];
IndexType addFactor(const FunctionIdentifier &, ITERATOR, ITERATOR)
add a factor to the graphical model
MergeGraph & mergeGraph()
get a reference to the merge
McClusterOp(const Graph &graph, MergeGraph &mergegraph, const Parameter ¶m, std::vector< ValueType > &weights)
PermutableLabelFusionMove< GM, ACC > SelfType
vigra::AdjacencyListGraph Graph
SimpleDiscreteSpace< IndexType, LabelType > SubSpace
bool doMoveMmcw(const MapType &accWeights, const marray::Marray< ValueType > &accUnaries, const std::vector< LabelType > &ab, const IndexType numNewVar, const std::vector< LabelType > &a, const std::vector< LabelType > &b, std::vector< LabelType > &res, const ValueType valA, const ValueType valB, ValueType &valRes)
size_t intersect(const std::vector< LabelType > &a, const std::vector< LabelType > &b, std::vector< LabelType > &res)
FunctionIdentifier addFunction(const FUNCTION_TYPE &)
add a function to the graphical model
FusionSolver fusionSolver_
const size_t shape(const size_t) const
Get the shape in one dimension.
Discrete space in which all variables have the same number of labels.
ValueType evaluate(ITERATOR) const
evaluate the modeled function for a given labeling
void printArg(const std::vector< LabelType > arg)
void reserveFactors(const size_t numF)
bool doMoveHierachicalClustering(const MapType &accWeights, const std::vector< LabelType > &ab, const IndexType numNewVar, const std::vector< LabelType > &a, const std::vector< LabelType > &b, std::vector< LabelType > &res, const ValueType valA, const ValueType valB, ValueType &valRes)
std::vector< bool > allowCutsWithin_
detail_types::UInt64Type UInt64Type
uint64
MapType::const_iterator MapCIter
PermutableLabelFusionMove(const GraphicalModelType &gm, const Parameter ¶m=Parameter())
void mergeEdges(const Edge &a, const Edge &b)
PottsFunction< ValueType, IndexType, LabelType > PFunction
Parameter(const FusionSolver fusionSolver=SelfType::DefaultSolver, const bool planar=false, const std::string workflow=std::string(), const int nThreads=1, const bool decompose=false, const std::vector< bool > &allowCutsWithin=std::vector< bool >())
bool doMoveBase(const MapType &accWeights, const std::vector< LabelType > &ab, const IndexType numNewVar, const std::vector< LabelType > &a, const std::vector< LabelType > &b, std::vector< LabelType > &res, const ValueType valA, const ValueType valB, ValueType &valRes)
WeightType contractionWeight()
get the edge weight of the edge which should be contracted next
bool doMoveMulticut(const MapType &accWeights, const std::vector< LabelType > &ab, const IndexType numNewVar, const std::vector< LabelType > &a, const std::vector< LabelType > &b, std::vector< LabelType > &res, const ValueType valA, const ValueType valB, ValueType &valRes)
void reserveFactorsVarialbeIndices(const size_t size)
vigra::MergeGraphAdaptor< Graph > MergeGraph
bool doMoveMulticutNative(const MapType &accWeights, const std::vector< LabelType > &ab, const IndexType numNewVar, const std::vector< LabelType > &a, const std::vector< LabelType > &b, std::vector< LabelType > &res, const ValueType valA, const ValueType valB, ValueType &valRes)
bool doMoveCgc(const MapType &accWeights, const std::vector< LabelType > &ab, const IndexType numNewVar, const std::vector< LabelType > &a, const std::vector< LabelType > &b, std::vector< LabelType > &res, const ValueType valA, const ValueType valB, ValueType &valRes)
bool fuse(const LabelVector &argA, const LabelVector argB, LabelVector &argRes, const ValueType valA, const ValueType valB, ValueType &valRes)
ExplicitFunction< ValueType, IndexType, LabelType > EFunction
std::map< UInt64Type, ValueType > MapType
#define OPENGM_CHECK_OP(A, OP, B, TXT)
Potts function for two variables.
std::vector< ValueType > & weights_
MapType::iterator MapIter
Disjoint set data structure with path compression.
bool fuse(const std::vector< LabelType > &a, const std::vector< LabelType > &b, std::vector< LabelType > &res, const ValueType valA, const ValueType valB, ValueType &valRes)
void eraseEdge(const Edge &edge)
bool fuseMmwc(const std::vector< LabelType > &a, const std::vector< LabelType > &b, std::vector< LabelType > &res, const ValueType valA, const ValueType valB, ValueType &valRes)
IndexType numberOfFactors() const
GraphicalModel< ValueType, Adder, OPENGM_TYPELIST_2(EFunction, PFunction), SubSpace > SubModel
Parameter(const float stopWeight=0.0)
bool fuseClassic(const std::vector< LabelType > &a, const std::vector< LabelType > &b, std::vector< LabelType > &res, const ValueType valA, const ValueType valB, ValueType &valRes)
vigra::ChangeablePriorityQueue< ValueType,std::greater< ValueType > > pq_