Segmentação de dados espaciais: conceitos e aplicação
Segmentar não é o mesmo que classificar. A segmentação agrupa pixels em objetos coerentes antes de atribuir um rótulo, produzindo resultados mais limpos e fáceis de analisar. Este guia aborda os conceitos, os algoritmos e sua aplicação no QGIS e no PostGIS.
O que é segmentar e por que isso importa?
Na análise raster tradicional, cada pixel é classificado de forma independente. Isso produz resultados com “sal e pimenta”: pixels isolados classificados incorretamente no meio de uma região homogênea. A segmentação resolve isso agrupando primeiro os pixels em segmentos — regiões contíguas e espectralmente semelhantes — e depois trabalhando com esses objetos.
A diferença é conceitual: em vez de classificar “este pixel é floresta”, você classifica “este objeto de 2,3 ha, com NDVI médio de 0,72 e forma compacta, é floresta densa”. Os objetos resultantes podem ser vetorizados, têm atributos estatísticos (média, desvio, forma) e são muito mais úteis para análise territorial.
Segmentação de imagens versus segmentação de dados tabulares
O termo segmentação aparece em dois contextos distintos nos dados espaciais:
- Segmentação de imagem raster — agrupa pixels por similaridade espectral e contiguidade espacial. O resultado são polígonos. Ferramentas: Orfeo Toolbox, GDAL, rasterio + scikit-image.
- Segmentação de dados vetoriais / tabulares — agrupa entidades (pontos, polígonos, registros) por atributos ou proximidade espacial. O resultado são clusters. Ferramentas: PostGIS, K-Means geoespacial e DBSCAN com coordenadas.
Algoritmos comuns
- MeanShift — agrupa pixels por densidade no espaço espectral-espacial. É robusto e não exige definir o número de clusters, mas é lento em imagens grandes. Implementado no Orfeo Toolbox.
- SLIC (Simple Linear Iterative Clustering) — gera superpixels compactos com tamanho aproximado definido pelo usuário. Muito rápido. Disponível no scikit-image.
- Felzenszwalb — segmentação baseada em grafos, captura bem bordas irregulares. scikit-image.
- Watershed — segmentação morfológica, útil para separar objetos que se tocam (edificações, parcelas).
Segmentação no QGIS com Orfeo Toolbox
Orfeo Toolbox (OTB) é a suíte de sensoriamento remoto do CNES, que pode ser integrada ao QGIS como provedor de algoritmos.
- Instale OTB a partir de otb.orfeo-toolbox.org e configure o provedor em QGIS → Opções → Provedores → OTB.
- Acesse Processamento → Caixa de ferramentas → OTB → Segmentation → Segmentation (otb).
- Selecione a imagem de entrada e o algoritmo (meanshift).
- Ajuste os parâmetros: Spatial radius (raio espacial, px), Range radius (tolerância espectral), Min region size (tamanho mínimo do segmento).
- O resultado é um raster de rótulos no qual cada valor inteiro identifica um segmento.
Segmentação com Python (rasterio + scikit-image)
import numpy as np
import rasterio
from rasterio.features import shapes
from skimage.segmentation import slic
from skimage.color import label2rgb
import geopandas as gpd
from shapely.geometry import shape
# Cargar imagen multibanda
with rasterio.open("imagen_sentinel.tif") as src:
imagen = src.read() # (bandas, filas, cols)
transform = src.transform
crs = src.crs
# Reordenar a (filas, cols, bandas) para scikit-image
img = np.moveaxis(imagen[:3], 0, -1).astype(float)
# Normalizar 0-1
img = (img - img.min()) / (img.max() - img.min())
# Segmentación SLIC
# n_segments: número aproximado de superpíxeles
# compactness: balance forma/espectro (mayor = más compacto)
segmentos = slic(img, n_segments=500, compactness=10, sigma=1, start_label=1)
print(f"Segmentos generados: {segmentos.max()}")
# Calcular estadísticas por segmento (media de cada banda)
from skimage.measure import regionprops_table
import pandas as pd
stats = regionprops_table(
segmentos,
intensity_image=img[:, :, 0], # banda 1 (Rojo)
properties=["label", "area", "mean_intensity", "bbox"]
)
df_stats = pd.DataFrame(stats)
print(df_stats.head())
# Vectorizar segmentos a polígonos GeoPackage
mask = segmentos.astype(np.int32)
poligonos = []
for geom, valor in shapes(mask, transform=transform):
poligonos.append({"geometry": shape(geom), "seg_id": int(valor)})
gdf = gpd.GeoDataFrame(poligonos, crs=crs)
# Unir estadísticas
gdf = gdf.merge(df_stats.rename(columns={"label": "seg_id"}), on="seg_id", how="left")
# Guardar
gdf.to_file("segmentos.gpkg", driver="GPKG")
print(f"Guardados {len(gdf)} segmentos")
Segmentação vetorial com PostGIS
Para dados vetoriais (pontos de amostragem, parcelas, registros cadastrais), o PostGIS permite agrupar por proximidade espacial com ST_ClusterDBSCAN ou ST_ClusterKMeans:
-- Agrupar parcelas en clusters por proximidad (DBSCAN)
-- eps: distancia máxima en metros, minpoints: mínimo de vecinos
SELECT
id_parcela,
ST_ClusterDBSCAN(geom, eps := 100, minpoints := 5)
OVER () AS cluster_id,
geom
FROM parcelas
WHERE municipio = 'Sevilla';
-- Calcular área total y centroide por cluster
SELECT
cluster_id,
COUNT(*) AS n_parcelas,
SUM(ST_Area(geom)) AS area_total_m2,
ST_Centroid(ST_Collect(geom)) AS centroide
FROM (
SELECT id_parcela, geom,
ST_ClusterDBSCAN(geom, 100, 5) OVER () AS cluster_id
FROM parcelas
WHERE municipio = 'Sevilla'
) t
WHERE cluster_id IS NOT NULL
GROUP BY cluster_id
ORDER BY area_total_m2 DESC;
Quando usar cada abordagem
- Orfeo Toolbox no QGIS — imagens grandes, fluxo visual, sem programação. Ideal para produção cartográfica.
- scikit-image + rasterio — integração em pipelines Python, controle total dos parâmetros e processamento automatizado em lote.
- PostGIS ST_ClusterDBSCAN — dados vetoriais ou tabulares com coordenadas, análise territorial sobre registros existentes no banco de dados.