EstevezAlvarez
QGIS Segmentação Geoinformação PostGIS

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.

Imagem raster (pixels individuais) segmentar Segmentos (objetos) (regiões homogêneas) Vegetação Urbano Água Solo exposto cada pixel tratado separadamente objetos com atributos estatísticos
A segmentação agrupa pixels espectralmente semelhantes e espacialmente contíguos em objetos coerentes, passando da análise pixel a pixel para a análise orientada a objetos.

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:

Imagem GeoTIFF multibanda Segmentação MeanShift SLIC / FELZ Atributos média, desvio, área forma, NDVI Classificação por objeto RF / SVM Vetorizar polígonos GeoPackage PostGIS análise espacial exportar, relatar
Pipeline OBIA (Object-Based Image Analysis): segmentação → extração de atributos → classificação por objeto → vetorização → carga no PostGIS.

Algoritmos comuns

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.

  1. Instale OTB a partir de otb.orfeo-toolbox.org e configure o provedor em QGIS → Opções → Provedores → OTB.
  2. Acesse Processamento → Caixa de ferramentas → OTB → Segmentation → Segmentation (otb).
  3. Selecione a imagem de entrada e o algoritmo (meanshift).
  4. Ajuste os parâmetros: Spatial radius (raio espacial, px), Range radius (tolerância espectral), Min region size (tamanho mínimo do segmento).
  5. 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