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;
}
Exemple #2
0
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));
	}
}
Exemple #3
0
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);
}
Exemple #4
0
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;
		}
	}
}