3#include "../attributes/AttributeComputation.hpp"
4#include "../trees/detail/TreeNeighborhood.hpp"
5#include "../trees/MorphologicalTree.hpp"
6#include "../utils/Common.hpp"
7#include "../utils/Contract.hpp"
8#include "detail/VariationMeasure.hpp"
50 const Real* externalAttr_ =
nullptr;
52 std::vector<Real> ownedAttr_;
54 Real maxVariation = Real{10};
56 Real minAttr = Real{0};
62 bool hasComputed_ =
false;
64 std::vector<Real> variation;
66 std::vector<NodeId> ancestors;
68 std::vector<NodeId> descendants;
75 [[nodiscard]]
const Real* attributeData() const noexcept {
return ownedAttr_.empty() ? externalAttr_ : ownedAttr_.data(); }
82 void requireComputed(
const char* context)
const {
92 static void validateOwnedAttributeSize(
const MorphologicalTree& tree,
const std::vector<Real>& attr) {
94 throw std::invalid_argument(
"DepthStableRegionComputer attribute size must match the internal node slot count."));
104 DepthStableRegionComputer(
const MorphologicalTree& tree,
const Real* attr, std::vector<Real> ownedAttr)
105 : tree(tree), externalAttr_(attr), ownedAttr_(std::move(ownedAttr)),
106 maxAttr(static_cast<Real>(tree.numColumns() * tree.numRows())) {}
117 validateOwnedAttributeSize(tree,
attr);
118 return std::move(
attr);
130 throw std::invalid_argument(
"DepthStableRegionComputer requires a non-null attribute buffer for the raw-pointer constructor."));
157 throw std::invalid_argument(
"DepthStableRegionComputer requires a positive depth window radius."));
161 this->descendants = std::move(
neighborhood.descendants);
164 this->variation = detail::computeVariationsFromNeighborhood<Real>(this->tree, this->ancestors, this->descendants,
attrAt);
165 std::vector<uint8_t>
selected = detail::selectStrictVariationMinima<Real>(this->tree, this->variation, this->ancestors, this->descendants,
attrAt,
166 this->maxVariation, this->minAttr, this->maxAttr, this->num);
167 this->hasComputed_ =
true;
178 requireComputed(
"DepthStableRegionComputer::getVariation");
179 detail::validateStabilityNeighborhoodShape(this->tree, this->ancestors, this->descendants,
"DepthStableRegionComputer::getVariation");
181 return detail::computeVariationValue<Real>(node, this->ancestors, this->descendants,
attrAt);
191 if (attributeData() ==
nullptr) {
192 auto area = AttributeComputation::computeSingleTopologyAttribute<Real>(this->tree, Area);
193 this->ownedAttr_ = std::move(area.second);
195 const Real* data = attributeData();
196 if (data ==
nullptr) {
197 throw std::logic_error(
"DepthStableRegionComputer attribute storage is unavailable.");
199 return data[
static_cast<std::size_t
>(node)];
209 requireComputed(
"DepthStableRegionComputer::nodeWithMinimumVariationInWindow");
210 detail::validateStabilityNeighborhoodShape(this->tree, this->ancestors, this->descendants,
211 "DepthStableRegionComputer::nodeWithMinimumVariationInWindow");
212 return detail::nodeWithMinimumVariationInWindow<Real>(node, this->variation, this->ancestors, this->descendants);
222 requireComputed(
"DepthStableRegionComputer::ancestorInStabilityWindow");
223 return this->ancestors[
static_cast<std::size_t
>(node)];
233 requireComputed(
"DepthStableRegionComputer::descendantInStabilityWindow");
234 return this->descendants[
static_cast<std::size_t
>(node)];
243 requireComputed(
"DepthStableRegionComputer::getVariations");
253 requireComputed(
"DepthStableRegionComputer::numNodes");
int NodeId
Node identifier type used throughout the project.
#define MMCFILTERS_CONTRACT_REQUIRE(condition,...)
Evaluates a caller precondition and its failure action only in checked builds.
Detects stable regions from a topological depth window.
DepthStableRegionComputer(DepthStableRegionComputer &&) noexcept=default
Moves the evaluator while preserving its referenced tree.
void setMinAttribute(Real value)
Sets the lower bound of the accepted attribute interval.
std::vector< uint8_t > computeByDepth(int depthWindowRadius)
Computes the stable-region indicator vector for a positive depth-window radius.
NodeId nodeWithMinimumVariationInWindow(NodeId node) const
Returns the node with minimum variation in the depth window.
DepthStableRegionComputer(const MorphologicalTree &tree, const Real *attr)
Creates a detector backed by a non-owning attribute buffer.
int numNodes() const
Returns the number of nodes selected in the last run.
DepthStableRegionComputer(const DepthStableRegionComputer &)=default
Copies the evaluator while preserving owned-buffer safety.
Real getVariation(NodeId node)
Returns the variation score currently associated with a node.
void setMaxAttribute(Real value)
Sets the upper bound of the accepted attribute interval.
NodeId descendantInStabilityWindow(NodeId node) const
Returns the descendant used in the current depth window.
NodeId ancestorInStabilityWindow(NodeId node) const
Returns the ancestor used in the current depth window.
void setMaxVariation(Real value)
Sets the maximum accepted variation value.
DepthStableRegionComputer(const MorphologicalTree &tree, std::vector< Real > attr)
Creates a detector backed by an owned increasing-attribute buffer.
Real variation_value_type
Floating-point type used to store variation scores.
DepthStableRegionComputer(const MorphologicalTree &tree)
Creates a detector that lazily computes topology-only AREA.
Real getAttribute(NodeId node)
Returns the increasing attribute used by the stability measure.
std::vector< Real > & getVariations()
Returns the current variation array, indexed by node slot.
Mutable connected-subset tree on a finite pixel domain.
Owning result for one computed scalar attribute layout and buffer.