void ImageReader::readImage() { // get information about the image to read vigra::ImageImportInfo info(_filename.c_str()); // abort if image is not grayscale if (!info.isGrayscale()) { UTIL_THROW_EXCEPTION( IOError, _filename << " is not a gray-scale image!"); } // allocate image _image = new Image(info.width(), info.height()); _image->setIdentifiyer(_filename); try { // read image importImage(info, vigra::destImage(*_image)); } catch (vigra::PostconditionViolation& e) { UTIL_THROW_EXCEPTION( IOError, "error reading " << _filename << ": " << e.what()); } if (strcmp(info.getPixelType(), "FLOAT") == 0) return; // scale image to [0..1] float factor; if (strcmp(info.getPixelType(), "UINT8") == 0) factor = 255.0; else { factor = 1.0; LOG_DEBUG(imagereaderlog) << _filename << " has pixel format " << info.getPixelType() << ", will not scale values" << std::endl; } vigra::transformImage( vigra::srcImageRange(*_image), vigra::destImage(*_image), vigra::linearIntensityTransform<float>(1.0/factor)); }
/** * Read the variables and their corresponding segment hashes from the given * file. */ std::vector<SegmentHash> readVariables(const std::string& filename) { std::vector<SegmentHash> hashes; std::ifstream labelsfile(filename.c_str()); std::string line; while(std::getline(labelsfile, line)) { std::stringstream linestream(line); bool defaultValue; linestream >> defaultValue; char hashSymbol; linestream >> hashSymbol; if (hashSymbol != '#') UTIL_THROW_EXCEPTION( IOError, "line '" << line << "' does not have valid syntax (expected '#', got '" << hashSymbol << "'"); SegmentHash hash; linestream >> hash; hashes.push_back(hash); } return hashes; }
/** * Read the coefficients of each segment from the given file. */ std::map<SegmentHash, double> readCoefficients(const std::string& filename) { std::map<SegmentHash, double> coefficients; std::ifstream coefsfile(filename.c_str()); while (coefsfile.good()) { std::string line; std::getline(coefsfile, line); std::stringstream linestream(line); std::string varname; linestream >> varname; // first line or comment or empty or constant if (varname == "numVar" || varname == "constant" || varname.find_first_of('#') == 0 || varname.empty()) continue; double coef; linestream >> coef; char hashSymbol; linestream >> hashSymbol; if (hashSymbol != '#') UTIL_THROW_EXCEPTION( IOError, "line '" << line << "' does not have valid syntax (expected '#', got '" << hashSymbol << "'"); SegmentHash hash; linestream >> hash; double gs; linestream >> gs; double fs; linestream >> fs; double fm; linestream >> fm; double fp; linestream >> fp; double fn; linestream >> fn; double weightSplits = optionWeightSplits.as<double>(); double weightMerges = optionWeightMerges.as<double>(); // Initial factor accounts for sign depending on if the segment is part of the goldstandard. coefficients[hash] = (-2*gs + 1) * ( weightSplits * (fs + fp) + weightMerges * (fm + fn) ); } return coefficients; }
MultiInput& ProcessNode::getMultiInput(unsigned int i) { if (_multiInputs.size() <= i) UTIL_THROW_EXCEPTION( NotEnoughInputs, "invalid multi-input number " << i << ", this process node has only " << _multiInputs.size() << " multi-inputs"); return *_multiInputs[i]; }
void Oracle::operator()( const std::vector<double>& weights, double& value, std::vector<double>& gradient) { updateCosts(weights); MultiCut::Status status = _mostViolatedMulticut.solve(); std::stringstream filename; filename << "most-violated_" << std::setw(6) << std::setfill('0') << _iteration << ".tif"; _mostViolatedMulticut.storeSolution(filename.str(), true); if (status != MultiCut::SolutionFound) UTIL_THROW_EXCEPTION( Exception, "solution not found"); value = _constant - _mostViolatedMulticut.getValue(); // value = E(y',w) - E(y*,w) + Δ(y',y*) // = B_c - <wΦ,y*> + <Δ_l,y*> + Δ_c // loss = value - B_c + <wΦ,y*> // margin = value - loss double mostViolatedEnergy = 0; for (Crag::NodeIt n(_crag); n != lemon::INVALID; ++n) if (_mostViolatedMulticut.getSelectedRegions()[n]) mostViolatedEnergy += nodeCost(weights, _nodeFeatures[n]); for (Crag::EdgeIt e(_crag); e != lemon::INVALID; ++e) if (_mostViolatedMulticut.getMergedEdges()[e]) mostViolatedEnergy += edgeCost(weights, _edgeFeatures[e]); double loss = value - _B_c + mostViolatedEnergy; double margin = value - loss; LOG_USER(oraclelog) << "Δ(y*) = " << loss << std::endl; LOG_USER(oraclelog) << "E(y') - E(y*) = " << margin << std::endl; accumulateGradient(gradient); if (optionStoreEachCurrentlyBest) { _currentBestMulticut.solve(); std::stringstream filename; filename << "current-best_" << std::setw(6) << std::setfill('0') << _iteration << ".tif"; _currentBestMulticut.storeSolution(filename.str(), true); } _iteration++; }
OutputBase& ProcessNode::getOutput(unsigned int i) { if (_outputs.size() <= i) { UTIL_THROW_EXCEPTION( NotEnoughOutputs, "invalid output number " << i << ", this process node has only " << _outputs.size() << " outputs"); } return *_outputs[i]; }
int main(int argc, char** argv) { try { util::ProgramOptions::init(argc, argv); logger::LogManager::init(); pipeline::Process<ImageStackDirectoryReader> intensityReader(optionIntensities.as<std::string>()); pipeline::Process<ImageStackDirectoryReader> labelReader(optionLabels.as<std::string>()); pipeline::Value<ImageStack> intensityStack = intensityReader->getOutput(); pipeline::Value<ImageStack> labelStack = labelReader->getOutput(); if (optionExtractLabels) { LOG_DEBUG(logger::out) << "[main] extracting labels from connected components" << std::endl; pipeline::Process<ExtractLabels> extractLabels; extractLabels->setInput(labelReader->getOutput()); labelStack = extractLabels->getOutput(); } unsigned int width = labelStack->width(); unsigned int height = labelStack->height(); unsigned int depth = labelStack->size(); if (width != intensityStack->width() || height != intensityStack->height() || depth != intensityStack->size()) UTIL_THROW_EXCEPTION( UsageError, "intensity and label stacks have different sizes"); // create volumes from stacks ExplicitVolume<float> intensities(*intensityStack); ExplicitVolume<int> labels(*labelStack); intensities.normalize(); // store them in the project file boost::filesystem::remove(optionProjectFile.as<std::string>()); Hdf5VolumeStore volumeStore(optionProjectFile.as<std::string>()); volumeStore.saveIntensities(intensities); volumeStore.saveLabels(labels); } catch (boost::exception& e) { handleException(e, std::cerr); } }
MultiInput& ProcessNode::getMultiInput(std::string name) { if (!_multiInputNames.count(name)) { UTIL_THROW_EXCEPTION( NoSuchInput, "no such input: " << name); } else { return *_multiInputNames[name]; } }
int IlpSolver::level(NodeId n) { std::size_t lowest_var_num = n*_num_levels; if (_solution[lowest_var_num] < 0.5) UTIL_THROW_EXCEPTION( Exception, "no level was selected for node " << n); for (int l = 1; l < _num_levels; l++) if (_solution[lowest_var_num + l] < 0.5) return l-1; return _num_levels - 1; }
OutputBase& ProcessNode::getOutput(std::string name) { PIPELINE_LOG_ALL(pipelinelog) << "[ProcessNode] searching for output with name " << name << std::endl; if (!_outputNames.count(name)) { UTIL_THROW_EXCEPTION( NoSuchOutput, "no such output: " << name); } else { return *_outputNames[name]; } }
void Sopnet::createPipeline() { LOG_DEBUG(sopnetlog) << "creating pipeline" << std::endl; if (!_neuronSlices.isSet() && !_neuronSliceStackDirectories.isSet()) UTIL_THROW_EXCEPTION( UsageError, "either an image stack of slices or a list of directory names has to be set as 'neuron slices' or 'neuron slice stack directories'"); createBasicPipeline(); createInferencePipeline(); if (_groundTruth.isSet()) createTrainingPipeline(); _pipelineCreated = true; }
IlpSolver::NodeId IlpSolver::add_nodes(std::size_t num_nodes) { if (num_nodes < 1) UTIL_THROW_EXCEPTION( UsageError, "at least one node has to be added with a call to add_nodes"); _num_nodes += num_nodes; NodeId first = _graph.id(_graph.addNode()); num_nodes--; for (std::size_t i = 0; i < num_nodes; i++) _graph.addNode(); return first; }
void QuadraticSolver::solve() { double value; std::string message; if (_solver->solve(*_solution, value, message)) { LOG_USER(quadraticsolverlog) << "optimal solution found" << std::endl; } else { LOG_ERROR(quadraticsolverlog) << "error: " << message << std::endl; UTIL_THROW_EXCEPTION(NoSolutionException, message); } }
void Skeletonize::findRoot() { _dijkstra.run(_center); // find furthest point on boundary _root = GraphVolume::NodeIt(_graphVolume.graph()); float maxValue = -1; for (GraphVolume::Node n : _boundary) { if (_dijkstra.distMap()[n] > maxValue) { _root = n; maxValue = _dijkstra.distMap()[n]; } } if (maxValue == -1) UTIL_THROW_EXCEPTION( NoNodeFound, "could not find a root boundary point"); // mark root as being part of skeleton _nodeLabels[_root] = OnSkeleton; }
return boost::make_shared<SegmentConstraints>(); } std::vector<double> LocalSegmentStore::getFeatureWeights() { return _weights; } void LocalSegmentStore::storeSegmentCosts( const std::map<SegmentHash, double>& /*costs*/) { UTIL_THROW_EXCEPTION( NotYetImplemented, "LocalSegmentStore does not yet store segment costs.") } void LocalSegmentStore::storeSolution( const std::vector<std::set<SegmentHash> >& assemblies, const Core& core) { _solutions[core] = assemblies; } std::vector<std::set<SegmentHash> > LocalSegmentStore::getSolutionByCores( const Cores& cores) {
double IlpSolver::min_surface(const Parameters& parameters) { std::size_t num_vars = _num_nodes*_num_levels; LOG_DEBUG(ilpsolverlog) << "creating objective for " << num_vars << " binary variables" << std::endl; LinearObjective objective(num_vars); LOG_DEBUG(ilpsolverlog) << "setting objective coefficients" << std::endl; for (GraphType::NodeIt n(_graph); n != lemon::INVALID; ++n) { double sum = 0; for (int l = 0; l < _num_levels; l++) { std::size_t var_num = _graph.id(n)*_num_levels + l; double costs = _level_costs[n][l]; double accumulated_costs = costs - sum; sum += accumulated_costs; objective.setCoefficient(var_num, accumulated_costs); } } LinearConstraints constraints; // pick at least lowest level LOG_DEBUG(ilpsolverlog) << "adding indicator constraints" << std::endl; for (GraphType::NodeIt n(_graph); n != lemon::INVALID; ++n) { std::size_t var_num = _graph.id(n)*_num_levels; LinearConstraint indicator; indicator.setCoefficient(var_num, 1.0); indicator.setRelation(Equal); indicator.setValue(1.0); constraints.add(indicator); } // column inclusion constraints LOG_DEBUG(ilpsolverlog) << "adding column inclusion constraints" << std::endl; for (GraphType::NodeIt n(_graph); n != lemon::INVALID; ++n) { for (int l = 1; l < _num_levels; l++) { std::size_t upper_var_num = _graph.id(n)*_num_levels + l; std::size_t lower_var_num = _graph.id(n)*_num_levels + l - 1; LinearConstraint inclusion; inclusion.setCoefficient(upper_var_num, 1.0); inclusion.setCoefficient(lower_var_num, -1.0); inclusion.setRelation(LessEqual); inclusion.setValue(0.0); constraints.add(inclusion); } } // gradient constraints LOG_DEBUG(ilpsolverlog) << "adding gradient constraints" << std::endl; for (GraphType::EdgeIt e(_graph); e != lemon::INVALID; ++e) { GraphType::Node u = _graph.u(e); GraphType::Node v = _graph.v(e); for (auto& p : { std::make_pair(u, v), std::make_pair(v, u) }) { GraphType::Node u_ = p.first; GraphType::Node v_ = p.second; for (int l = _max_gradients[e]; l < _num_levels; l++) { std::size_t upper_var_num = _graph.id(u_)*_num_levels + l; std::size_t lower_var_num = _graph.id(v_)*_num_levels + l - _max_gradients[e]; LinearConstraint inclusion; inclusion.setCoefficient(upper_var_num, 1.0); inclusion.setCoefficient(lower_var_num, -1.0); inclusion.setRelation(LessEqual); inclusion.setValue(0.0); constraints.add(inclusion); } } } if (parameters.enforce_zero_minimum) { LOG_USER(ilpsolverlog) << "enforcing minima of zero" << std::endl; if (parameters.num_neighbors < 0) UTIL_THROW_EXCEPTION( UsageError, "if 'enforce_zero_minimum' is set, 'num_neighbors' has to be set, too."); // for each indicator between 1 and _num_levels - 1: if top indicator t // is 0, one of the neighbors n ∈ N must be zero, too: // // t=0 ⇒ Σn<|N| // // Σn - t ≤ |N| - 1 if t=0, one of neighbors has to be 0 // if t=1, constraint always true for (GraphType::NodeIt n(_graph); n != lemon::INVALID; ++n) { for (int l = 1; l < _num_levels - 1; l++) { LinearConstraint zero_minimum; // Σn for (GraphType::IncEdgeIt e(_graph, n); e != lemon::INVALID; ++e) { GraphType::Node nb = _graph.oppositeNode(n, e); std::size_t nb_var_num = _graph.id(nb)*_num_levels + l; zero_minimum.setCoefficient(nb_var_num, 1.0); } // -t std::size_t t_var_num = _graph.id(n)*_num_levels + l + 1; zero_minimum.setCoefficient(t_var_num, -1.0); // ≤ |N| - 1 zero_minimum.setRelation(LessEqual); zero_minimum.setValue(parameters.num_neighbors - 1); constraints.add(zero_minimum); } } } SolverFactory factory; _solver = std::unique_ptr<LinearSolverBackend>(factory.createLinearSolverBackend()); LOG_DEBUG(ilpsolverlog) << "initialize solver" << std::endl; if (parameters.solve_relaxed_problem) { _solver->initialize(num_vars, Continuous); // we have to force values to be within 0 and 1 for (std::size_t i = 0; i < num_vars; i++) { LinearConstraint lower_bound, upper_bound; lower_bound.setCoefficient(i, 1.0); lower_bound.setRelation(GreaterEqual); lower_bound.setValue(0.0); upper_bound.setCoefficient(i, 1.0); upper_bound.setRelation(LessEqual); upper_bound.setValue(1.0); constraints.add(lower_bound); constraints.add(upper_bound); } } else { _solver->initialize(num_vars, Binary); } LOG_DEBUG(ilpsolverlog) << "setting objective" << std::endl; _solver->setObjective(objective); LOG_DEBUG(ilpsolverlog) << "setting setting constraints" << std::endl; _solver->setConstraints(constraints); LOG_ALL(ilpsolverlog) << objective << std::endl; for (auto c : constraints) LOG_ALL(ilpsolverlog) << c << std::endl; LinearSolverBackend::Parameters solverParameters; solverParameters.numThreads = parameters.num_threads; solverParameters.verbose = parameters.verbose; LOG_DEBUG(ilpsolverlog) << "solving" << std::endl; std::string message; if (!_solver->solve(_solution, message, solverParameters)) UTIL_THROW_EXCEPTION( LinearSolverBackendException, "linear program could not be solved: " << message); LOG_ALL(ilpsolverlog) << _solution.getVector() << std::endl; return _solution.getValue(); }