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 create_crag() { // useful for later: // //boost::filesystem::path dataDir = dir_of(__FILE__); //boost::filesystem::path graphfile = dataDir/"star.dat"; Crag crag; // add 100 nodes for (int i = 0; i < 100; i++) crag.addNode(); // create chains of 10 nodes for (int i = 0; i < 100; i += 10) { for (int j = i+1; j < i + 10; j++) { Crag::Node u = crag.nodeFromId(j-1); Crag::Node v = crag.nodeFromId(j); crag.addSubsetArc(u, v); } } // check levels of nodes for (int i = 0; i < 100; i++) { Crag::Node n = crag.nodeFromId(i); BOOST_CHECK_EQUAL(crag.getLevel(n), i%10); if (i%10 == 0) BOOST_CHECK(crag.isLeafNode(n)); else BOOST_CHECK(!crag.isLeafNode(n)); if (i%10 == 9) BOOST_CHECK(crag.isRootNode(n)); else BOOST_CHECK(!crag.isRootNode(n)); } }
void hausdorff() { Crag cragA; Crag cragB; CragVolumes volumesA(cragA); CragVolumes volumesB(cragB); // add two nodes each Crag::Node a1 = cragA.addNode(); Crag::Node a2 = cragA.addNode(); Crag::Node b1 = cragB.addNode(); Crag::Node b2 = cragB.addNode(); // add more nodes as parents of a and b Crag::Node p_a1 = cragA.addNode(); Crag::Node p_b1 = cragB.addNode(); cragA.addSubsetArc(a1, p_a1); cragB.addSubsetArc(b1, p_b1); // add more nodes merging p_a1 and a2 (same for b) Crag::Node root_a = cragA.addNode(); Crag::Node root_b = cragB.addNode(); cragA.addSubsetArc(p_a1, root_a); cragA.addSubsetArc(a2, root_a); cragB.addSubsetArc(p_b1, root_b); cragB.addSubsetArc(b2, root_b); // create volumes std::shared_ptr<CragVolume> volumeA1 = std::make_shared<CragVolume>(11, 11, 1); std::shared_ptr<CragVolume> volumeA2 = std::make_shared<CragVolume>(11, 11, 1); std::shared_ptr<CragVolume> volumeB1 = std::make_shared<CragVolume>(11, 11, 1); std::shared_ptr<CragVolume> volumeB2 = std::make_shared<CragVolume>(11, 11, 1); volumeA2->setOffset(util::point<float, 3>(5, 5, 0)); volumeB2->setOffset(util::point<float, 3>(5, 5, 0)); volumeA1->data() = 0; volumeA2->data() = 0; volumeB1->data() = 0; volumeB2->data() = 0; // add a stripe for volumeA{1,2} and a dot for volumeB{1,2} // // 00000000000 00000000000 // 00000000000 00000000000 // 00000000000 00000000000 // 00000000x00 00000000*00 x=8,y=3 // 00000000000 00000000000 // *********** xxxxxxxxxxx y=5 // 00000000000 00000000000 // 00000000000 00000000000 // 00000000000 00000000000 // 00000000000 00000000000 // 00000000000 00000000000 for (int x = 0; x < 11; x++) { (*volumeA1)(x, 5, 0) = 1; (*volumeA2)(x, 5, 0) = 1; } (*volumeB1)(8, 3, 0) = 1; (*volumeB2)(8, 3, 0) = 1; volumesA.setVolume(a1, volumeA1); volumesA.setVolume(a2, volumeA2); volumesB.setVolume(b1, volumeB1); volumesB.setVolume(b2, volumeB2); volumesA.fillEmptyVolumes(); volumesB.fillEmptyVolumes(); HausdorffDistance hausdorff(100); double a_b, b_a; hausdorff(*volumesA[a1], *volumesB[b1], a_b, b_a); // Hausdorff should be sqrt(2*2 + 8*8) = 8.25 for A->B and 2 for B->A BOOST_CHECK_CLOSE(a_b, 8.246, 0.01); BOOST_CHECK_CLOSE(b_a, 2.0, 0.01); // same for parents hausdorff(*volumesA[p_a1], *volumesB[p_b1], a_b, b_a); BOOST_CHECK_CLOSE(a_b, 8.246, 0.01); BOOST_CHECK_CLOSE(b_a, 2.0, 0.01); // between a1 and b2, the distances should be sqrt(3*3 + 13*13) = 13.342 // A->B and sqrt(3*3 + 3*3) = 4.243 for B->A hausdorff(*volumesA[a1], *volumesB[b2], a_b, b_a); BOOST_CHECK_CLOSE(a_b, 13.342, 0.01); BOOST_CHECK_CLOSE(b_a, 4.243, 0.01); // between root_a and root_b Hausdorff should be sqrt(2*2 + 8*8) = 8.25 for // A->B and 2 for B->A hausdorff(*volumesA[root_a], *volumesB[root_b], a_b, b_a); BOOST_CHECK_CLOSE(a_b, 8.246, 0.01); BOOST_CHECK_CLOSE(b_a, 2.0, 0.01); }
void hausdorff_anisotropic() { Crag cragA; Crag cragB; CragVolumes volumesA(cragA); CragVolumes volumesB(cragB); // add two nodes each Crag::Node a1 = cragA.addNode(); Crag::Node a2 = cragA.addNode(); Crag::Node b1 = cragB.addNode(); Crag::Node b2 = cragB.addNode(); // add more nodes as parents of a and b Crag::Node p_a1 = cragA.addNode(); Crag::Node p_b1 = cragB.addNode(); cragA.addSubsetArc(a1, p_a1); cragB.addSubsetArc(b1, p_b1); // add more nodes merging p_a1 and a2 (same for b) Crag::Node root_a = cragA.addNode(); Crag::Node root_b = cragB.addNode(); cragA.addSubsetArc(p_a1, root_a); cragA.addSubsetArc(a2, root_a); cragB.addSubsetArc(p_b1, root_b); cragB.addSubsetArc(b2, root_b); // create volumes std::shared_ptr<CragVolume> volumeA1 = std::make_shared<CragVolume>(11, 11, 1); std::shared_ptr<CragVolume> volumeA2 = std::make_shared<CragVolume>(11, 11, 1); std::shared_ptr<CragVolume> volumeB1 = std::make_shared<CragVolume>(11, 11, 1); std::shared_ptr<CragVolume> volumeB2 = std::make_shared<CragVolume>(11, 11, 1); volumeA2->setOffset(util::point<float, 3>(5, 6, 0)); volumeB2->setOffset(util::point<float, 3>(5, 6, 0)); volumeA1->setResolution(util::point<float, 3>(1, 2, 1)); volumeA2->setResolution(util::point<float, 3>(1, 2, 1)); volumeB1->setResolution(util::point<float, 3>(1, 2, 1)); volumeB2->setResolution(util::point<float, 3>(1, 2, 1)); volumeA1->data() = 0; volumeA2->data() = 0; volumeB1->data() = 0; volumeB2->data() = 0; // add a stripe for volumeA{1,2} and a dot for volumeB{1,2} // // 00000000000 00000000000 // 00000000000 00000000000 // 00000000000 00000000000 // 00000000x00 00000000*00 x=8,y=3 // 00000000000 00000000000 // *********** xxxxxxxxxxx y=5 // 00000000000 00000000000 * x=13,y=6 // 00000000000 00000000000 // 00000000000 00000xxxxxxxxxxx // 00000000000 00000000000 // 00000000000 00000000000 for (int x = 0; x < 11; x++) { (*volumeA1)(x, 5, 0) = 1; (*volumeA2)(x, 5, 0) = 1; } (*volumeB1)(8, 3, 0) = 1; (*volumeB2)(8, 3, 0) = 1; volumesA.setVolume(a1, volumeA1); volumesA.setVolume(a2, volumeA2); volumesB.setVolume(b1, volumeB1); volumesB.setVolume(b2, volumeB2); volumesA.fillEmptyVolumes(); volumesB.fillEmptyVolumes(); { HausdorffDistance hausdorff(100); double a_b, b_a; hausdorff(*volumesA[a1], *volumesB[b1], a_b, b_a); BOOST_CHECK_CLOSE(a_b, sqrt(4*4 + 8*8), 0.01); BOOST_CHECK_CLOSE(b_a, sqrt(4*4), 0.01); // same for parents hausdorff(*volumesA[p_a1], *volumesB[p_b1], a_b, b_a); BOOST_CHECK_CLOSE(a_b, sqrt(4*4 + 8*8), 0.01); BOOST_CHECK_CLOSE(b_a, sqrt(4*4), 0.01); // b2 is offset by (5,6), which corresponds (5,3) pixels // // between a1 and b2, the distances should be sqrt(13*13 + 10*10) A->B and // sqrt(3*3 + 3*3) = 4.243 for B->A hausdorff(*volumesA[a1], *volumesB[b2], a_b, b_a); BOOST_CHECK_CLOSE(a_b, sqrt(13*13 + 2*2), 0.01); BOOST_CHECK_CLOSE(b_a, sqrt(3*3 + 2*2), 0.01); // between root_a and root_b Hausdorff should be sqrt(2*2 + 16*16) for A->B // and 4 for B->A hausdorff(*volumesA[root_a], *volumesB[root_b], a_b, b_a); BOOST_CHECK_CLOSE(a_b, sqrt(4*4 + 8*8), 0.01); BOOST_CHECK_CLOSE(b_a, sqrt(4*4), 0.01); } { HausdorffDistance hausdorff(10); double a_b, b_a; hausdorff(*volumesA[a1], *volumesB[b1], a_b, b_a); BOOST_CHECK_CLOSE(a_b, std::min(10.0, sqrt(4*4 + 8*8)), 0.01); BOOST_CHECK_CLOSE(b_a, std::min(10.0, sqrt(4*4)), 0.01); // same for parents hausdorff(*volumesA[p_a1], *volumesB[p_b1], a_b, b_a); BOOST_CHECK_CLOSE(a_b, std::min(10.0, sqrt(4*4 + 8*8)), 0.01); BOOST_CHECK_CLOSE(b_a, std::min(10.0, sqrt(4*4)), 0.01); // b2 is offset by (5,6), which corresponds (5,3) pixels // // between a1 and b2, the distances should be sqrt(13*13 + 10*10) A->B and // sqrt(3*3 + 3*3) = 4.243 for B->A hausdorff(*volumesA[a1], *volumesB[b2], a_b, b_a); BOOST_CHECK_CLOSE(a_b, std::min(10.0, sqrt(13*13 + 2*2)), 0.01); BOOST_CHECK_CLOSE(b_a, std::min(10.0, sqrt(3*3 + 2*2)), 0.01); // between root_a and root_b Hausdorff should be sqrt(2*2 + 16*16) for A->B // and 4 for B->A hausdorff(*volumesA[root_a], *volumesB[root_b], a_b, b_a); BOOST_CHECK_CLOSE(a_b, std::min(10.0, sqrt(4*4 + 8*8)), 0.01); BOOST_CHECK_CLOSE(b_a, std::min(10.0, sqrt(4*4)), 0.01); } }
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; } } }