3#include "../attributes/AttributeComputation.hpp"
4#include "../trees/detail/TreeStabilityNeighborhood.hpp"
5#include "../trees/detail/HierarchyCapabilityValidation.hpp"
6#include "../trees/MorphologicalTree.hpp"
7#include "../trees/TreeAltitudeAlgorithms.hpp"
8#include "../trees/ValuedMorphologicalTree.hpp"
9#include "../utils/Common.hpp"
10#include "../utils/Contract.hpp"
11#include "detail/VariationMeasure.hpp"
59template <AltitudeValue T, std::
floating_po
int Real =
float>
class MSERComputer {
70 const std::vector<T>& altitude_;
72 const Real* externalAttrMser_;
74 std::vector<Real> ownedAttrMser_;
84 bool hasComputed_ =
false;
86 std::vector<Real> variation;
88 std::vector<NodeId> ancestors;
90 std::vector<NodeId> descendants;
97 [[
nodiscard]]
const Real* attributeData()
const noexcept {
return ownedAttrMser_.empty() ? externalAttrMser_ : ownedAttrMser_.data(); }
104 void requireComputed(
const char*
context)
const {
114 static void validateOwnedAttributeSize(
const MorphologicalTree& tree,
const std::vector<Real>& attr) {
116 throw std::invalid_argument(
"MSERComputer attribute size must match the internal node slot count."));
126 MSERComputer(
const ValuedMorphologicalTree<T>& valuedTree,
const Real* attr_increasing, std::vector<Real> ownedAttr)
127 : valuedTree_(valuedTree), tree(valuedTree.topology()), altitude_(valuedTree.nodeAltitudes()), externalAttrMser_(attr_increasing),
128 ownedAttrMser_(std::move(ownedAttr)), maxVariation(Real{10}), minAttr(Real{0}),
129 maxAttr(static_cast<Real>(this->tree.numColumns() * this->tree.numRows())) {
131 detail::validateGlobalMonotoneAltitudeOrder(this->tree,
"MSERComputer");
158 throw std::invalid_argument(
"MSERComputer requires a non-null attribute buffer for the raw-pointer constructor."));
192 detail::computeAltitudeStabilityNeighborhood(tree, std::span<const T>(altitude_),
altitudeWindowRadius);
194 this->descendants = std::move(
neighborhood.descendants);
197 this->variation = detail::computeVariationsFromNeighborhood<Real>(this->tree, this->ancestors, this->descendants,
attrAt);
198 std::vector<uint8_t>
selected = detail::selectStrictVariationMinima<Real>(this->tree, this->variation, this->ancestors, this->descendants,
attrAt,
199 this->maxVariation, this->minAttr, this->maxAttr, this->num);
200 this->hasComputed_ =
true;
211 requireComputed(
"MSERComputer::getVariation");
212 detail::validateStabilityNeighborhoodShape(this->tree, this->ancestors, this->descendants,
"MSERComputer::getVariation");
214 return detail::computeVariationValue<Real>(node, this->ancestors, this->descendants,
attrAt);
225 if (attributeData() ==
nullptr) {
226 auto area = AttributeComputation::computeSingleAttribute<Real>(valuedTree_, Area);
229 const Real* data = attributeData();
230 if (data ==
nullptr) {
231 throw std::logic_error(
"MSERComputer attribute storage is unavailable.");
244 requireComputed(
"MSERComputer::nodeWithMinimumVariationInWindow");
245 detail::validateStabilityNeighborhoodShape(this->tree, this->ancestors, this->descendants,
"MSERComputer::nodeWithMinimumVariationInWindow");
246 return detail::nodeWithMinimumVariationInWindow<Real>(node, this->variation, this->ancestors, this->descendants);
256 requireComputed(
"MSERComputer::ancestorInStabilityWindow");
257 return this->ancestors[
static_cast<std::size_t
>(node)];
267 requireComputed(
"MSERComputer::descendantInStabilityWindow");
268 return this->descendants[node];
277 requireComputed(
"MSERComputer::getVariations");
278 return this->variation;
287 requireComputed(
"MSERComputer::numNodes");
typename detail::AltitudeDifferenceSelector< T >::type AltitudeDifference
Arithmetic result type for altitude differences.
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 MSER-like nodes from a monotone increasing attribute defined on the hierarchy.
int numNodes()
Returns the number of nodes selected as MSER-like in the last run.
std::vector< uint8_t > computeMSER(AltitudeDifference< T > altitudeWindowRadius)
Computes the MSER indicator vector for an altitude-window radius.
MSERComputer(const ValuedMorphologicalTree< T > &valuedTree)
Creates an MSER detector that lazily falls back to AREA.
Real getVariation(NodeId node)
Returns the variation score currently associated with a node.
MSERComputer(const ValuedMorphologicalTree< T > &valuedTree, std::vector< Real > attr_increasing)
Creates an MSER detector backed by an owned attribute buffer.
NodeId descendantInStabilityWindow(NodeId node) const
Returns the descendant used in the current stability window.
MSERComputer(const MSERComputer &)=default
Copies the evaluator while preserving owned-buffer safety.
NodeId nodeWithMinimumVariationInWindow(NodeId node)
Returns the node with minimum variation among the current node and its altitude-window neighbours.
void setMaxVariation(Real maxVariation)
Sets the maximum accepted variation value.
void setMaxAttribute(Real maxAttr)
Sets the upper bound of the accepted attribute interval.
NodeId ancestorInStabilityWindow(NodeId node) const
Returns the ancestor used in the current stability window.
Real variation_value_type
Floating-point type used to store variation scores.
std::vector< Real > & getVariations()
Returns the current variation array, indexed by node slot.
MSERComputer(MSERComputer &&) noexcept=default
Moves the evaluator while preserving its referenced tree.
void setMinAttribute(Real minAttr)
Sets the lower bound of the accepted attribute interval.
Real getAttrMSER(NodeId node)
Returns the attribute used by the MSER stability measure, lazily computing AREA when no external buff...
MSERComputer(const ValuedMorphologicalTree< T > &valuedTree, const Real *attr_increasing)
Creates an MSER detector backed by a non-owning attribute view.
Mutable connected-subset tree on a finite pixel domain.
static void validateNodeAltitudeBufferShape(const MorphologicalTree &tree, std::span< const T > altitude)
Validates that an altitude buffer covers the dense internal-node domain.
Owning result for one computed scalar attribute layout and buffer.
std::vector< Real > second
Flat per-node attribute buffer indexed through first.