Performs image segmentation using a **mean-shift filtering + clustering** approach on multi-band rasters (RGB or multispectral).
Usage
meanshift_segmenter(
x,
spatialr = 5L,
ranger = 1,
max_iter = 10L,
eps = 0.001,
merge_thr = NA_real_,
min_size = 30L,
eight = TRUE,
scale_bands = TRUE,
smooth = 0L,
return_filtered = FALSE,
output_file = NULL,
verbose = TRUE
)Arguments
- x
A
SpatRasterwith 1 or more bands.- spatialr
Integer \(\ge 1\). Spatial radius (in pixels) of the local neighborhood used during mean-shift filtering. Larger values increase spatial smoothing and runtime.
- ranger
Positive numeric. Range bandwidth controlling how strongly pixels are weighted by spectral similarity during mean-shift filtering. Smaller values preserve edges more aggressively; larger values smooth more.
- max_iter
Integer \(\ge 1\). Maximum number of mean-shift iterations per pixel.
- eps
Positive numeric. Convergence tolerance for the mean-shift update. Iteration stops when the squared shift is \(\le eps^2\).
- merge_thr
Optional numeric threshold used during clustering of the filtered image. Neighboring pixels whose filtered spectral distance is \(\le merge\_thr\) are connected. If
NA(default), the C++ routine uses0.5 * ranger.- min_size
Integer \(\ge 1\). Minimum segment size (in pixels). Components smaller than
min_sizeare merged into the most similar neighboring component (based on filtered spectral distance).- eight
Logical. If
TRUE, uses 8-neighborhood connectivity for clustering and also includes diagonal offsets in the mean-shift spatial neighborhood. IfFALSE, uses 4-neighborhood.- scale_bands
Logical. If
TRUE(default), standardizes each band to z-scores(x - mean) / sdusingna.rm = TRUE. This is often recommended for multispectral imagery with bands in different numeric ranges.- smooth
Integer \(\ge 0\). Optional mean filter window size (pixels) applied to the raster prior to mean-shift. If
0(default), no pre-smoothing is applied. If> 0, asmooth x smoothmean filter is applied viaterra::focal().- return_filtered
Logical. If
FALSE(default), returns only the segmentation labels raster. IfTRUE, also returns the filtered multi-band raster produced by mean-shift.- output_file
Optional character string. If provided, the resulting segmentation raster is written to this file via
terra::writeRaster().- verbose
Logical. If
TRUE, prints progress messages from the R wrapper. IfFALSE, runs quietly and suppresses console output from the underlying C++ routine.
Value
If return_filtered = FALSE, a single-layer
SpatRaster of integer segment labels
named "segment_id".
If return_filtered = TRUE, a list with:
segmentsSingle-layer labels
SpatRaster.filteredMulti-layer
SpatRasterwith the mean-shift filtered bands (same number of layers asx).
Details
The method first applies mean-shift *range filtering* (edge-preserving smoothing) in a local spatial neighborhood, then groups pixels into connected components based on similarity of the filtered values. Small components can be merged into the most similar neighboring component.
This is a high-level R wrapper around a C++ implementation optimized for raster grids and multi-band imagery.
**Algorithm outline (C++ implementation):**
Validity mask: A pixel is marked invalid if any band is
NAor not finite. Invalid pixels receive label0in C++ and are converted toNAin the output raster.Mean-shift filtering: For each valid pixel, the algorithm iteratively updates a spectral vector \(y\) using a weighted mean of the local neighborhood within
spatialr. The weight is a product of:a Gaussian spatial kernel (sigma \(\approx spatialr/2\)), and
a Gaussian range kernel based on spectral distance with bandwidth
ranger.
Iteration stops after
max_itersteps or when the update magnitude is beloweps.Clustering: The filtered image is clustered by building connected components on the grid. Neighboring pixels are linked when the squared distance between their filtered spectral vectors is below
merge_thr^2. Connectivity followseight.Minimum size enforcement: Components smaller than
min_sizeare merged into the most similar neighboring component using local neighbor search.Relabeling: Components are relabeled to consecutive integers
1..K. Invalid pixels remainNAin the R output.
Internally, pixel values are passed to C++ in a band-major layout
(all pixels of band 1, then all pixels of band 2, ...). The wrapper handles
the conversion from terra values.
Examples
if (FALSE) { # \dontrun{
library(terra)
r <- terra::rast(sample_raster_path())
# MeanShift segmentation (labels only)
seg <- meanshift_segmenter(
r,
spatialr = 5,
ranger = 1.0,
min_size = 50,
eight = TRUE,
scale_bands = TRUE,
smooth = 0,
verbose = TRUE
)
plot(seg)
# Also return the filtered image
res <- meanshift_segmenter(r, return_filtered = TRUE, verbose = FALSE)
plot(res$segments)
} # }