std::vector<std::pair<Crag::Node, Crag::Node>>
CragStackCombiner::findLinks(const Crag& a, const Crag& b) {

	UTIL_TIME_METHOD;

	HausdorffDistance hausdorff(a, b, 100);

	std::vector<std::pair<Crag::Node, Crag::Node>> links;

	for (Crag::NodeIt i(a); i != lemon::INVALID; ++i) {

		LOG_DEBUG(cragstackcombinerlog) << "checking for links of node " << a.id(i) << std::endl;

		for (Crag::NodeIt j(b); j != lemon::INVALID; ++j) {

			if (_requireBbOverlap) {

				util::box<float, 2> bb_i = a.getVolume(i).getBoundingBox().project<2>();
				util::box<float, 2> bb_j = b.getVolume(j).getBoundingBox().project<2>();

				if (!bb_i.intersects(bb_j))
					continue;
			}

			double i_j, j_i;
			hausdorff.distance(i, j, i_j, j_i);

			double distance = std::min(i_j, j_i);

			if (distance <= _maxDistance)
				links.push_back(std::make_pair(i, j));
		}
	}

	return links;
}
Exemple #2
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 #3
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);
	}
}
Exemple #4
0
double avg(Pixel3DSet & a, Pixel3DSet & b)
{
	return hausdorff(a, b);
}
Exemple #5
0
double avg(std::vector<ll_R3::R3> & a, std::vector<ll_R3::R3> & b)
{
	return hausdorff(a, b);
}