Skip to main content

Shepherd segmentation (Remote Sensing 2019) in pure NumPy/SciPy - runs in Pyodide/WebAssembly and CPython. Bit-exact compat mode vs pyshepseg; algorithm-faithful by default.

Project description

🛰️ shepherd-wasm

Segmentación Shepherd (Shepherd, Bunting & Dymond 2019) en NumPy/SciPy puro — corre en WebAssembly.

Pure NumPy/SciPy implementation of Shepherd segmentation for satellite imagery. Bit-exact against pyshepseg, numba-free, so it runs in the browser via Pyodide/WebAssembly — and just as happily in regular CPython.

🎬 Demo en vivo (todo corre en tu navegador): https://abxda.github.io/portable-satelital/lab/index.html?path=Taller_ML_Urbano_WASM.ipynb


¿Por qué existe esto?

La implementación de referencia, pyshepseg, acelera sus bucles críticos con numba (JIT sobre LLVM). Eso la hace rápida — y también imposible de ejecutar en WebAssembly: el sandbox WASM prohíbe la generación de código nativo en tiempo de ejecución, y numba no existe (ni existirá) en Pyodide.

shepherd_pure.py es un port fiel, línea por línea, de pyshepseg 2.0.5 a NumPy/SciPy vectorizado. Sin numba, sin C, sin compilación: un solo archivo que corre idéntico en CPython y dentro de una pestaña del navegador.

Fidelidad: bit-exacto, no "parecido"

Validado contra pyshepseg 2.0.5 sobre ventanas reales de una geomediana Sentinel-2 (12 bandas, int16, Aguascalientes, México), compartiendo el mismo objeto KMeans (kmeansObj) para aislar los pasos reimplementados:

Ventana minSegmentSize ARI Píxeles idénticos Segmentos (ref / puro)
256×256 (centro) 50 1.000000 100 % 587 / 587
512×512 (centro) 50 1.000000 100 % 2 082 / 2 082
512×512 (borde, con nodata) 50 1.000000 100 % 2 191 / 2 191
1024×1024 100 1.000000 100 % 4 700 / 4 700

Misma cuenta de píxeles sueltos eliminados, mismos segmentos pequeños fusionados, mismo maxSpectralDiff automático. La fidelidad incluye los detalles que no aparecen en el paper: IDs de clump por orden de descubrimiento en barrido raster, tope MAX_CLUMP_SIZE=10000, la pasada previa de eliminación de píxeles sueltos, y los desempates "primero encontrado" en orden fila→columna. Reproduce la validación con validate_shepherd.py.

Rendimiento (sorpresa)

Tile pyshepseg (numba, incluye ~4 s de JIT) shepherd-wasm (CPython) shepherd-wasm (navegador, Pyodide)
256² ×12 bandas 4.5 s 0.6 s 0.8 s
512² ×12 4.4 s 1.8 s
1024² ×12 4.7 s 17.5 s

En tiles chicos gana al original (se ahorra el costo del JIT); en tiles grandes el procesamiento por mosaico — el mismo patrón de pyshepseg.tiling — mantiene todo en la zona dulce.

Instalación

pip install shepherd-wasm
import shepherd_wasm   # módulo canónico (import shepherd_pure sigue funcionando como alias)

Uso

import numpy as np
import shepherd_wasm

# img: ndarray (n_bandas, filas, columnas); usa float32 para evitar wraparound
res = shepherd_wasm.doShepherdSegmentation(
    img.astype(np.float32),
    numClusters=60,
    minSegmentSize=50,
    maxSpectralDiff='auto',
    imgNullVal=nodata,        # o None
    fixedKMeansInit=True,     # determinista (recomendado para docencia)
)
res.segimg                    # ndarray (filas, columnas) con IDs de segmento; 0 = nulo
res.singlePixelsEliminated, res.smallSegmentsEliminated, res.maxSpectralDiff

