Let the model say what a thing is and the watershed say where it ends
Local masking needs to know where an image's regions are. The watershed spike (S15 arm A) found the boundaries but had no idea what any of them enclosed; its coarse levels were geometric accidents. This adds the other half and the thing that joins them. `core/dr-segment` is where region reasoning now lives — the hierarchy moves out of `dr-gpu`, which keeps only the pixel passes that are genuinely shaders. The new crate is device-free and, without its default features, model-free too: 20 of its tests need neither an adapter nor 11 MB of weights. Arm B runs YOLO26n-seg through `ort`. D13 framed inference as a choice between `ort`'s C++ runtime and the pure-Rust dependency policy; that was a false choice. `ort`'s `alternative-backend` feature unlinks the C entirely and `ort-tract` supplies the API from tract, which is pure Rust. Measured before committing to it: zero unsupported operators, 420 ms for 640x640, and correct masks on bus.jpg. No NDK problem to solve, so D13's largest tolerated exception is not needed. Arm C is `prior.rs`, and it ships because the two arms fail in opposite directions. Instance membership re-weights the merge saddles, so region pairs the model believes share an object merge early and pairs straddling its edge merge late. No boundary moves — only the order in which they dissolve — which is how the result stays pixel-accurate at every level while its coarse levels become named things. Two things the spec assumed that turned out to be false, both recorded in models/LICENCE.md: there is no usable ADE20K-trained YOLO, so the shipped vocabulary is COCO's 80 subjects and *stuff* like sky and foliage must come from arm A; and tract cannot parse a dynamic-shape export, so the graph's input is fixed and tiling is the only route to more semantic resolution. Weights are AGPL-3.0, which GPLv3 §13 permits and which makes the combined work effectively AGPL. Deliberate, not accidental. They live in Git LFS, and a build script fails with an instruction rather than embedding a pointer file when the clone lacks them.
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
[package]
|
||||
name = "dr-segment"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
license.workspace = true
|
||||
# Guards against a Git LFS pointer being embedded in place of the weights.
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
thiserror.workspace = true
|
||||
log.workspace = true
|
||||
|
||||
# Inference. `ort` is the API; **tract is the engine** — see the workspace
|
||||
# manifest for why the C++ ONNX Runtime is not linked here.
|
||||
ort = { workspace = true, optional = true }
|
||||
ort-tract = { workspace = true, optional = true }
|
||||
ndarray = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
# The example reads an ordinary JPEG, because the thing worth looking at is
|
||||
# whether detections land on a real photograph. Pure Rust, and already in the
|
||||
# tree for embedded previews.
|
||||
zune-jpeg.workspace = true
|
||||
env_logger.workspace = true
|
||||
|
||||
[features]
|
||||
# On by default: a local adjustment that cannot select a subject is half the
|
||||
# feature, and the whole point of the tract backend is that enabling this costs
|
||||
# no C dependency on any platform.
|
||||
default = ["semantic", "embedded-model"]
|
||||
|
||||
# Arm B — the ONNX runtime and the instance decoder.
|
||||
#
|
||||
# Separable because the watershed half is genuinely independent of it: with
|
||||
# this off, `dr-segment` is a pure-CPU graph algorithm crate with no model to
|
||||
# carry, which is what the headless hierarchy tests want.
|
||||
semantic = ["dep:ort", "dep:ort-tract", "dep:ndarray"]
|
||||
|
||||
# Compile the weights into the binary.
|
||||
#
|
||||
# Separate from `semantic` because the two answer different questions. Android
|
||||
# hands the app no filesystem path to read a model from (ARCH §6.9), so there
|
||||
# it must be embedded; a desktop packager pointing at a system model directory,
|
||||
# or a test that only needs the decoder, wants the runtime without the 11 MB.
|
||||
embedded-model = ["semantic"]
|
||||
Reference in New Issue
Block a user