Skip to contents

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 SpatRaster with 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 uses 0.5 * ranger.

min_size

Integer \(\ge 1\). Minimum segment size (in pixels). Components smaller than min_size are 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. If FALSE, uses 4-neighborhood.

scale_bands

Logical. If TRUE (default), standardizes each band to z-scores (x - mean) / sd using na.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, a smooth x smooth mean filter is applied via terra::focal().

return_filtered

Logical. If FALSE (default), returns only the segmentation labels raster. If TRUE, 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. If FALSE, 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:

segments

Single-layer labels SpatRaster.

filtered

Multi-layer SpatRaster with the mean-shift filtered bands (same number of layers as x).

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):**

  1. Validity mask: A pixel is marked invalid if any band is NA or not finite. Invalid pixels receive label 0 in C++ and are converted to NA in the output raster.

  2. 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_iter steps or when the update magnitude is below eps.

  3. 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 follows eight.

  4. Minimum size enforcement: Components smaller than min_size are merged into the most similar neighboring component using local neighbor search.

  5. Relabeling: Components are relabeled to consecutive integers 1..K. Invalid pixels remain NA in 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)
} # }