vibespatial.raster.label¶
Connected component labeling, sieve filtering, and morphology.
CPU baseline uses scipy.ndimage. GPU path uses custom NVRTC union-find kernels (kernels/ccl.py) and morphology stencil kernels (kernels/morphology.py).
ADR-0040: CCCL Connected Component Labeling
Attributes¶
Functions¶
Label connected components in a raster. |
|
|
GPU connected component labeling using iterative union-find. |
|
Build a binary structuring element (SE) for morphological operations. |
|
GPU binary morphology using NVRTC 3x3 stencil kernels. |
|
Apply binary morphological operation to a raster. |
Black top-hat transform: morphological closing minus original. |
|
White top-hat transform: original minus morphological opening. |
|
|
Remove small connected components from a labeled raster. |
Module Contents¶
- vibespatial.raster.label.label_connected_components(raster: vibespatial.raster.buffers.OwnedRasterArray, *, connectivity: int = 4, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray¶
Label connected components in a raster.
Each group of connected nonzero (and non-nodata) pixels receives a unique integer label. Background (zero or nodata) pixels get label 0.
For multiband rasters, each band is labeled independently: the foreground of each band is labeled as a separate 2-D connected component analysis. The output has the same band count as the input.
Parameters¶
- rasterOwnedRasterArray
Input raster. Nonzero values are foreground.
- connectivityint
4 or 8 neighbor connectivity.
- use_gpubool or None
Force GPU (True), force CPU (False), or auto-dispatch (None). Auto uses GPU when available and pixel count exceeds threshold.
Returns¶
- OwnedRasterArray
Integer-labeled raster where each connected component has a unique label.
- vibespatial.raster.label.label_gpu(raster: vibespatial.raster.buffers.OwnedRasterArray, *, connectivity: int = 4) vibespatial.raster.buffers.OwnedRasterArray¶
GPU connected component labeling using iterative union-find.
Multiband rasters are labeled per-band independently via
dispatch_per_band_gpu.Uses NVRTC kernels: init_labels -> local_merge -> pointer_jump (iterate) -> relabel to compact sequential labels 1..N.
Optimizations over naive union-find: - Path-splitting find_root with atomicCAS (reduces tree height in-place) - Lock-free union via atomicCAS (avoids atomicMin serialization on roots) - Asymmetric neighbor scan (each edge processed once, not twice) - Pointer jump runs to full convergence (no fixed iteration cap) - Compact relabel via direct LUT (O(1) per pixel, no binary search) - All relabel computation on device (no D->H->D ping-pong) - Occupancy-based launch configs (no hardcoded block sizes) - Grid-stride loops in 1D kernels for wave-quantization robustness - Single d_changed buffer reused (no per-iteration allocation)
Parameters¶
- rasterOwnedRasterArray
Input raster. Nonzero values are foreground.
- connectivityint
4 or 8 neighbor connectivity.
Returns¶
- OwnedRasterArray
HOST-resident integer-labeled raster (int32, nodata=0).
- vibespatial.raster.label.make_structuring_element(shape: str, size: int | tuple[int, int]) numpy.ndarray¶
Build a binary structuring element (SE) for morphological operations.
Parameters¶
- shapestr
One of
'rect','cross','disk'.- sizeint or (int, int)
For
'rect'and'cross': side length (int) or (height, width). For'disk': radius as int (the SE will be(2*r+1, 2*r+1)). Sizes must be odd.
Returns¶
- np.ndarray
2-D uint8 array with 1s for active SE positions.
Raises¶
- ValueError
If shape is unknown or size is even.
- vibespatial.raster.label.morphology_gpu(raster: vibespatial.raster.buffers.OwnedRasterArray, operation: str, *, connectivity: int = 4, iterations: int = 1) vibespatial.raster.buffers.OwnedRasterArray¶
GPU binary morphology using NVRTC 3x3 stencil kernels.
Parameters¶
- rasterOwnedRasterArray
Input binary raster (nonzero = foreground).
- operationstr
One of “erode”, “dilate”, “open”, “close”.
- connectivityint
4 or 8 neighbor connectivity for the structuring element.
- iterationsint
Number of times to apply the operation.
Returns¶
- OwnedRasterArray
HOST-resident result raster.
- vibespatial.raster.label.raster_morphology(raster: vibespatial.raster.buffers.OwnedRasterArray, operation: str, *, connectivity: int = 4, iterations: int = 1, structuring_element: numpy.ndarray | None = None, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray¶
Apply binary morphological operation to a raster.
Parameters¶
- rasterOwnedRasterArray
Input binary raster (nonzero = foreground).
- operationstr
One of “erode”, “dilate”, “open”, “close”.
- connectivityint
4 or 8 neighbor connectivity for the structuring element. Ignored when structuring_element is provided.
- iterationsint
Number of times to apply the operation.
- structuring_elementnp.ndarray or None
Custom structuring element (2-D uint8 array with odd dimensions). If None, falls back to the legacy 3x3 SE based on connectivity. Use
make_structuring_element()to build presets.- use_gpubool or None
Force GPU (True), force CPU (False), or auto-dispatch (None).
Returns¶
- OwnedRasterArray
Result raster.
- vibespatial.raster.label.raster_morphology_blackhat(raster: vibespatial.raster.buffers.OwnedRasterArray, structuring_element: numpy.ndarray | None = None, *, connectivity: int = 4, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray¶
Black top-hat transform: morphological closing minus original.
Extracts dark features (holes) smaller than the structuring element. Multiband rasters are processed per-band independently.
Parameters¶
- rasterOwnedRasterArray
Input binary raster (nonzero = foreground).
- structuring_elementnp.ndarray or None
Custom SE (2-D uint8, odd dimensions). Defaults to 3x3 from connectivity.
- connectivityint
4 or 8 (used only if structuring_element is None).
- use_gpubool or None
Force GPU (True), force CPU (False), or auto-dispatch (None).
Returns¶
- OwnedRasterArray
Pixels that were added by closing (dark detail / holes filled).
- vibespatial.raster.label.raster_morphology_tophat(raster: vibespatial.raster.buffers.OwnedRasterArray, structuring_element: numpy.ndarray | None = None, *, connectivity: int = 4, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray¶
White top-hat transform: original minus morphological opening.
Extracts bright features smaller than the structuring element. Multiband rasters are processed per-band independently.
Parameters¶
- rasterOwnedRasterArray
Input binary raster (nonzero = foreground).
- structuring_elementnp.ndarray or None
Custom SE (2-D uint8, odd dimensions). Defaults to 3x3 from connectivity.
- connectivityint
4 or 8 (used only if structuring_element is None).
- use_gpubool or None
Force GPU (True), force CPU (False), or auto-dispatch (None).
Returns¶
- OwnedRasterArray
Pixels that were removed by opening (bright detail).
- vibespatial.raster.label.sieve_filter(labeled: vibespatial.raster.buffers.OwnedRasterArray, min_size: int, *, connectivity: int = 4, replace_value: int = 0, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray¶
Remove small connected components from a labeled raster.
Parameters¶
- labeledOwnedRasterArray
Integer-labeled raster (e.g., from label_connected_components).
- min_sizeint
Minimum pixel count to keep a component.
- connectivityint
4 or 8 neighbor connectivity (used for counting).
- replace_valueint
Value to assign to removed components (default 0 = background).
- use_gpubool or None
Force GPU (True), force CPU (False), or auto-dispatch (None). Auto uses GPU when available and pixel count exceeds threshold.
Returns¶
- OwnedRasterArray
Sieved raster with small components replaced.
- vibespatial.raster.label.logger¶