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; }
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; }
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())); } }