Segmentation¶
Segmentation divides an image into regions that can be measured and classified as objects. OBIA connects image segmentation algorithms to geospatial rasters, returning object IDs, polygon boundaries, and feature tables.
Load a raster¶
The examples use numeric band indices. Adjust them to the bands in your raster; the first example assumes at least four loaded bands.
1 2 3 4 | |
open_geotiff() reads all bands by default. Its bands argument uses one-based
Rasterio band numbers. Once loaded, segmentation_bands and statistics_bands
use zero-based indexes into the loaded image.
Create segment objects¶
Use segment() to create boundaries and calculate features in one call:
1 2 3 4 5 6 7 8 9 10 11 | |
objects.segments is the polygon table with one row per object.
objects.labels is a raster of the corresponding object IDs. SLIC's n_segments
sets an approximate number of regions; inspect the boundaries and adjust it for
the sizes of objects you want to distinguish.
Choose an algorithm¶
The method names match the functions in
scikit-image's segmentation API.
| Method | Input bands | Additional inputs | Result |
|---|---|---|---|
slic |
One or more | Optional n_segments, compactness; slic_zero=True enables SLICO |
Superpixels |
quickshift |
One or more | Optional kernel_size, max_dist, ratio |
Mode-seeking regions |
felzenszwalb |
One or more | Optional scale, sigma, min_size |
Graph-based regions |
watershed |
Exactly one | Optional markers array or count, compactness |
Basins in the input surface |
random_walker |
One or more | Required labels seed array |
Regions grown from seeds |
chan_vese |
Exactly one | Optional init_level_set, max_num_iter |
Foreground objects |
morphological_chan_vese |
Exactly one | Required num_iter; optional init_level_set |
Foreground objects |
morphological_geodesic_active_contour |
Exactly one | Required num_iter; optional init_level_set, balloon |
Foreground objects |
active_contour |
One or more | Required closed snake coordinates |
Pixels inside the fitted contour |
flood |
Exactly one | Required seed_point; optional tolerance |
Region connected to the seed |
List supported methods programmatically:
1 2 3 | |
SLIC is the default. Algorithm-specific keyword arguments are passed to the underlying function. The examples below explain the required inputs and how OBIA converts each result to objects.
Superpixels and graph segmentation¶
1 2 3 4 5 6 7 8 9 | |
Felzenszwalb controls object size indirectly: larger scale generally produces
larger regions.
Quickshift's convert2lab defaults to True for three selected bands and False
otherwise. For three bands that are not RGB, pass convert2lab=False; the same
option is available for SLIC. Channels are always stored last in OBIA.
Seeded segmentation¶
Markers use pixel positions, not map coordinates. Random walker requires an integer array: positive values identify seed classes, zero means unlabelled, and negative values mark inactive pixels. Watershed accepts an integer marker array or a desired basin count; without markers, scikit-image finds local minima.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Choose seed locations that represent the regions you want. Watershed operates on
the selected band as a surface: low values are flooded first. To segment a
precomputed gradient or other elevation surface, put that surface in a raster
band and select it. watershed_line=True leaves separating pixels as background.
Random walker's mode="cg_mg" requires the optional upstream dependency pyamg.
Level sets and active contours¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Morphological geodesic active contours need an edge-stopping image. OBIA computes
skimage.segmentation.inverse_gaussian_gradient from the selected band by default.
gradient_kwargs controls that preprocessing. Alternatively, pass gimage=array
with a finite (height, width) edge-stopping image; it is used as supplied and
cannot be combined with gradient_kwargs.
init_level_set also accepts an array matching the raster's spatial shape.
Scikit-image's disk_level_set and checkerboard_level_set helpers can create one.
For a parametric active contour, supply initial (row, column) pixel coordinates
around the object. Do not duplicate the endpoint of a periodic snake:
1 2 3 4 5 6 7 8 9 10 | |
OBIA fills the fitted closed contour to create objects. Open snakes do not define an enclosed region, so use scikit-image directly for nonperiodic boundary conditions.
Flood region growing¶
1 2 3 4 | |
The tolerance is in normalized [0, 1] units by default. To use the raster's
original units, pass normalize=False and a tolerance in those units.
Band values, masks, and output¶
By default, OBIA normalizes each selected band independently to [0, 1]. Constant
bands become zero. The source raster is never modified. normalize=False preserves
input values. Algorithms that require a scalar image need one selected band;
OBIA does not silently average RGB or multispectral bands.
segmentation_bands controls boundaries. statistics_bands controls the bands
summarized afterward, and can include bands that were not used for segmentation.
Feature statistics use the original raster values.
Use feature_options to request spectral distributions, indices specified with
numeric band positions, shape measurements, and configurable texture. Alternatively,
run obia.features.extract_features() on existing polygons to change measurements
without rerunning segmentation. See raster object features
for configuration, formulas, and examples.
An optional boolean mask with shape (height, width) restricts output to True
pixels. SLIC, watershed, and random walker use the mask during segmentation.
Other algorithms operate on the full prepared image, then their output is clipped;
the mask is not a barrier to their evolution or region growing. Excluded input
pixels are set to zero in the working copy. Nonfinite values inside the mask are
rejected; nonfinite values outside it are ignored. An entirely empty mask returns
no objects.
The returned Segments object stores:
objects.labels: an int32 array with a unique positive ID per connected object.objects.segments: a GeoDataFrame whosesegment_idvalues match the label image.objects.methodandobjects.params: the method and explicitly supplied parameters.
Zero denotes background or excluded pixels. Binary methods polygonize only the foreground. Superpixel label zero is retained as an object and assigned a positive ID. Disconnected pieces receive different object IDs, even when an upstream algorithm gives them the same label. Upstream marker IDs are therefore not class labels in the output table; use the labelling workflow to attach training classes.
Scikit-image options that change the return type (return_tree=True,
extended_output=True, return_full_prob=True) raise a clear error. Use the
upstream functions for trees, energies, probability maps, or open contour coordinates.
Create labels or polygons without features¶
Use the individual operations when you want to inspect boundaries or calculate features separately:
1 2 3 4 5 6 | |
Boundary-processing helpers such as find_boundaries, clear_border, and
join_segmentations can be used directly from scikit-image. For region growing
that produces object polygons, use method="flood"; flood_fill instead paints
the selected region into an image.
Continue with object analysis¶
Inspect the boundaries, then add raster features or label and classify the objects. You can also add point-cloud features to the same polygon table.
For images that are impractical to process in memory, the large-raster workflow provides tiled SLIC segmentation.