Install
openclaw skills install @ruiduobao/water-body-extractionAutomatic water body extraction from multi-band satellite imagery using NDWI and MNDWI indices. Supports Landsat 8/9 and Sentinel-2, Otsu threshold optimization, and vector output.
openclaw skills install @ruiduobao/water-body-extractionAutomatically extract water bodies from satellite imagery using spectral indices (NDWI / MNDWI). Designed for Landsat 8/9 and Sentinel-2 multi-band GeoTIFF inputs.
| Sensor | Green | NIR | SWIR |
|---|---|---|---|
| Landsat 8/9 | B3 | B5 | B6 |
| Sentinel-2 | B3 | B8 | B11 |
python scripts\water-body-extraction.py extract \
--input image.tif \
--sensor landsat8 \
--index mndwi \
--output water_mask.tif \
--vector water_boundary.geojson
python scripts\water-body-extraction.py threshold \
--input image.tif \
--sensor landsat8 \
--index ndwi \
--method otsu
python scripts\water-body-extraction.py batch \
--input-dir ./images/ \
--sensor sentinel2 \
--index mndwi \
--output-dir ./masks/ \
--vector-dir ./vectors/
pip install rasterio>=1.3.0 numpy>=1.21.0 scipy>=1.7.0 shapely>=1.8.0 fiona>=1.8.0 tqdm>=4.64.0
# Or: pip install -r scripts/requirements.txt
--input: Path to multi-band GeoTIFF--sensor: Sensor type (landsat8, landsat9, sentinel2)--index: Index to compute (ndwi, mndwi)--threshold: Manual threshold value (default: auto via Otsu)--output: Output raster mask path--vector: Output vector GeoJSON path (optional)--input-dir: Directory for batch processing--output-dir: Output directory for batch masks--vector-dir: Output directory for batch vectors--method: Threshold method (otsu, manual)--json: Output statistics as JSONrasterio>=1.3.0
numpy>=1.21.0
scipy>=1.7.0
shapely>=1.8.0
fiona>=1.8.0
tqdm>=4.64.0
| Index | Best For | Caution |
|---|---|---|
| NDWI | Open water, rural areas | Built-up areas may show false positives |
| MNDWI | Urban areas, mixed land cover | Suppresses built-up noise; may miss turbid water |
Recommendation: Use MNDWI for urban/suburban scenes; NDWI for natural landscapes.
Clouds and cloud shadows cause false water detections. Best practices:
Remove small noise polygons with --min-area:
python scripts\water-body-extraction.py extract \
--input image.tif --sensor landsat8 --index mndwi \
--output water_mask.tif --vector water_boundary.geojson \
--min-area 1000
--min-area is in map units (m² for projected CRS). Typical values: 500–5000 m².
For rasters >1 GB:
--tile-size 4096 --overlap 256--compress lzw to reduce output sizeIn addition to GeoJSON, Shapefile and GeoPackage output are supported:
python scripts\water-body-extraction.py extract \
--input image.tif --sensor landsat8 --index mndwi \
--output water_mask.tif --vector water_boundary.gpkg --vector-format gpkg
Validate results against reference data:
Visualize results in QGIS or Python:
import rasterio
import matplotlib.pyplot as plt
with rasterio.open('water_mask.tif') as src:
mask = src.read(1)
plt.imshow(mask, cmap='Blues')
plt.title('Water Body Extraction Result')
plt.show()
If this tool supports your research, please cite:
@software{water_body_extraction,
author = {ruiduobao},
title = {Water Body Extraction Tool},
url = {https://github.com/ruiduobao/water-body-extraction},
version = {0.1.0},
year = {2024},
}
| Error | Cause | Solution |
|---|---|---|
ConnectionError | Network issue | Check internet, retry |
HTTP 429 | Rate limit | Wait 60s, retry |
ValueError | Invalid input | Check parameter format |
| Empty output | No data / all cloud | Try different image or adjust threshold |
ModuleNotFoundError | Missing dep | Run pip install |
MemoryError | Raster too large | Use tiling (--tile-size) or increase RAM |
| All water / no water | Threshold issue | Try manual threshold or different index |
Local raster processing — uses pre-downloaded satellite imagery. No external API calls.
for img in scenes/*.tif; do
python scripts\water-body-extraction.py extract --input "$img" --index MNDWI --sensor sentinel2 --output "water_$(basename $img)"
sleep 1
done
# .github/workflows/monthly-water.yml
name: Monthly Water Extraction
on:
schedule:
- cron: '0 0 1 * *' # Monthly
jobs:
extract:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- run: pip install numpy rasterio scipy
- run: |
python scripts\water-body-extraction.py extract \
--input data/latest_scene.tif \
--index MNDWI --sensor sentinel2 --otsu \
--output data/water_latest.tif
# Extract water and export as GeoJSON vector
python scripts\water-body-extraction.py extract --input scene.tif --index MNDWI --vector --output water.geojson
# Import to PostGIS
ogr2ogr -f PostgreSQL PG:"dbname=gis_db" water.geojson -nln water_bodies
--threshold 0.0 for manual control--min-area 100 to filter small noise polygons--cloud-mask with QA_PIXEL to improve accuracy in cloudy scenes使用光谱指数(NDWI / MNDWI)从卫星影像中自动提取水体。支持 Landsat 8/9 和 Sentinel-2 多波段 GeoTIFF 输入。
| 传感器 | Green | NIR | SWIR |
|---|---|---|---|
| Landsat 8/9 | B3 | B5 | B6 |
| Sentinel-2 | B3 | B8 | B11 |
python scripts\water-body-extraction.py extract \
--input image.tif \
--sensor landsat8 \
--index mndwi \
--output water_mask.tif \
--vector water_boundary.geojson
python scripts\water-body-extraction.py threshold \
--input image.tif \
--sensor landsat8 \
--index ndwi \
--method otsu
python scripts\water-body-extraction.py batch \
--input-dir ./images/ \
--sensor sentinel2 \
--index mndwi \
--output-dir ./masks/ \
--vector-dir ./vectors/
pip install rasterio>=1.3.0 numpy>=1.21.0 scipy>=1.7.0 shapely>=1.8.0 fiona>=1.8.0 tqdm>=4.64.0
# 或: pip install -r scripts/requirements.txt
--input: 多波段 GeoTIFF 路径--sensor: 传感器类型(landsat8, landsat9, sentinel2)--index: 计算指数(ndwi, mndwi)--threshold: 手动阈值(默认 Otsu 自动)--output: 输出栅格掩膜路径--vector: 输出矢量 GeoJSON 路径(可选)--input-dir: 批量处理输入目录--output-dir: 批量输出掩膜目录--vector-dir: 批量输出矢量目录--method: 阈值方法(otsu, manual)--json: 以 JSON 格式输出统计信息rasterio>=1.3.0
numpy>=1.21.0
scipy>=1.7.0
shapely>=1.8.0
fiona>=1.8.0
tqdm>=4.64.0
| 指数 | 适用场景 | 注意事项 |
|---|---|---|
| NDWI | 开阔水体、农村地区 | 建筑区可能产生假阳性 |
| MNDWI | 城市区域、混合用地 | 抑制建筑噪声;可能漏检浑浊水体 |
建议:城市/郊区场景用 MNDWI;自然地貌用 NDWI。
云和云影会导致虚假水体检测。最佳实践:
使用 --min-area 去除小面积噪声多边形:
python scripts\water-body-extraction.py extract \
--input image.tif --sensor landsat8 --index mndwi \
--output water_mask.tif --vector water_boundary.geojson \
--min-area 1000
--min-area 单位为地图单位(投影 CRS 为 m²)。典型值:500–5000 m²。
对于 >1 GB 的栅格:
--tile-size 4096 --overlap 256 分块处理--compress lzw 减小输出除 GeoJSON 外,还支持 Shapefile 和 GeoPackage 输出:
python scripts\water-body-extraction.py extract \
--input image.tif --sensor landsat8 --index mndwi \
--output water_mask.tif --vector water_boundary.gpkg --vector-format gpkg
使用参考数据验证结果:
在 QGIS 或 Python 中可视化结果:
如果本工具支持您的研究,请引用:
@software{water_body_extraction,
author = {ruiduobao},
title = {Water Body Extraction Tool},
url = {https://github.com/ruiduobao/water-body-extraction},
version = {0.1.0},
year = {2024},
}
| 错误 | 原因 | 解决方案 |
|---|---|---|
ConnectionError | 网络问题 | 检查网络,重试 |
HTTP 429 | 速率限制 | 等待 60 秒后重试 |
ValueError | 无效输入 | 检查参数格式 |
| 无输出 | 无数据 / 全是云 | 更换影像或调整阈值 |
ModuleNotFoundError | 缺少依赖 | 运行 pip install |
MemoryError | 栅格过大 | 使用分块处理或增加内存 |
| 全水体 / 无水 | 阈值问题 | 尝试手动阈值或更换指数 |
本地栅格处理 — 使用预下载的卫星影像,无外部 API 调用。