3#include "../trees/TreeAltitudeAlgorithms.hpp"
4#include "../trees/ValuedMorphologicalTree.hpp"
5#include "../trees/ValuedMorphologicalTreeView.hpp"
6#include "../trees/detail/TreeKernelAccess.hpp"
7#include "../trees/saliency/HierarchySaliencyMapValidation.hpp"
8#include "../trees/saliency/HierarchySaliencyMap.hpp"
9#include "../trees/saliency/HierarchicalWatershedSaliency.hpp"
10#include "../utils/Image.hpp"
11#include "../utils/Common.hpp"
12#include "../utils/Contract.hpp"
13#include "../contours/ContourComputation.hpp"
62 enum class Mode { TopK, MinimumExtinction };
65 Mode mode_ = Mode::TopK;
67 int extremaToKeep_ = 0;
69 Real threshold_ = Real{0};
95 policy.mode_ = Mode::MinimumExtinction;
127enum class ExtinctionContourScorePolicy {
231 throw std::invalid_argument(std::string(
context) +
" requires a non-null attribute buffer."));
246 throw std::invalid_argument(std::string(
context) +
" attribute size must match the internal node slot count."));
261 return view.nodeAltitudes()[
static_cast<std::size_t
>(nodeId)];
297 throw std::invalid_argument(std::string(
context) +
" requires a non-negative extremaToKeep value."));
309 throw std::invalid_argument(std::string(
context) +
" requires a finite extinction threshold."));
324 if (
policy.selectsTopK()) {
344 if (!std::isfinite(value)) {
345 throw std::invalid_argument(std::string(
context) +
" requires finite extinction values.");
347 if (value < Real{0}) {
348 throw std::invalid_argument(std::string(
context) +
" requires non-negative extinction values.");
375 for (
NodeId childId : detail::TreeKernelAccess::children(tree, nodeId)) {
399 HierarchyValuationPolicy::AllowLevelCollapse,
400 HierarchyValuationRangePolicy::RequireNonNegative,
context);
420 std::vector<const RegionalExtremaNode<Real>*>
records;
421 if (
policy.selectsTopK()) {
436 std::vector<SelectedExtremum>
selected;
469 std::stack<NodeId>
stack;
471 while (!
stack.empty()) {
475 for (
PixelId pixel : detail::TreeKernelAccess::properParts(tree, nodeId)) {
532 void initialize(
const Real*
attr) {
543 if (detail::TreeKernelAccess::numChildren(this->tree,
parentNodeId) > 1) {
567 if (a.extinction != b.extinction) {
568 return a.extinction > b.extinction;
570 if (
a.cutoffNode !=
b.cutoffNode) {
571 return a.cutoffNode < b.cutoffNode;
573 return a.leaf <
b.leaf;
618 view_.requireTopologyUnchanged(
"ExtinctionValues");
681 constexpr const char*
context =
"ExtinctionValues::contourMap";
685 std::vector<uint8_t>
keep(tree.numInternalNodeSlots(),
false);
686 std::vector<Real>
scoreByNode(tree.numInternalNodeSlots(), Real{0});
689 const NodeId cutoffNode =
item.record->cutoffNode;
690 Real
score = Real{0};
692 case ExtinctionContourScorePolicy::RankScore:
693 score =
static_cast<Real
>(
item.rankScore);
695 case ExtinctionContourScorePolicy::ExtinctionValue:
699 throw std::invalid_argument(std::string(
context) +
" received an unknown extinction contour score policy.");
701 if (!
keep[
static_cast<std::size_t
>(cutoffNode)]) {
703 keep[
static_cast<std::size_t
>(cutoffNode)] =
true;
718 std::vector<std::size_t>
priorityByNode(tree.numInternalNodeSlots(), 0);
764 constexpr const char*
context =
"ExtinctionValues::getExtinctionValueAttribute";
785 const std::vector<Real>&
valuation = getExtinctionValueAttribute();
814 const std::vector<Real>&
valuation = getExtinctionValueAttribute();
848 const std::vector<Real>&
valuation = getExtinctionValueAttribute();
865 return computeRankedFormalSaliencyEdgeMap(
884 const std::vector<Real>&
valuation = getExtinctionValueAttribute();
897 return computeMonotoneExtinctionProjection(
911 const std::vector<Real>&
valuation = getExtinctionValueAttribute();
913 HierarchyValuationPolicy::AllowLevelCollapse);
925 return computeRankedMonotoneExtinctionProjection(
939 constexpr const char*
context =
"ExtinctionValues::filtering";
951 requireStableTree(
"ExtinctionValues::getRegionalExtrema");
#define MMCFILTERS_CONTRACT_REQUIRE(condition,...)
Evaluates a caller precondition and its failure action only in checked builds.
Incremental foreground A4 contours on the image domain.
void forEachContour(Consumer &&consumer) const
Calls consumer(node, pixels) once for every live node.
Explicit extinction-extrema selection policy.
int extremaToKeep() const noexcept
Maximum number of ranked extrema retained by a top-k policy.
bool selectsTopK() const noexcept
Returns true when the policy selects the first ranked extrema.
static ExtinctionSelectionPolicy byThreshold(Real threshold) noexcept
Select every extremum whose extinction value is at least threshold.
static ExtinctionSelectionPolicy byTopK(int extremaToKeep) noexcept
Select the strongest extrema by decreasing extinction ranking.
Real minimumExtinction() const noexcept
Minimum accepted extinction value for a threshold policy.
Computes and stores extinction values for regional extrema.
ExtinctionValues(const AltitudeView &view, const std::shared_ptr< Real[]> &attr)
Computes extinction values from a valued-tree view and shared attribute buffer.
EdgeSaliencyMap< Real > computeMonotoneExtinctionProjection(const RegularGridAdjacency2D &adjacency) const
Projects the max-descendant extinction attribute directly by LCA.
ExtinctionValues(const ValuedMorphologicalTree< T > &valuedTree, const std::vector< Real > &attr)
Computes extinction values from a valued tree and vector attribute buffer.
ExtinctionValues(const ValuedMorphologicalTree< T > &valuedTree, const std::shared_ptr< Real[]> &attr)
Computes extinction values from a valued tree and shared attribute buffer.
const std::vector< RegionalExtremaNode< Real > > & getRegionalExtrema() const
Returns regional-extremum records sorted by decreasing extinction.
EdgeSaliencyMap< int > computeRankedMonotoneExtinctionProjection(const RegularGridAdjacency2D &adjacency) const
Computes canonical effective-edge ranks for the monotone projection.
ImagePtr< T > filtering(const ExtinctionSelectionPolicy< Real > &selection) const
Reconstructs an image from selected regional extrema.
EdgeSaliencyMap< Real > computeFormalSaliencyEdgeMap(const RegularGridAdjacency2D &adjacency) const
Computes the formal hierarchical-watershed extinction saliency map.
EdgeSaliencyMap< int > computeRankedFormalSaliencyEdgeMap(const RegularGridAdjacency2D &adjacency) const
Computes a ranked formal extinction saliency edge map.
Real value_type
Scalar type used for input attributes and extinction values.
ExtinctionValues(const ValuedMorphologicalTree< T > &valuedTree, const Real *attr)
Computes extinction values from a valued tree and raw attribute buffer.
EdgeSaliencyMap< int > computeRankedFormalSaliencyEdgeMap() const
Computes a ranked formal extinction saliency edge map using stored adjacency.
std::vector< int > computeRankedExtinctionValueAttribute() const
Builds a dense integer extinction attribute from extinction levels.
ExtinctionValues(const AltitudeView &view, const Real *attr)
Computes extinction values from a valued-tree view and raw attribute buffer.
EdgeSaliencyMap< int > computeRankedMonotoneExtinctionProjection() const
Stored-adjacency overload of computeRankedMonotoneExtinctionProjection.
EdgeSaliencyMap< Real > computeFormalSaliencyEdgeMap() const
Computes the formal extinction saliency edge map using stored adjacency.
ExtinctionValues(const AltitudeView &view, const std::vector< Real > &attr)
Computes extinction values from a valued-tree view and vector attribute buffer.
ImagePtr< Real > contourMap(const ExtinctionSelectionPolicy< Real > &selection, ExtinctionContourScorePolicy scorePolicy) const
Builds a contour-valued image from selected extinction events.
const std::vector< Real > & getExtinctionValueAttribute() const
Returns extinction values extended from extrema to every hierarchy node.
EdgeSaliencyMap< Real > computeMonotoneExtinctionProjection() const
Stored-adjacency overload of computeMonotoneExtinctionProjection.
static EdgeSaliencyMap< Real > compute(const ValuedMorphologicalTreeView< T > &valuedTree, std::span< const Real > leafExtinction, const RegularGridAdjacency2D &adjacency)
Computes the full-graph extinction hierarchical-watershed saliency.
static EdgeSaliencyMap< int > computeRanked(const ValuedMorphologicalTreeView< T > &valuedTree, std::span< const Real > leafExtinction, const RegularGridAdjacency2D &adjacency)
Computes the canonical dense rank scale of compute.
static void validateHierarchyValuation(const MorphologicalTree &tree, std::span< const Value > valuation, HierarchyValuationPolicy policy=HierarchyValuationPolicy::AllowLevelCollapse, HierarchyValuationRangePolicy rangePolicy=HierarchyValuationRangePolicy::AllowAnyFinite, const char *context="HierarchySaliencyMapValidation::validateHierarchyValuation")
Validates that a node-indexed valuation is compatible with a hierarchy.
static std::vector< int > rankHierarchyValuation(const MorphologicalTree &tree, std::span< const Value > valuation, HierarchyValuationPolicy policy=HierarchyValuationPolicy::AllowLevelCollapse)
Converts a compatible valuation to dense non-negative integer levels.
static EdgeSaliencyMap< int > computeCanonicalRankedSaliencyEdgeMap(const MorphologicalTree &tree, const RegularGridAdjacency2D &adjacency, std::span< const Value > valuation, HierarchyValuationPolicy policy=HierarchyValuationPolicy::AllowLevelCollapse, HierarchyConnectivityPolicy connectivityPolicy=HierarchyConnectivityPolicy::ValidateConnected)
Computes the canonical dense integer saliency scale of a valuation.
static RegularGridAdjacency2D requireProjectionAdjacency(const MorphologicalTree &tree, const char *context="HierarchySaliencyMap::requireProjectionAdjacency")
Returns the unambiguous adjacency stored by a hierarchy.
static EdgeSaliencyMap< Value > computeSaliencyEdgeMap(const MorphologicalTree &tree, const RegularGridAdjacency2D &adjacency, std::span< const Value > valuation, HierarchyValuationPolicy policy=HierarchyValuationPolicy::AllowLevelCollapse, HierarchyLevelConvention levelConvention=HierarchyLevelConvention::EdgeSaliencyValue, HierarchyConnectivityPolicy connectivityPolicy=HierarchyConnectivityPolicy::ValidateConnected)
Computes the formal edge-indexed saliency map induced by a valuation.
static Ptr create(int rows, int columns)
Creates an owned image with uninitialised pixel values.
Mutable connected-subset tree on a finite pixel domain.
int numRows() const
Returns the number of rows in the regular 2D pixel domain.
int numInternalNodeSlots() const
Returns the size of the dense internal-node id domain.
PostOrderNodeRange postOrder() const
Returns a post-order traversal range rooted at the connected root.
void requireMutationVersion(std::size_t expectedVersion, const char *context) const
Rejects stale read-only views that captured an older mutation version.
bool isRoot(NodeId nodeId) const
Tests whether nodeId is the current root.
std::vector< NodeId > leaves() const
Returns all live leaf nodes in the current hierarchy.
int numColumns() const
Returns the number of columns in the regular 2D pixel domain.
NodeId root() const
Returns the current hierarchy root.
Immutable regular-grid 2D adjacency with allocation-free traversal.
static void requireGlobalMonotoneAltitudeOrder(const MorphologicalTree &tree, const char *context)
Requires a declared globally monotone altitude order.
Owning result for one computed scalar attribute layout and buffer.
Record describing one regional extremum and its extinction value.
RegionalExtremaNode(NodeId leaf, NodeId cutoffNode, Real extinction)
Builds one extinction-value record.
Real extinction
Attribute value at cutoffNode, or numeric_limits<Real>::max() for the dominant extremum that survives...
NodeId cutoffNode
Highest node retained before the extremum merges with a stronger branch.
NodeId leaf
Leaf node that represents the regional extremum in a max-tree/min-tree.