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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
int main(int argc, char** argv) {

	try {

		util::ProgramOptions::init(argc, argv);
		logger::LogManager::init();

		Hdf5CragStore   cragStore(optionProjectFile.as<std::string>());
		Hdf5VolumeStore volumeStore(optionProjectFile.as<std::string>());

		Crag crag;
		cragStore.retrieveCrag(crag);

		NodeFeatures nodeFeatures(crag);
		EdgeFeatures edgeFeatures(crag);

		LOG_USER(logger::out) << "reading features" << std::endl;
		cragStore.retrieveNodeFeatures(crag, nodeFeatures);
		cragStore.retrieveEdgeFeatures(crag, edgeFeatures);

		BundleOptimizer::Parameters parameters;
		parameters.lambda      = optionRegularizerWeight;
		parameters.epsStrategy = BundleOptimizer::EpsFromGap;
		BundleOptimizer optimizer(parameters);

		BestEffort*  bestEffort  = 0;
		OverlapLoss* overlapLoss = 0;

		if (optionBestEffortFromProjectFile) {

			LOG_USER(logger::out) << "reading best-effort" << std::endl;

			bestEffort = new BestEffort(crag);

			vigra::HDF5File project(
					optionProjectFile.as<std::string>(),
					vigra::HDF5File::OpenMode::ReadWrite);
			project.cd("best_effort");
			vigra::ArrayVector<int> beNodes;
			vigra::MultiArray<2, int> beEdges;
			project.readAndResize("nodes", beNodes);
			project.readAndResize("edges", beEdges);

			std::set<int> nodes;
			for (int n : beNodes)
				nodes.insert(n);

			std::set<std::pair<int, int>> edges;
			for (int i = 0; i < beEdges.shape(1); i++)
				edges.insert(
						std::make_pair(
							std::min(beEdges(i, 0), beEdges(i, 1)),
							std::max(beEdges(i, 0), beEdges(i, 1))));

			for (Crag::NodeIt n(crag); n != lemon::INVALID; ++n)
				bestEffort->node[n] = nodes.count(crag.id(n));

			for (Crag::EdgeIt e(crag); e != lemon::INVALID; ++e)
				bestEffort->edge[e] = edges.count(
						std::make_pair(
								std::min(crag.id(crag.u(e)), crag.id(crag.v(e))),
								std::max(crag.id(crag.u(e)), crag.id(crag.v(e)))));

		} else {

			LOG_USER(logger::out) << "reading ground-truth" << std::endl;
			ExplicitVolume<int> groundTruth;
			volumeStore.retrieveGroundTruth(groundTruth);

			LOG_USER(logger::out) << "finding best-effort solution" << std::endl;
			overlapLoss = new OverlapLoss(crag, groundTruth);
			bestEffort = new BestEffort(crag, *overlapLoss);
		}

		Loss* loss = 0;
		bool  destructLoss = false;

		if (optionLoss.as<std::string>() == "hamming") {

			LOG_USER(logger::out) << "using Hamming loss" << std::endl;

			loss = new HammingLoss(crag, *bestEffort);
			destructLoss = true;

		} else if (optionLoss.as<std::string>() == "overlap") {

			LOG_USER(logger::out) << "using overlap loss" << std::endl;

			if (!overlapLoss) {

				LOG_USER(logger::out) << "reading ground-truth" << std::endl;
				ExplicitVolume<int> groundTruth;
				volumeStore.retrieveGroundTruth(groundTruth);

				LOG_USER(logger::out) << "finding best-effort solution" << std::endl;
				overlapLoss = new OverlapLoss(crag, groundTruth);
			}

			loss = overlapLoss;

		} else {

			LOG_ERROR(logger::out)
					<< "unknown loss: "
					<< optionLoss.as<std::string>()
					<< std::endl;
			return 1;
		}

		if (optionNormalizeLoss) {

			LOG_USER(logger::out) << "normalizing loss..." << std::endl;
			loss->normalize(crag, MultiCut::Parameters());
		}

		Oracle oracle(
				crag,
				nodeFeatures,
				edgeFeatures,
				*loss,
				*bestEffort);

		std::vector<double> weights(nodeFeatures.dims() + edgeFeatures.dims(), 0);
		optimizer.optimize(oracle, weights);

		storeVector(weights, optionFeatureWeights);

		if (destructLoss && loss != 0)
			delete loss;

		if (overlapLoss)
			delete overlapLoss;

		if (bestEffort)
			delete bestEffort;

	} catch (boost::exception& e) {

		handleException(e, std::cerr);
	}
}
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
SolutionImageWriter::write(
		const Crag& crag,
		const CragVolumes& volumes,
		const CragSolution& solution,
		const std::string& basename,
		bool boundary) {

	LOG_DEBUG(solutionimagewriterlog) << "storing solution in " << basename << std::endl;

	if (_volumesBB.isZero())
		_volumesBB = volumes.getBoundingBox();

	LOG_DEBUG(solutionimagewriterlog) << "using bounding box of " << _volumesBB << std::endl;

	util::point<float, 3> resolution;
	for (Crag::CragNode n : crag.nodes()) {

		if (!crag.isLeafNode(n))
			continue;
		resolution = volumes[n]->getResolution();
		break;
	}

	LOG_DEBUG(solutionimagewriterlog) << "using resolution of " << resolution << std::endl;

	// create a vigra multi-array large enough to hold all volumes
	vigra::MultiArray<3, float> components(
			vigra::Shape3(
				_volumesBB.width() /resolution.x(),
				_volumesBB.height()/resolution.y(),
				_volumesBB.depth() /resolution.z()),
			std::numeric_limits<int>::max());

	// background for areas without candidates
	if (boundary)
		components = 0.25;
	else
		components = 0;

	for (Crag::CragNode n : crag.nodes()) {

		LOG_ALL(solutionimagewriterlog) << "drawing node " << crag.id(n) << std::endl;

		// draw only selected nodes
		if (!solution.selected(n))
			continue;

		const util::point<float, 3>&      volumeOffset     = volumes[n]->getOffset();
		const util::box<unsigned int, 3>& volumeDiscreteBB = volumes[n]->getDiscreteBoundingBox();

		util::point<unsigned int, 3> begin = (volumeOffset - _volumesBB.min())/resolution;
		util::point<unsigned int, 3> end   = begin +
				util::point<unsigned int, 3>(
						volumeDiscreteBB.width(),
						volumeDiscreteBB.height(),
						volumeDiscreteBB.depth());

		LOG_ALL(solutionimagewriterlog) << "\toffset      : " << volumeOffset << std::endl;
		LOG_ALL(solutionimagewriterlog) << "\tdiscrete bb : " << volumeDiscreteBB << std::endl;
		LOG_ALL(solutionimagewriterlog) << "\ttarget area : " << begin << " -- " << end << std::endl;

		// fill id of connected component
		vigra::combineTwoMultiArrays(
			volumes[n]->data(),
			components.subarray(TinyVector3UInt(&begin[0]),TinyVector3UInt(&end[0])),
			components.subarray(TinyVector3UInt(&begin[0]),TinyVector3UInt(&end[0])),
			vigra::functor::ifThenElse(
					vigra::functor::Arg1() == vigra::functor::Param(1),
					vigra::functor::Param(solution.label(n)),
					vigra::functor::Arg2()
		));
	}

	if (boundary) {

		// gray boundary for all leaf nodes
		for (Crag::CragNode n : crag.nodes())
			if (crag.isLeafNode(n))
				drawBoundary(volumes, n, components, 0.5);

		// black boundary for all selected nodes
		for (Crag::CragNode n : crag.nodes())
			if (solution.selected(n))
				drawBoundary(volumes, n, components, 0);
	}

	if (components.shape(2) > 1) {

		boost::filesystem::create_directory(basename);
		for (unsigned int z = 0; z < components.shape(2); z++) {

			std::stringstream ss;
			ss << std::setw(4) << std::setfill('0') << z;
			vigra::exportImage(
					components.bind<2>(z),
					vigra::ImageExportInfo((basename + "/" + ss.str() + ".tif").c_str()));
		}

	} else {

		vigra::exportImage(
				components.bind<2>(0),
				vigra::ImageExportInfo((basename + ".tif").c_str()));
	}
}