Misma firma y semántica que pyshepseg.shepseg.doShepherdSegmentation — es un reemplazo directo. Dependencias: numpy, scipy, scikit-learn (las tres existen en Pyodide).

En Pyodide/JupyterLite, recuerda que el auto-cargador no ve los imports internos de un módulo: ejecuta import scipy.ndimage, sklearn.cluster en una celda antes de import shepherd_pure.

Crédito y licencia

  • Algoritmo: Shepherd, J.D.; Bunting, P.; Dymond, J.R. Operational Large-Scale Segmentation of Imagery Based on Iterative Elimination. Remote Sensing 2019, 11(6), 658. DOI 10.3390/rs11060658.
  • Implementación de referencia: pyshepseg © Neil Flood & Sam Gillingham (MIT). Este proyecto es un port derivado y conserva su licencia y crédito.
  • Port a NumPy puro, validación y empaque WASM: abxda × ClaudeDr. Abel Coronado en colaboración con Claude (Anthropic), 2026.

MIT. Ver LICENSE.

⚠️ Divergencia documentada respecto a pyshepseg: maxClumpSize

pyshepseg introduce en su clump() un tope duro MAX_CLUMP_SIZE = 10000 píxeles (optimización del port a numba, ausente en el paper y en RSGISLib, la implementación canónica de los mismos autores). Consecuencia: cualquier objeto homogéneo mayor a 10,000 px — un lago, una presa, una mancha urbana — queda rebanado en tiras paralelas (la huella del frente del flood fill) que la eliminación iterativa jamás fusiona, porque cada tira supera minSegmentSize.

Caso real (Laguna de Yuriria, geomediana Sentinel-2 12 bandas): con el tope, el segmento mayor mide 11,767 px y el lago queda en ~30 tiras; sin el tope, 387,989 px — el lago entero, estructuralmente idéntico al resultado de RSGISLib.

Por eso esta biblioteca diverge deliberadamente:

maxClumpSize Comportamiento
None (default) Fiel al algoritmo (paper / RSGISLib): objetos grandes enteros
10000 Modo compatibilidad: reproduce bit a bit a pyshepseg, incluido su artefacto (es lo que usa validate_shepherd.py)

La validación es por lo tanto de dos niveles: compatibilidad (ARI 1.0 contra pyshepseg con maxClumpSize=10000) y corrección (objetos grandes íntegros, consistente con RSGISLib).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

shepherd_wasm-1.1.0.tar.gz (10.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

shepherd_wasm-1.1.0-py3-none-any.whl (12.1 kB view details)

Uploaded Python 3

File details

Details for the file shepherd_wasm-1.1.0.tar.gz.

File metadata

  • Download URL: shepherd_wasm-1.1.0.tar.gz
  • Upload date:
  • Size: 10.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for shepherd_wasm-1.1.0.tar.gz
Algorithm Hash digest
SHA256 7e6106a1401ad0812c2339891dae0106127eac0643feecdc97f0a6bb2b2db435
MD5 25b63d76ccf96ddeb1c27b19527497d3
BLAKE2b-256 b6c39963ce6f77895e7797056e7a97b5649689a3de4fa8a7ae4b067c640b9d11

See more details on using hashes here.

Provenance

The following attestation bundles were made for shepherd_wasm-1.1.0.tar.gz:

Publisher: publish.yml on abxda/shepherd-wasm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file shepherd_wasm-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: shepherd_wasm-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 12.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for shepherd_wasm-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 580b1b012160867985bc6446c6e93ff5f0a37bf548a16c9786bed902332bd25c
MD5 8559084eaf47aff5faae5871c1601e75
BLAKE2b-256 4238c65f749c7bd3fc0d93de507ff78787b9fb6ee2ba840b0fdcd9d5e88f9cbd

See more details on using hashes here.

Provenance

The following attestation bundles were made for shepherd_wasm-1.1.0-py3-none-any.whl:

Publisher: publish.yml on abxda/shepherd-wasm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page