3#include "../trees/TreeAltitudeAlgorithms.hpp"
4#include "../trees/ValuedMorphologicalTree.hpp"
5#include "../trees/ValuedMorphologicalTreeView.hpp"
6#include "../trees/detail/CommittedTreeAccess.hpp"
7#include "../trees/detail/HierarchyCapabilityValidation.hpp"
8#include "../trees/saliency/HierarchySaliencyMapValidation.hpp"
9#include "../trees/saliency/HierarchySaliencyMap.hpp"
10#include "../trees/saliency/HierarchicalWatershedSaliency.hpp"
11#include "../utils/Image.hpp"
12#include "../utils/Common.hpp"
13#include "../utils/Contract.hpp"
14#include "../contours/ContourComputation.hpp"
63 enum class Mode { TopK, MinimumExtinction };
66 Mode mode_ = Mode::TopK;
68 int extremaToKeep_ = 0;
70 Real threshold_ = Real{0};
96 policy.mode_ = Mode::MinimumExtinction;
128enum class ExtinctionContourScorePolicy {
232 throw std::invalid_argument(std::string(
context) +
" requires a non-null attribute buffer."));
247 throw std::invalid_argument(std::string(
context) +
" attribute size must match the internal node slot count."));
262 return view.nodeAltitudes()[
static_cast<std::size_t
>(
nodeId)];
298 throw std::invalid_argument(std::string(
context) +
" requires a non-negative extremaToKeep value."));
310 throw std::invalid_argument(std::string(
context) +
" requires a finite extinction threshold."));
325 if (
policy.selectsTopK()) {
345 if (!std::isfinite(value)) {
346 throw std::invalid_argument(std::string(
context) +
" requires finite extinction values.");
348 if (value < Real{0}) {
349 throw std::invalid_argument(std::string(
context) +
" requires non-negative extinction values.");
400 HierarchyValuationPolicy::AllowLevelCollapse,
401 HierarchyValuationRangePolicy::RequireNonNegative,
context);
421 std::vector<const RegionalExtremaNode<Real>*>
records;
422 if (
policy.selectsTopK()) {
437 std::vector<SelectedExtremum>
selected;
470 std::stack<NodeId>
stack;
472 while (!
stack.empty()) {
476 for (
PixelId pixel : detail::CommittedTreeAccess::properParts(tree,
nodeId)) {
544 if (detail::CommittedTreeAccess::numChildren(this->tree,
parentNodeId) > 1) {
568 if (a.extinction != b.extinction) {
569 return a.extinction > b.extinction;
571 if (
a.cutoffNode !=
b.cutoffNode) {
572 return a.cutoffNode < b.cutoffNode;
574 return a.leaf <
b.leaf;
619 view_.requireTopologyUnchanged(
"ExtinctionValues");
620 detail::validateGlobalMonotoneAltitudeOrder(this->tree,
"ExtinctionValues");
682 constexpr const char*
context =
"ExtinctionValues::contourMap";
686 std::vector<uint8_t>
keep(tree.numInternalNodeSlots(),
false);
687 std::vector<Real>
scoreByNode(tree.numInternalNodeSlots(), Real{0});
690 const NodeId cutoffNode =
item.record->cutoffNode;
691 Real
score = Real{0};
693 case ExtinctionContourScorePolicy::RankScore:
694 score =
static_cast<Real
>(
item.rankScore);
696 case ExtinctionContourScorePolicy::ExtinctionValue:
700 throw std::invalid_argument(std::string(
context) +
" received an unknown extinction contour score policy.");
702 if (!
keep[
static_cast<std::size_t
>(cutoffNode)]) {
704 keep[
static_cast<std::size_t
>(cutoffNode)] =
true;
719 std::vector<std::size_t>
priorityByNode(tree.numInternalNodeSlots(), 0);
765 constexpr const char*
context =
"ExtinctionValues::getExtinctionValueAttribute";
786 const std::vector<Real>&
valuation = getExtinctionValueAttribute();
815 const std::vector<Real>&
valuation = getExtinctionValueAttribute();
849 const std::vector<Real>&
valuation = getExtinctionValueAttribute();
866 return computeRankedFormalSaliencyEdgeMap(
885 const std::vector<Real>&
valuation = getExtinctionValueAttribute();
898 return computeMonotoneExtinctionProjection(
912 const std::vector<Real>&
valuation = getExtinctionValueAttribute();
914 HierarchyValuationPolicy::AllowLevelCollapse);
926 return computeRankedMonotoneExtinctionProjection(
940 constexpr const char*
context =
"ExtinctionValues::filtering";
952 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.
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.