Files
water-body-segmentation/README.md
2026-03-09 17:31:28 +08:00

4.0 KiB
Raw Blame History

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

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

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

对应脚本:water_V5.py

功能概览

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

环境依赖

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

分区域参数:

  • num_splits_y、num_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)改为“子区域级别一次计算并复用”
  • 推理使用 autocast(float16),通常更省显存

输出说明

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

常见问题

  • 运行报 AssertionError(RoPE 相关)

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

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