The watershed hierarchy does not survive a photograph, so local masking stops depending on it. A layer can now be one recognised object, and the object's own coverage is the mask. `Options::watershed` defaults off. It costs ~80 ms plus a full-resolution readback to produce a ladder that collapses, and paying that on every photograph buys a control that misleads. Kept switchable rather than deleted: the passes and the hierarchy are correct in themselves and it is the merge criterion that fails, which is a change to one function. Masks now rasterise in **source** space at proxy resolution and are sampled by the composed shader after the framing map. That fixes a real bug: they were rasterised in output space, so zooming slid the photograph underneath a mask that stayed pinned to the viewport, and cropping moved every adjustment to a different part of the picture. Doing it this way also leaves the framing map in exactly one place — a second copy in the mask shader would have been a second thing to keep in step, failing only when straightened. A subject is stored as identity, not pixels: the mask is megabytes and is reproducible by running the same model over the same image, so the sidecar carries the index, the class and the score, and the session carries the pixels. The class is there to be checked — if instance 3 comes back a "car" where it was a "dog", something changed and the layer is stale rather than silently masking the wrong thing. The overlay now draws instances and is transparent everywhere else. The region version covered every pixel and so hid the photograph it was drawn over; the question it exists to answer is whether an outline follows the subject, which you can only answer by seeing both. `examples/local.rs` is the worked example: subject in colour with the rest monochrome, and the subject lifted out of its background. Run on a 5472x3648 CR2 it finds two people and two cars, and the colour-pop keeps her hat and hair while the wall and grass behind go grey.
63 lines
2.2 KiB
TOML
63 lines
2.2 KiB
TOML
[package]
|
|
name = "dr-gpu"
|
|
version.workspace = true
|
|
edition.workspace = true
|
|
rust-version.workspace = true
|
|
license.workspace = true
|
|
|
|
[dependencies]
|
|
dr-types.workspace = true
|
|
dr-decode.workspace = true
|
|
dr-pipeline.workspace = true
|
|
# The watershed's pixel passes are here because they are shaders; everything
|
|
# that reasons about regions rather than pixels lives there, where it is
|
|
# testable with no adapter present. No features: this half needs neither the
|
|
# inference runtime nor the weights, and the workspace declaration defaults
|
|
# them off so that stays true.
|
|
dr-segment.workspace = true
|
|
wgpu.workspace = true
|
|
thiserror.workspace = true
|
|
log.workspace = true
|
|
bytemuck.workspace = true
|
|
# Needed outside tests: shader compilation errors are collected through an
|
|
# async error scope, which must be resolved before the pipeline is returned.
|
|
pollster.workspace = true
|
|
|
|
[dev-dependencies]
|
|
env_logger.workspace = true
|
|
# The local-adjustment example needs the model, which the library half of this
|
|
# crate deliberately does not: `dr-gpu` holds the shaders, and the inference
|
|
# runtime belongs to whoever is asking a question about the picture.
|
|
dr-segment = { workspace = true, features = ["semantic", "embedded-model"] }
|
|
|
|
[[example]]
|
|
name = "bench"
|
|
required-features = ["readback"]
|
|
|
|
[[example]]
|
|
name = "develop"
|
|
# No `readback` needed since S1: this writes a file, so it goes through
|
|
# `export_pixels`, which is ungated precisely because an export is not the
|
|
# round-trip AC-8 forbids.
|
|
|
|
[features]
|
|
default = []
|
|
# Exposes read_pixels outside tests. Production must not enable this.
|
|
readback = []
|
|
# Exposes `Segmentation::read_field`, which builds the region adjacency graph
|
|
# on the CPU. Separate from `readback` on purpose — see `segment.rs`. Once per
|
|
# image on a worker, not the per-frame display round-trip AC-8 forbids; still a
|
|
# full-resolution transfer, and still F3's open gap.
|
|
segment-readback = []
|
|
|
|
[[example]]
|
|
name = "segment"
|
|
required-features = ["segment-readback"]
|
|
|
|
[[example]]
|
|
name = "local"
|
|
# No `segment-readback`: this reads the *rendered* proxy back through
|
|
# `export_pixels` to feed the model, which is the ungated export path. The
|
|
# watershed, and the region-graph transfer that needs the gate, is not involved.
|
|
|