Raster Object Features¶
Features describe each object's raster values, shape, and texture. Add them to
segment polygons with extract_features(). You can change the measurements
without repeating segmentation; the result preserves the original geometry and
attributes and adds numeric feature columns.
All feature inputs use zero-based integer band indices into the loaded image.
If a file was loaded with open_geotiff(path, bands=[4, 1, 2]), feature bands
0, 1, and 2 refer to those loaded bands in that order. The loader's file-band
argument is one-based. Choose band positions explicitly for your raster.
Extract object features¶
This example uses a raster with at least four loaded bands and a projected CRS.
Choose the band positions for your image. For a geographic CRS, use
shape_units="pixel" to measure shape relative to the raster grid.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
Feature column names record the calculation and band positions. Depending on the measurements you request, examples include:
b0_median,b3_p90,b0_valid_fractionindex_ndvi_b3_b0_mean,index_vari_b0_b1_b2_stdshape_area,shape_elongationb0_glcm_entropy_d1,b0_glcm_entropy_d4b0_local_entropy_r3_mean,b0_local_entropy_r3_std
Calling extract_features() again replaces requested columns with freshly
calculated values and preserves unrelated columns. It does not modify the input
table or raster. spectral=(), percentiles=() disables distributions;
bands=() calculates distributions only for requested indices. Shape and texture
are opt-in. Without options, extraction returns all spectral statistics below
and the 10th and 90th percentiles for all loaded bands.
Band statistics¶
| Feature | Definition |
|---|---|
mean |
Arithmetic mean of finite valid pixels |
std, variance |
Population standard deviation and variance (ddof=0) |
min, max |
Minimum and maximum valid values |
median |
Median valid value |
iqr |
75th percentile minus 25th percentile |
mad |
Median absolute deviation from the median, without a scaling factor |
skewness |
Standardized third moment, using SciPy's bias=True convention |
kurtosis |
Excess kurtosis (normal distribution: 0), fisher=True, bias=True |
valid_count |
Number of valid pixels within the polygon |
valid_fraction |
Valid count divided by polygon-covered pixel centers within the raster |
percentiles=(5, 50, 95) adds p5, p50, and p95 columns using linear
interpolation. Fractional requests are supported: 2.5 produces p2p5.
Constant samples have zero standard deviation, variance, IQR, and MAD. Their skewness and kurtosis are undefined and returned as NaN. Objects with no valid samples have count 0 and NaN distribution measurements. Their valid fraction is 0 when they cover raster pixels, and NaN when they cover none.
Spectral indices and color¶
indices maps each calculation name to an ordered tuple of band indices. For
example, {"ndvi": (3, 0)} means (b3 - b0) / (b3 + b0). The caller chooses the
correct positions; specifying an index name never discovers or reorders bands.
In the formulas below, a, b, and c mean pixel values from the first, second,
and third numeric band positions supplied in the tuple, respectively. Wavelength descriptions explain
the conventional index definitions; they are not API parameter names.
| Name | Formula | Required input order |
|---|---|---|
normalized_difference |
(a-b)/(a+b) |
Any two chosen bands |
ndvi |
(a-b)/(a+b) |
NIR, red |
gndvi |
(a-b)/(a+b) |
NIR, green |
ndre |
(a-b)/(a+b) |
NIR, red edge |
ndwi |
(a-b)/(a+b) |
Green, NIR (McFeeters water index) |
mndwi |
(a-b)/(a+b) |
Green, SWIR |
ndmi |
(a-b)/(a+b) |
NIR, SWIR1 |
nbr |
(a-b)/(a+b) |
NIR, SWIR2 |
ndbi |
(a-b)/(a+b) |
SWIR1, NIR |
ratio |
a/b |
Any two chosen bands |
difference |
a-b |
Any two chosen bands |
exg |
(2*b-a-c)/(a+b+c) |
Red, green, blue; normalized excess green |
vari |
(b-a)/(b+a-c) |
Red, green, blue |
brightness |
Arithmetic mean | One or more chosen bands |
Each index is computed per pixel, then summarized using the requested spectral statistics and percentiles. Mean pixel NDVI is generally different from NDVI computed from object band means. Inputs retain their original values; segmentation normalization is never used for feature calculations. Apply any required radiometric calibration before extracting features.
Pixels need valid finite values in every required band. Zero denominators and nonfinite results become NaN, which are excluded from summaries. Valid results are not clipped to an assumed index range. Source arrays are unchanged and integer inputs are converted before arithmetic to avoid unsigned subtraction.
To obtain an index image directly:
1 2 3 | |
compute_index() honors masked arrays and nonfinite values. When passing a plain
array directly, apply any file NoData mask first. extract_features() applies
the Image source validity masks automatically.
Index definitions can be compared with the original references collected in Awesome Spectral Indices.
Size and shape¶
Pass shape=True for all measurements, or a list such as
shape=("area", "circularity", "solidity").
| Feature | Definition |
|---|---|
area |
Polygon area, excluding holes |
perimeter |
All boundary lengths, including holes |
major_axis_length, minor_axis_length |
Long and short sides of the minimum-area oriented bounding rectangle |
elongation |
Major axis length / minor axis length |
circularity |
4 * pi * area / perimeter**2 |
solidity |
Area / convex-hull area |
rectangularity |
Area / oriented bounding rectangle area |
orientation |
Major rectangle axis angle in degrees, in [0, 180) |
hole_count |
Number of interior polygon rings, summed for multipolygons |
shape_units="map" requires a projected CRS. Area is in squared CRS units,
lengths in CRS units, and angles run counterclockwise from the positive x-axis.
Units may be feet rather than meters; inspect the raster CRS.
shape_units="pixel" first transforms geometry through the full inverse affine,
including rotation, shear, and unequal pixel sizes. Lengths are in pixels, area
in square pixels, and angles run from increasing columns toward increasing rows.
For tied rectangle axes, the smaller axis angle is chosen.
Measurements use the supplied polygon geometry. Feature masks affect sampled pixels but do not redefine its shape. Empty geometries yield NaN shape features. These formulas are explicit because software packages use different meanings for names such as compactness and roundness. Compare ENVI's shape definitions.
Texture¶
Texture describes spatial variation within an object. A gray-level co-occurrence matrix (GLCM) counts pairs of pixel values at specified distances and directions. Local entropy measures variation within a neighborhood.
Add texture measurements to an object table with TextureConfig. All distances
and radii are in pixels:
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
GLCM pairs count only when both endpoints are finite valid pixels inside the same object. Polygon holes, other objects, NoData, and pixels outside a supplied mask never contribute artificial zero-valued observations. Pair distances describe endpoint separation; intermediate pixels do not determine pair validity.
Values are quantized into levels uniform bins, from 2 to 256. By default, a
separate range is fitted to each band's finite included pixels over the whole
image, then reused for every object. It is not fitted separately to each object.
Use value_range=(0, 10000) to fix the bounds explicitly, especially when comparing
scenes. Out-of-range values are clipped before binning. Constant bands occupy
one bin. Integer rasters are not cast directly to 8-bit values.
The available features are:
contrast,dissimilarity,homogeneity,ASM,energy,correlation, using scikit-image's definitions.entropy:-sum(p * log2(p))over nonzero GLCM probabilities.mean:sum(i * p[i,j]), the first marginal mean.variance:sum((i - mean_i)**2 * p[i,j]).maximum_probability: the largest GLCM probability.cluster_shade,cluster_prominence: third and fourth moments ofi + j - mean_i - mean_j, respectively.
Matrices are normalized, and symmetric=True includes both pair orders. Each
distance is reported separately. The default angle_aggregation="mean" averages
feature values over directions that have valid pairs, giving each such direction
equal weight. angle_aggregation="none" produces _a0, _a1, etc., referring to
positions in the supplied angles tuple. Angles are in radians, measured from
increasing columns toward increasing rows.
A direction with no valid pairs produces NaN. A distance with no usable direction also produces NaN. Constant valid pairs have contrast 0 and correlation 1, following scikit-image's convention.
entropy_radii=(1, 3) additionally calculates local Shannon entropy in bits using
disk footprints of those radii. Only valid pixels within the object participate
in each window. The mean and population standard deviation across valid window
centers become object features. Set features=() for local entropy alone.
Configuration and fitted bounds are available in objects.attrs["obia_features"].
This is in-memory metadata; save it separately if needed alongside a GeoPackage.
Extract features during segmentation¶
segment() combines boundary creation and feature extraction. Pass
feature_options to choose measurements in the same call:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
These options are forwarded to create_objects(). They take precedence over
individual calc_* switches. Without feature_options, segment() uses its
default statistics and texture measurements, with names such as b0_mean and
b0_contrast.
For create_objects(), calculate_spectral=False disables band and index
distributions, and calculate_textural=False disables texture. This permits
shape-only extraction. texture_config selects texture measurements;
spectral_features selects spectral statistics. Without an explicit
texture band list, create_objects() uses textural_bands or all loaded bands;
the standalone extract_features() instead defaults texture to its bands selection.
Missing data and spatial alignment¶
Features are calculated from image.img_data, so they also work with in-memory
images and after the source file has been closed. open_geotiff() retains source
NoData/dataset masks in image.valid_mask, in loaded band order. A manually
constructed Image can supply the same optional boolean array, with shape
(height, width, bands). Nonfinite values and NumPy masked-array samples are
always excluded.
An additional mask has shape (height, width) and applies to all bands. Polygon
sampling uses pixel centers and honors holes. Segments must have the same CRS as
the raster; reproject them explicitly before extraction. Polygons outside the
raster retain their geometry and receive undefined raster measurements.
Pass the result to the labelling and classification workflow. Inspect missing values before training; tiny objects may have no texture pairs, and some indices are undefined where their denominators vanish.