Skip to contents

Segments a multi-band image using the **Felzenszwalb-Huttenlocher** graph-based region merging algorithm (often used as an efficient OBIA-style "superpixel" generator). Each pixel is a node in a grid graph; edges connect neighboring pixels (4- or 8-neighborhood) with weights given by spectral distance. Regions are merged in increasing edge-weight order subject to an adaptive internal-difference criterion controlled by k, with an optional cleanup pass that enforces a minimum region size.

Usage

fh_segmenter(
  x,
  k = 1,
  min_size = 50,
  eight = TRUE,
  scale_bands = TRUE,
  smooth = 0,
  output_file = NULL,
  verbose = TRUE
)

Arguments

x

A SpatRaster with one or more layers (bands). Bands should be numeric and represent co-registered imagery (e.g., RGB, VNIR/SWIR).

k

Numeric scalar. Scale/threshold parameter controlling region merging. Larger k generally yields fewer, larger segments.

min_size

Integer scalar. Minimum allowed segment size (in pixels). Segments smaller than this are merged during a cleanup pass.

eight

Logical. If TRUE, use 8-neighborhood connectivity; if FALSE, use 4-neighborhood connectivity.

scale_bands

Logical. If TRUE (recommended), each band is z-score scaled using its mean and standard deviation computed with na.rm=TRUE.

smooth

Integer scalar. If > 0, applies a mean (box) filter of size smooth x smooth to each band before segmentation. Use small odd values (e.g., 3 or 5). Set to 0 to disable smoothing.

output_file

Optional character string. If provided, the resulting segmentation raster is written to this file via terra::writeRaster().

verbose

Do progress messages? (default: TRUE)

Value

A single-layer SpatRaster with integer segment IDs in the layer "segment_id". Invalid pixels are NA.

Details

This wrapper accepts a SpatRaster and returns a single-layer label raster with integer segment IDs. It optionally applies a mean (box) filter prior to segmentation and z-score scales each band to stabilize the distance threshold across bands and sensors.

**Algorithm behavior**

  • k controls the tendency to merge: larger values typically produce larger segments.

  • min_size enforces a minimum mapping unit by merging small regions to the most similar neighbor in a post-processing step.

  • eight toggles 8-neighborhood (Queen) vs 4-neighborhood (Rook) connectivity; 8-neighborhood usually yields more "diagonal-safe" objects.

  • scale_bands applies per-band z-score scaling using na.rm=TRUE.

**NA handling** Pixels with NA in any band are treated as invalid by the underlying C++ implementation and returned as NA in the output label raster. If your scene contains large NA areas, consider masking/cropping/filling prior to segmentation to avoid creating many invalid edge cases.

**Performance notes** The heavy lifting is implemented in Rcpp/C++ and is designed for large rasters. For very large scenes, prefer tiling.

See also

Examples

if (FALSE) { # \dontrun{
library(terra)

r <- rast("image.tif")

seg <- fh_segmenter(
  r,
  k = 0.5,
  min_size = 20,
  eight = TRUE,
  scale_bands = TRUE,
  smooth = 3
)

# Overlay boundaries on RGB
rgb <- stretch(r[[1:3]])
bnd <- boundaries(seg, directions = 8)
plotRGB(rgb, r=1, g=2, b=3, stretch="lin")
plot(bnd, add=TRUE, col="yellow", lwd=0.8)
} # }