std::map<Crag::Node, Crag::Node> CragStackCombiner::copyNodes(const Crag& source, Crag& target) { std::map<Crag::Node, Crag::Node> nodeMap; for (Crag::NodeIt i(source); i != lemon::INVALID; ++i) { Crag::Node n = target.addNode(); ExplicitVolume<unsigned char> volume = source.getVolume(i); if (!volume.getBoundingBox().isZero()) target.getVolume(n) = volume; nodeMap[i] = n; } for (Crag::EdgeIt e(source); e != lemon::INVALID; ++e) { Crag::Node u = nodeMap[source.u(e)]; Crag::Node v = nodeMap[source.v(e)]; target.addAdjacencyEdge(u, v); } for (Crag::SubsetArcIt a(source); a != lemon::INVALID; ++a) { Crag::Node s = nodeMap[source.toRag(source.getSubsetGraph().source(a))]; Crag::Node t = nodeMap[source.toRag(source.getSubsetGraph().target(a))]; target.addSubsetArc(s, t); } return nodeMap; }
void CragStackCombiner::combine(const std::vector<Crag>& crags, Crag& crag) { LOG_USER(cragstackcombinerlog) << "combining CRAGs, " << (_requireBbOverlap ? "" : " do not ") << "require bounding box overlap" << std::endl; std::map<Crag::Node, Crag::Node> prevNodeMap; std::map<Crag::Node, Crag::Node> nextNodeMap; for (unsigned int z = 1; z < crags.size(); z++) { LOG_USER(cragstackcombinerlog) << "linking CRAG " << (z-1) << " and " << z << std::endl; if (z == 1) prevNodeMap = copyNodes(crags[0], crag); else prevNodeMap = nextNodeMap; nextNodeMap = copyNodes(crags[z], crag); std::vector<std::pair<Crag::Node, Crag::Node>> links = findLinks(crags[z-1], crags[z]); for (const auto& pair : links) crag.addAdjacencyEdge( prevNodeMap[pair.first], nextNodeMap[pair.second]); } }
std::set<Crag::CragNode> AdjacencyAnnotator::recurseAdjacencies(Crag& crag, Crag::CragNode n) { LOG_ALL(adjacencyannotatorlog) << "recursing into node " << crag.id(n) << std::endl; // get all leaf subnodes std::set<Crag::CragNode> subnodes; for (Crag::CragArc a : crag.inArcs(n)) { std::set<Crag::CragNode> a_subnodes = recurseAdjacencies(crag, a.source()); for (Crag::CragNode s : a_subnodes) subnodes.insert(s); } // for each leaf subnode adjacent to a non-subnode, add an adjacency edge to // the non-subnode std::set<Crag::CragNode> neighbors; LOG_ALL(adjacencyannotatorlog) << "subnodes of " << crag.id(n) << " are:" << std::endl; for (Crag::CragNode s : subnodes) { LOG_ALL(adjacencyannotatorlog) << "\t" << crag.id(s) << std::endl; for (Crag::CragEdge e : crag.adjEdges(s)) { Crag::CragNode neighbor = e.opposite(s); // not a subnode if (!subnodes.count(neighbor)) neighbors.insert(neighbor); } } for (Crag::CragNode neighbor : neighbors) { LOG_ALL(adjacencyannotatorlog) << "adding propagated edge between " << crag.id(n) << " and " << crag.id(neighbor) << std::endl; crag.addAdjacencyEdge(n, neighbor); } _numAdded += neighbors.size(); subnodes.insert(n); LOG_ALL(adjacencyannotatorlog) << "leaving node " << crag.id(n) << std::endl; return subnodes; }
void PlanarAdjacencyAnnotator::annotate(Crag& crag) { if (optionCragType.as<std::string>() == "empty") return; UTIL_TIME_METHOD; util::box<float, 3> cragBB = crag.getBoundingBox(); util::point<float, 3> resolution; for (Crag::NodeIt n(crag); n != lemon::INVALID; ++n) { if (!crag.isLeafNode(n)) continue; resolution = crag.getVolume(n).getResolution(); break; } // no nodes? if (resolution.isZero()) return; // create a vigra multi-array large enough to hold all volumes vigra::MultiArray<3, int> ids( vigra::Shape3( cragBB.width() /resolution.x(), cragBB.height()/resolution.y(), cragBB.depth() /resolution.z()), std::numeric_limits<int>::max()); for (Crag::NodeIt n(crag); n != lemon::INVALID; ++n) { if (!crag.isLeafNode(n)) continue; const util::point<float, 3>& volumeOffset = crag.getVolume(n).getOffset(); const util::box<unsigned int, 3>& volumeDiscreteBB = crag.getVolume(n).getDiscreteBoundingBox(); util::point<unsigned int, 3> begin = (volumeOffset - cragBB.min())/resolution; util::point<unsigned int, 3> end = begin + util::point<unsigned int, 3>( volumeDiscreteBB.width(), volumeDiscreteBB.height(), volumeDiscreteBB.depth()); vigra::combineTwoMultiArrays( crag.getVolume(n).data(), ids.subarray( vigra::Shape3( begin.x(), begin.y(), begin.z()), vigra::Shape3( end.x(), end.y(), end.z())), ids.subarray( vigra::Shape3( begin.x(), begin.y(), begin.z()), vigra::Shape3( end.x(), end.y(), end.z())), vigra::functor::ifThenElse( vigra::functor::Arg1() == vigra::functor::Param(1), vigra::functor::Param(crag.id(n)), vigra::functor::Arg2() )); } //vigra::exportImage( //ids.bind<2>(0), //vigra::ImageExportInfo("debug/ids.tif")); typedef vigra::GridGraph<3> GridGraphType; typedef vigra::AdjacencyListGraph RagType; GridGraphType grid( ids.shape(), _neighborhood == Direct ? vigra::DirectNeighborhood : vigra::IndirectNeighborhood); RagType rag; RagType::EdgeMap<std::vector<GridGraphType::Edge>> affiliatedEdges; vigra::makeRegionAdjacencyGraph( grid, ids, rag, affiliatedEdges, std::numeric_limits<int>::max()); unsigned int numAdded = 0; crag.setGridGraph(grid); for (RagType::EdgeIt e(rag); e != lemon::INVALID; ++e) { int u = rag.id(rag.u(*e)); int v = rag.id(rag.v(*e)); Crag::Edge newEdge = crag.addAdjacencyEdge( crag.nodeFromId(u), crag.nodeFromId(v)); crag.setAffiliatedEdges( newEdge, affiliatedEdges[*e]); numAdded++; LOG_ALL(planaradjacencyannotatorlog) << "adding leaf node adjacency between " << u << " and " << v << std::endl; } LOG_USER(planaradjacencyannotatorlog) << "added " << numAdded << " leaf node adjacency edges" << std::endl; if (optionCragType.as<std::string>() == "full") propagateLeafAdjacencies(crag); }
void closed_set_solver() { /** * Subsets: * n7 * / \ * / \ * / \ * n5 n6 * / \ / \ * n1 n2 n3 n4 * * Adjacencies: * n7 * * * d * n5--------n6 * \ / * * e \ / f * * / \ * n1---n2----n3---n4 * a b c */ Crag crag; Crag::CragNode n1 = crag.addNode(); Crag::CragNode n2 = crag.addNode(); Crag::CragNode n3 = crag.addNode(); Crag::CragNode n4 = crag.addNode(); Crag::CragNode n5 = crag.addNode(); Crag::CragNode n6 = crag.addNode(); Crag::CragNode n7 = crag.addNode(); crag.addSubsetArc(n1, n5); crag.addSubsetArc(n2, n5); crag.addSubsetArc(n3, n6); crag.addSubsetArc(n4, n6); crag.addSubsetArc(n5, n7); crag.addSubsetArc(n6, n7); Crag::CragEdge a = crag.addAdjacencyEdge(n1, n2); Crag::CragEdge b = crag.addAdjacencyEdge(n2, n3); Crag::CragEdge c = crag.addAdjacencyEdge(n3, n4); Crag::CragEdge d = crag.addAdjacencyEdge(n5, n6); Crag::CragEdge e = crag.addAdjacencyEdge(n5, n3); Crag::CragEdge f = crag.addAdjacencyEdge(n2, n6); ClosedSetSolver solver(crag); CragSolution x(crag); ClosedSetSolver::Status status; { Costs costs(crag); costs.node[n7] = -1; solver.setCosts(costs); status = solver.solve(x); BOOST_CHECK_EQUAL(status, ClosedSetSolver::SolutionFound); // everything should be turned on for (Crag::CragNode n : crag.nodes()) BOOST_CHECK(x.selected(n)); for (Crag::CragEdge e : crag.edges()) BOOST_CHECK(x.selected(e)); } { Costs costs(crag); costs.node[n7] = 1; costs.edge[d] = -1; solver.setCosts(costs); status = solver.solve(x); BOOST_CHECK_EQUAL(status, ClosedSetSolver::SolutionFound); // everything except n7 should be turned on for (Crag::CragNode n : crag.nodes()) BOOST_CHECK(n != n7 ? x.selected(n) : !x.selected(n)); for (Crag::CragEdge e : crag.edges()) BOOST_CHECK(x.selected(e)); } }
void crag_iterators() { Crag crag; int numNodes = 10; for (int i = 0; i < numNodes; i++) crag.addNode(); int numEdges = 0; for (int i = 0; i < numNodes; i++) for (int j = 0; j < numNodes; j++) if (rand() > RAND_MAX/2) { crag.addAdjacencyEdge( crag.nodeFromId(i), crag.nodeFromId(j)); numEdges++; } int numArcs = 0; for (int i = 0; i < numNodes; i += 5) { for (int j = i; j < i + 4; j++) { crag.addSubsetArc( crag.nodeFromId(j), crag.nodeFromId(j+1)); numArcs++; } } BOOST_CHECK_EQUAL(crag.nodes().size(), numNodes); BOOST_CHECK_EQUAL(crag.edges().size(), numEdges); BOOST_CHECK_EQUAL(crag.arcs().size(), numArcs); numNodes = 0; { //UTIL_TIME_SCOPE("crag node old-school iterator"); //for (int j = 0; j < 1e8; j++) for (Crag::CragNodeIterator i = crag.nodes().begin(); i != crag.nodes().end(); i++) numNodes++; } { //UTIL_TIME_SCOPE("crag node iterator"); //for (int j = 0; j < 1e8; j++) for (Crag::CragNode n : crag.nodes()) { dontWarnMeAboutUnusedVar(n); numNodes++; } } { //UTIL_TIME_SCOPE("lemon node iterator"); //for (int j = 0; j < 1e8; j++) for (Crag::NodeIt n(crag); n != lemon::INVALID; ++n) numNodes -= 2; } BOOST_CHECK_EQUAL(numNodes, 0); numEdges = 0; for (Crag::CragEdge e : crag.edges()) { dontWarnMeAboutUnusedVar(e); numEdges++; } for (Crag::EdgeIt e(crag); e != lemon::INVALID; ++e) numEdges--; BOOST_CHECK_EQUAL(numEdges, 0); numArcs = 0; for (Crag::CragArc a : crag.arcs()) { dontWarnMeAboutUnusedVar(a); numArcs++; } for (Crag::SubsetArcIt a(crag); a != lemon::INVALID; ++a) numArcs--; BOOST_CHECK_EQUAL(numArcs, 0); for (Crag::CragNode n : crag.nodes()) { int numAdjEdges = 0; for (Crag::IncEdgeIt e(crag, n); e != lemon::INVALID; ++e) numAdjEdges++; BOOST_CHECK_EQUAL(crag.adjEdges(n).size(), numAdjEdges); for (Crag::CragEdge e : crag.adjEdges(n)) { dontWarnMeAboutUnusedVar(e); numAdjEdges--; } BOOST_CHECK_EQUAL(numAdjEdges, 0); int numInArcs = 0; for (Crag::SubsetInArcIt a(crag, crag.toSubset(n)); a != lemon::INVALID; ++a) numInArcs++; BOOST_CHECK_EQUAL(numInArcs, crag.inArcs(n).size()); for (Crag::CragArc a : crag.inArcs(n)) { dontWarnMeAboutUnusedVar(a); numInArcs--; } BOOST_CHECK_EQUAL(numInArcs, 0); int numOutArcs = 0; for (Crag::SubsetOutArcIt a(crag, crag.toSubset(n)); a != lemon::INVALID; ++a) numOutArcs++; BOOST_CHECK_EQUAL(numOutArcs, crag.outArcs(n).size()); for (Crag::CragArc a : crag.outArcs(n)) { dontWarnMeAboutUnusedVar(a); numOutArcs--; } BOOST_CHECK_EQUAL(numOutArcs, 0); Crag::CragEdgeIterator cei = crag.edges().begin(); Crag::EdgeIt ei(crag); while (ei != lemon::INVALID) { BOOST_CHECK((Crag::RagType::Node)((*cei).u()) == crag.getAdjacencyGraph().u(ei)); BOOST_CHECK((Crag::RagType::Node)((*cei).v()) == crag.getAdjacencyGraph().v(ei)); ++cei; ++ei; } Crag::CragArcIterator cai = crag.arcs().begin(); Crag::SubsetArcIt ai(crag); while (ai != lemon::INVALID) { BOOST_CHECK(crag.toSubset((*cai).source()) == crag.getSubsetGraph().source(ai)); BOOST_CHECK(crag.toSubset((*cai).target()) == crag.getSubsetGraph().target(ai)); ++cai; ++ai; } } }