Files
water-body-segmentation/README_water_V5.md
2026-03-09 17:23:53 +08:00

4.0 KiB
Raw Blame History

water_V5.py超大遥感影像水体分割SAM3 + Rasterio 分块)

这个脚本用于在超大 GeoTIFF/遥感影像上分割水体(如 river/water body重点在于在 16GB 显存条件下平衡速度与显存:

  • 影像按“子区域”切分处理,避免一次性处理整图
  • 每个子区域先做一次低分辨率粗分割定位水体,再只对“边缘带”进行高分辨率分块精修
  • 精修的概率融合与大数组操作尽量放在 CPUfloat16显著降低显存占用

对应脚本:water_V5.py

功能概览

  • 读取 GeoTIFF 子区域Rasterio Window/MemoryFile
  • overview 粗分割(低分辨率一次推理)
  • 由粗分割生成边缘带ring/band
  • 仅对边缘带覆盖到的 tile 做精修推理(重叠窗口融合)
  • 后处理:内部 NoData 空洞填充、连通域面积过滤
  • 输出单通道 uint8 掩膜 GeoTIFF像元值 0/1

环境依赖

  • Python + PyTorchGPU 可选但推荐)
  • rasterio
  • numpy
  • PIL (Pillow)
  • scipy
  • tqdm

提示:运行时可能看到 pkg_resources is deprecated 警告,不影响推理结果。

运行方式

  1. 打开 water_V5.py,修改下面参数:
    • image_path:输入 GeoTIFF
    • mask_output_path:输出掩膜 GeoTIFF
    • prompt:文本提示(例如 "water body" / "river" / "water"
  2. 运行:
python e:\code\sam3-main\sam3-main\water_V5.py

输出 mask_output_path 为 uint8 单通道,像元值为 0/1并保留输入影像的空间参考transform/CRS

关键参数说明(建议优先调这几个)

在脚本“参数设置”区域:

  • coarse_read_max_sideoverview 粗分割输入的最大边长(越大越准/越慢,越小越快/越粗)
    • 建议:1024 ~ 153616GB 显存一般可从 1200 开始)
  • tile_size:精修分块大小(原图像素)
    • 建议:1536(更稳)或 2048(更快但更吃内存/更容易慢)
  • overlap:精修分块重叠(减少拼接缝)
    • 建议:128(更快)或 256(边缘更稳但慢)
  • band_radius:边缘带宽度(越大精修范围越大,速度越慢)
    • 建议:48 ~ 96
  • coarse_threshold / final_threshold:粗分割/最终阈值
    • 通常 0.5 可用;若漏检多,可适当降低阈值(例如 0.4

分区域参数:

  • num_splits_ynum_splits_x:将整图拆成多少个子区域处理
  • region_overlap:子区域之间重叠,避免区域边界出现断裂

后处理参数:

  • min_area:移除小碎片的最小连通域面积(像素)
  • keep_largest_only:只保留最大连通域(适合只想要“最大水体”的场景)

性能与显存的取舍建议16GB

优先级从高到低:

  • 优先调小 tile_size(例如 2048 → 1536通常能显著降低显存与峰值计算量
  • overlap 从 256 降到 128可明显加速代价是拼接缝更可能出现
  • band_radius 适当减小,让精修只发生在更窄的边缘范围
  • coarse_read_max_side 适度提高可减少误分/漏分,但会更慢

脚本已做的关键优化:

  • 精修 tile 的“是否需要处理”的判断在 CPU 上完成,避免每个 tile 强制 GPU 同步
  • per-tile 的强度拉伸percentile改为“子区域级别一次计算并复用”
  • 推理使用 autocastfloat16通常更省显存

输出说明

  • 输出掩膜为 uint8 单通道:
    • 0非水体
    • 1水体
  • 输出 GeoTIFF 继承输入的 profile并设置 compress='lzw'

常见问题

  • 运行报 AssertionErrorRoPE 相关)

    • 该模型对输入分辨率有约束。脚本默认 coarse_resolution = 1008fine_resolution = 1008,不要随意改成 768/512 等。
  • 输出全黑/全白

    • 先换 prompt(如 "water" / "river"),再调 coarse_threshold/final_threshold
    • 若影像波段不是 RGB脚本会取前三个波段做可视输入需要更合适的波段组合时应自行调整 _bands_to_pil