Erode / dilate
Local minimum and maximum. Use them for shrinking or expanding bright foreground regions and for conservative mask cleanup.
Exact erosion, dilation, opening, closing, gradient, top-hat, and black-hat with explicit elements, anchors, iterations, and border behavior.
Local minimum and maximum. Use them for shrinking or expanding bright foreground regions and for conservative mask cleanup.
Opening removes small bright structures; closing fills small dark gaps. Iterations follow OpenCV's erode×N then dilate×N ordering.
Gradient extracts boundaries; top-hat and black-hat isolate bright or dark detail relative to the selected neighborhood scale.
Packed grayscale u8 rectangles use two separable one-dimensional min/max passes. Centered 5×5 Replicate operations use fixed extrema and direct row-major vertical passes with safe SIMD dispatch. Larger or asymmetric rectangles use prefix/suffix blocks, so work is linear in image size plus border padding rather than image size times rectangle area.
flowchart TD
A["u8 rectangle erode / dilate"] --> B{"5×5 anchor + Replicate?"}
B -- yes --> C["Centered 5×5 fast path
fixed extrema, direct vertical pass"]
B -- no --> D{"width×height ≥ 1,000,000?"}
D -- yes --> E["Parallel horizontal pass
per-worker line buffers"]
D -- no --> F["Sequential horizontal pass"]
E --> G["Blocked transpose"]
F --> G
G --> H["Vertical pass
prefix/suffix sliding extrema"]
H --> I["Blocked transpose back"]
C --> J["u8 output"]
I --> J
RectMorphologyWorkspace retains every full-image plane and one line-buffer set per worker. The *_into APIs write to caller-owned output. Python exposes the same contract as MorphologyWorkspace plus out=; overlapping input/output is rejected instead of silently copying.
Cross, ellipse, diamond, custom masks, other component types, channels, and strided views retain the safe generic implementation. Public CPU calls never upload to a GPU. Device morphology is a separate explicit wgpu API.
The OpenCV 4.13 comparison uses random packed uint8, replicated borders, allocated and caller-owned Python outputs, OpenCL off, and paired interleaved calls. All published timings first require bit-exact output; 980 additional randomized operation cases also pass.
SpatialRust lead for 1080p 511×511 opening with caller-owned outputs on the recorded 12-thread Windows host.
SpatialRust lead for 4K 511×511 opening with caller-owned outputs on the same host.
SpatialRust lead for 1080p 5×5 opening with caller-owned output; OpenCV still leads the other recorded 5×5 profiles.
Reproduce with the focused harness and inspect the small-kernel receipt or workspace receipt.
The implementation follows the van Herk/Gil–Werman family of constant-comparison sliding extrema. Semantics are checked against the OpenCV morphology API; the optimization direction is described by Kimmel and Gil and related streaming min/max work.