成果丢块定位(提出来了但成果里不在)
何时用
- 用户怀疑提取阶段有块,但最终交付里没有;或成果面积/块数明显小于提取量
- 用户提出补救想法:「把相邻块合并成一个」「村界外扩 N 米全都保留」
- 交付前核查:为什么生成成果比 SAM/提取原始输出少几百甚至上千亩
铁律:先分层对账,不要先改管线
永远按「原始提取(raw) → 逐级过滤」把每一级丢了多少单独量出来,再决定改哪一级。
不要听用户猜的机制就直接动手改参数(典型误判:以为是 max_area 上限、以为是算力、以为是接缝)。
三步诊断法
第 1 步:raw 与最终成果逐块分层(最快定位)
以「与目标范围(vector)的关系」给 raw 每个块打三态,一次就能看出丢在哪:
raw["cen_in"] = raw.centroid.within(vpoly) # 质心在范围内
raw["inter"] = raw.geometry.intersects(vpoly) # 与范围相交
raw["dist_m"] = raw.geometry.distance(vpoly.boundary)
raw["vill_mu"] = raw.geometry.intersection(vpoly).area/666.67 # 真正属于范围内的面积
出三层图:黄=保留 / 红=跨界但被丢 / 灰=全在外 + 蓝=范围界线。
截图一贴,用户 5 秒就懂,比任何表格都有效。
关键:很多管线的范围过滤用「质心在界内」而不是「相交」。
→ 跨界块只要质心落在界外,整块被静默丢弃;这些块有相当一坨面积是真的在界内的。
(实测案例:某村 raw 1269 块,跨界被丢 58 块/3067 亩,其中 471 亩确实在村界内。)
第 2 步:并集面积检验 —— 区分「去重」与「真丢地」★最关键
去重叠步骤会让块面积和掉很多,但那可能只是消除重复计数,不是丢地。判据:
u_pre = unary_union(before_de_overlap) # 去重叠前并集
u_post = unary_union(after_de_overlap) # 去重叠后并集
u_post == u_pre→ 纯去重,没丢一亩地,不要改它u_post < u_pre→ 真丢覆盖,要查
实测案例:某成果去重叠前后块面积和 9012→7413 亩(看起来丢了 17.7%),
但并集 7413→7413 亩完全不变,覆盖率 62.8%→62.8% 不变 → 结论「去重叠无罪」。
(另一个坑:块面积和 本身含重叠,不能当覆盖率;覆盖率必须用 union ∩ 范围 算。)
第 3 步:tile 缝邻近性(判断假缝 vs 真相邻)
提取按瓦片跑(如 tile=1024/overlap=200 → 步长 824),瓦片边缘会截断 mask。
把瓦片截断线换算到成果坐标系(影像 px → 影像坐标 → 成果 CRS),
量每对「共边块」的共享边中点到最近截断线的距离:
- 大量集中在 <20-50m → 强证据:假缝(同一块田被两侧各提了一半)
- 普遍很远(数百米)→ 不是缝问题,是 SAM 在弱边界处本来就没切开
「相邻同作物块合并」的判据与反例
判据(可自动筛候选):
1. 作物标签相同(不同作物绝不能合并,会毁掉作物图)
2. distance <= 2m(含真共边与 <1px 细缝)
3. 共享边长度 L 取几何:真共边直接 intersection 取线部件;
有细缝时不能 buffer 0.01 后取交(会变成面) → 用 buffer(gap/2+0.05) 后取交集,
交出来是面时用 inter.length/2 近似缝长(细条周长 ≈ 2×缝长)
4. L / min(周长i, 周长j) >= 阈值(实测:0.30 起比较稳,0.15 会明显过合并)
必须知道的覆盖率-精度权衡:合并后面积守恒(union 不重叠时 差 +0.0),
所以面积守恒不能证明合并正确,只能证明没叠压。真假必须看图。
反例(必看):实测 4 对里就有 1 对是「两块不同朝向、面积相当的田」——
共享边长、比值 0.33 都过阈值,但两块是不同朝向的相邻田,合并会拼出一个 L 形假地块。
→ 所以:纯数值判据会过度合并;要么加形状判据(union 后 solidity / 最小外接矩形填充率不降、
两块的第二主轴近于平行),要么导出候选对清单 + 放大对照图让人工过一遍(几十对,几分钟)。
先出候选清单比直接出合并成果安全。
用户想法 2:「范围外扩 N 米全都保留」怎么答
- 先量影像/窗口容量再承诺:底图常是按范围 bbox + 小 margin 裁的,
范围外可能只有几百米数据(实测某当季高分影像北边只剩 344m,做不了 1km)。
SAM 的MARGIN是像素单位,换到米要乘 GSD(200px 在 1.05m ≈ 210m,在 2m ≈ 400m)。 - 外扩通常不增加「范围内覆盖率」:实测外扩 400m / 1km / 全部,
范围内覆盖率都是 66.4%(+404 亩),一分不多——因为范围外的块够不到范围里。
→ 外扩的价值是「把邻区一起收进来」,不是修复范围内部提不全。
> 两个口径别混(同一个救回动作会报出两个数,用错就是自己打自己脸):
> -块交集面积和(逐块intersection(范围).area求和)= 471 亩 → 偏大,含多尺度重复 mask 的重复计数
> -并集 ∩ 范围增量(union(救回后) ∩ 范围−union(救回前) ∩ 范围)= 404 亩 → 正确口径
> 对外一律报并集口径的 404;471 只用于描述「哪些块跨界」。两个数同时出现时必须显式说明是哪个口径。 - 范围内部提不全要另算:覆盖率 =
union ∩ 范围 / 范围面积。实测 62.8%→66.4%(修掉跨界丢块后)
→ 修边界能拿回 3.6 个点;剩下 33.6% 是提取阶段就没提出来的,与范围过滤无关,别混为一谈。 - 落地建议做成两层而非直接放开:主层(范围内,用于按单位统计/核对)+ 附层(范围外,带
in_vill / dist_m / 交集面积字段,用于查漏)。这样既不丢块,又不让统计口径漂到范围外。
常见丢块环节清单(按排查优先级)
| 环节 | 判据 | 修法 |
|---|---|---|
| 范围过滤(质心 vs 相交) | 跨界块被丢 | 改 intersects 或「保留跨界完整块 + 标注在界内面积」 |
面积上限 max_area_mu |
巨型块被整块丢 | 放宽上限,但要知道巨型块可能是「多个田被并成一块」的伪块 |
面积下限 min_area |
碎块被丢 | 确认是否低于该层 GSD 可分辨下限,别把真实小田滤掉 |
| 去重叠 difference 链 | 见第 2 步 | 并集不变 → 不要改 |
| 非耕地类过滤(RF 判成居民点/林地) | 按 crop 字段筛 | 检查是否类间混淆(另见 crop-class-label-audit) |
| SAM 窗口/瓦片边缘 | 见第 3 步 | 放大窗口 MARGIN / 减 overlap 截断 |
> 注意分流:本 skill 治的是「提出来了,但成果里不在」(能逐块对账)。
> 如果 raw 里根本没有那些块(缺口里落不到任何 raw 像元),那是提取阶段就没提出来,
> 换用 extraction-hole-diagnosis —— 用缺口宽度分档 + NDVI 判定,别在本 skill 里绕。
交付物模板
*_村界分层.gpkg/shp(或范围分层):raw 全量 +area_mu / 界内面积 / dist_m / cen_in / inter / band*_范围过滤三层诊断.png:黄/红/灰 + 界线*_合并对清单.gpkg+*_合并前后放大对照.png(人工过筛用,先别出合并成果)- 一段覆盖率用并集口径的对照表:现口径 / +救回跨界 / +外扩,各自覆盖率与亩数