MorphoTreeAdjust provides the core C++ and Python implementation for dynamic updates of component trees and connected alternating sequential filters (CASF). The repository is organized around a small public API, example programs, and developer tools for experiments, validation, and benchmarks.
The repository is centered on dynamic update problems for component trees.
Let f be an image, and let T_f^min and T_f^max be the min-tree and
max-tree of f.
We set:
S: a subtree inT_f^minT_g^min: the min-tree obtained after pruningSfromT_f^ming: the image reconstructed fromT_g^minT_g^max: the max-tree ofg
The central question is:
How to modify
T_f^maxto obtainT_g^max?
This is the basis for the dual min/max tree incremental filtering work and for CASF implementations derived from those structures.
Related papers:
- Wonder Alves, Nicolas Passat, Dênnis José da Silva, Alexandre Morimitsu, Ronaldo F. Hashimoto. Efficient connected alternating sequential filters based on component trees. International Conference on Discrete Geometry and Mathematical Morphology (DGMM), November 2025, Groningen, Netherlands. hal-05163556
- Wonder Alves, Nicolas Passat, Dênnis José da Silva, Alexandre Morimitsu, Ronaldo F. Hashimoto. Component tree: Update rather than rebuild. Journal of Mathematical Imaging and Vision (under review), 2026.
If you want the Python surface first, install it from PyPI:
python -m pip install morphoTreeAdjustIf you want the current repository version instead, install it from the repository root:
python -m pip install .The package build is pyproject.toml-driven and uses scikit-build-core
with CMake for the native extension.
Then use the public module:
import numpy as np
import morphoTreeAdjust as mta
image = np.array(
[
[4, 4, 2, 1],
[4, 3, 2, 1],
[5, 5, 2, 0],
[5, 6, 6, 0],
],
dtype=np.uint8,
)
adj = mta.AdjacencyRelation(image.shape[0], image.shape[1], 1.5)
maxtree = mta.DynamicComponentTree(image, True, adj)
mintree = mta.DynamicComponentTree(image, False, adj)
adjust = mta.DualMinMaxTreeIncrementalFilter(mintree, maxtree)
casf = mta.ComponentTreeCasf(image, "area", adj)
filtered = casf.filter([1, 2])For a complete runnable script, see examples/core_python_api_example.py.
If you want a developer build with benchmarks and tools:
cmake -S dev-tools -B ../build/MorphoTreeAdjust/dev-tools
cmake --build ../build/MorphoTreeAdjust/dev-toolsIf you want the install surface from the root project:
cmake -S . -B ../build/MorphoTreeAdjust/install \
-DPYTHON_EXECUTABLE="$(python -c 'import sys; print(sys.executable)')"
cmake --build ../build/MorphoTreeAdjust/install
cmake --install ../build/MorphoTreeAdjust/install --prefix /tmp/mta-installcmake --install publishes:
- the Python package under
lib/morphoTreeAdjust; - the public C++ headers under
include/MorphoTreeAdjustwhenMTA_INSTALL_PUBLIC_CORE_HEADERS=ON.
- Public C++ entrypoint: morphoTreeAdjust/include/MorphoTreeAdjust.hpp
- Core headers: morphoTreeAdjust/include
- Python bindings: morphoTreeAdjust/morphoTreeAdjust.cpp
- Examples: examples
- Notebooks: notebooks
- Documentation: docs
- Developer tools and benchmarks: dev-tools
Recommended documentation entry points:
Ad hoc debug binaries under dev-tools/tools/debug_*.cpp are excluded from the
default developer build. Enable them explicitly when needed:
cmake -S dev-tools -B ../build/MorphoTreeAdjust/dev-tools \
-DMTA_BUILD_DEBUG_TOOLS=ON
cmake --build ../build/MorphoTreeAdjust/dev-toolsCore benchmark example:
../build/MorphoTreeAdjust/dev-tools/benchmarks/jmiv2026_benchmark \
--repeat 5 --warmup 1 --json --no-validate image1.png image2.pngdynamic_casf_apply applies connected alternating sequential filters on
grayscale images and compares the dynamic implementations against the naive
rebuild-based baseline.
After building dev-tools, the executable is available at:
../build/MorphoTreeAdjust/dev-tools/tools/dynamic_casf_applyUsage:
../build/MorphoTreeAdjust/dev-tools/tools/dynamic_casf_apply \
[--mode dynamic-subtree|dynamic-leaf|naive|compare] \
[--attribute area|bbox_width|bbox_height|bbox_diagonal] \
[--radio-adj <radius>] \
[--iter-timing] \
[--no-output] \
<input.png> [<output.png>] <threshold1> [threshold2 ...]Modes:
dynamic-subtree: CASF with dynamic subtree-based updates;dynamic-leaf: CASF with dynamic leaf-based updates;naive: CASF by rebuilding the trees at every threshold;compare: runsdynamic-subtree,dynamic-leaf, andnaive, checks that outputs match, and prints a timing summary.
Attributes:
areabbox_widthbbox_heightbbox_diagonal
Examples:
../build/MorphoTreeAdjust/dev-tools/tools/dynamic_casf_apply \
--mode dynamic-subtree \
--attribute area \
cameraman.png cameraman_dynamic.png 64 128 256../build/MorphoTreeAdjust/dev-tools/tools/dynamic_casf_apply \
--mode compare \
--attribute bbox_diagonal \
--radio-adj 1.5 \
--no-output \
cameraman.png 64 128 256Timing output:
Initialization time: dynamic setup cost before the threshold loop, including adjacency creation, max-tree/min-tree construction, attribute computer setup, initial attribute computation, and attribute binding;Iteration time: accumulated threshold-loop time, excluding initialization and final reconstruction;Reconstruction time: final image reconstruction time;Total time:Initialization time + Iteration time + Reconstruction time.
For naive, Total time measures the full per-threshold rebuild-and-filter
work. In compare mode, the reported dynamic totals include initialization so
they are directly comparable to the naive baseline.