3#include "../attributes/AttributeComputation.hpp"
4#include "../trees/detail/TreeStabilityNeighborhood.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."));
158 this->descendants = std::move(
neighborhood.descendants);
161 this->variation = detail::computeVariationsFromNeighborhood<Real>(this->tree, this->ancestors, this->descendants,
attrAt);
162 std::vector<uint8_t>
selected = detail::selectStrictVariationMinima<Real>(this->tree, this->variation, this->ancestors, this->descendants,
attrAt,
163 this->maxVariation, this->minAttr, this->maxAttr, this->num);
164 this->hasComputed_ =
true;
175 requireComputed(
"DepthStableRegionComputer::getVariation");
176 detail::validateStabilityNeighborhoodShape(this->tree, this->ancestors, this->descendants,
"DepthStableRegionComputer::getVariation");
178 return detail::computeVariationValue<Real>(node, this->ancestors, this->descendants,
attrAt);
188 if (attributeData() ==
nullptr) {
189 auto area = AttributeComputation::computeSingleTopologyAttribute<Real>(this->tree, Area);
192 const Real* data = attributeData();
193 if (data ==
nullptr) {
194 throw std::logic_error(
"DepthStableRegionComputer attribute storage is unavailable.");
196 return data[
static_cast<std::size_t
>(node)];
206 requireComputed(
"DepthStableRegionComputer::nodeWithMinimumVariationInWindow");
207 detail::validateStabilityNeighborhoodShape(this->tree, this->ancestors, this->descendants,
208 "DepthStableRegionComputer::nodeWithMinimumVariationInWindow");
209 return detail::nodeWithMinimumVariationInWindow<Real>(node, this->variation, this->ancestors, this->descendants);
219 requireComputed(
"DepthStableRegionComputer::ancestorInStabilityWindow");
220 return this->ancestors[
static_cast<std::size_t
>(node)];
230 requireComputed(
"DepthStableRegionComputer::descendantInStabilityWindow");
231 return this->descendants[
static_cast<std::size_t
>(node)];
240 requireComputed(
"DepthStableRegionComputer::getVariations");
250 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.
std::vector< Real > second
Flat per-node attribute buffer indexed through first.