1. 基于单波段阈值的厚云初筛掩膜

为什么先用蓝光波段做厚云初筛

厚云在可见光—近红外区间具有高反射率,其中蓝光波段(约 450–520 nm)对云滴的散射响应最敏感,同时受气溶胶与地表暗目标的干扰相对可控。对单景多光谱影像而言,最经济的做法是:取蓝光波段反射率 ρ_blue,设定一个阈值 T,令 ρ_blue ≥ T 的像元进入“厚云候选”集合。这一步不追求最终精度,只求用极低计算成本把明显云区圈出来,为后续光谱指数、亮温、阴影匹配等精细判据缩小搜索范围。

阈值 T 的选择本质是漏检与误检的权衡:T 偏低,云边缘薄云、亮白建筑、裸沙、雪被一并纳入,误检上升;T 偏高,云区内部被掏空、薄云与云边缘漏检,掩膜破碎。因此本例的核心不是“算出一个掩膜”,而是“通过目视对比找到平衡点”。

数据准备与反射率口径统一

单景多光谱影像通常以 DN 值存储,直接对 DN 设阈值不可移植(不同增益、不同太阳高度角会漂移)。必须先转为大气顶反射率(TOA reflectance)或地表反射率,本例采用 TOA 反射率,公式为:

ρ_λ = (π · L_λ · d²) / (ESUN_λ · cosθ_s)

其中 L_λ 为辐亮度,d 为日地距离(天文单位),ESUN_λ 为大气顶太阳辐照度,θ_s 为太阳天顶角。若影像已带定标系数,可简化为 ρ = gain · DN + offset 后按波段归一。实操中更稳妥的做法是:先确认元数据中的 REFLECTANCE_MULT_BAND_x 与 REFLECTANCE_ADD_BAND_x,再除以 sin(太阳高度角) 完成太阳角校正。下面给出一个可直接运行的 Python 片段,用 rasterio 读取蓝光波段并生成候选掩膜:

import numpy as np
import rasterio

BLUE_BAND = 2          # 示例:蓝光波段索引
T = 0.28               # 示例阈值,需目视调优
NODATA = 0

with rasterio.open("scene.tif") as src:
    blue = src.read(BLUE_BAND).astype("float32")
    profile = src.profile.copy()
    nodata_mask = (blue == NODATA)

# 若数据为 DN,先按元数据转为 TOA 反射率(示例系数,实际以元数据为准)
refl = blue * 2.0e-5 - 0.1
refl = np.clip(refl, 0, 1)

cloud = (refl >= T) & (~nodata_mask)
profile.update(dtype="uint8", count=1, nodata=0)
with rasterio.open("cloud_candidate.tif", "w", **profile) as dst:
    dst.write(cloud.astype("uint8"), 1)

注意:上面的定标系数只是示例占位,实际必须替换为影像元数据中的真实值;若影像已是反射率产品,则跳过定标,直接对反射率设阈值。

阈值扫描与目视对比的判读逻辑

单阈值无法一次定准,推荐做“阈值扫描 + 目视对比”。选取 3–5 个候选阈值(例如 0.20、0.24、0.28、0.32、0.36),分别生成二值掩膜,叠加到真彩色影像上,重点观察四类区域:云区内部是否连续、云边缘是否被削、暗地表(水体、浓密植被)是否被误判、亮地表(裸沙、建筑屋顶、雪)是否被误判。判读时不要只看总体像元比例,而要看“错误发生在哪类地物上”。

蓝光反射率阈值扫描:漏检与误检的平衡 ρ_blue 0.0 1.0 水体/浓密植被 裸土/建筑 雪/亮沙 厚云(高反射) T=0.20 误检多 T=0.24 T=0.28 平衡点 T=0.32 T=0.36 漏检多 T 偏低:云区完整 误检 T=0.28:云区连续 厚云候选 T 偏高:云区破碎 漏检空洞

上图把“反射率轴—地物区间—候选阈值—掩膜形态”放在同一视野里:阈值线落在雪/亮沙区间左侧时,亮地表被大量误判;落在厚云区间右侧时,云区被削出空洞。平衡点通常位于厚云反射率分布的下沿附近,本例示例数据下约在 0.28 左右,但必须用本景影像实测分布确认,不能照搬。

用直方图辅助定位候选阈值

目视对比之外,可先看蓝光反射率直方图:厚云像元会在高反射端形成一个明显的次峰或长尾。把候选阈值放在该峰谷之间,再回到影像上验证。下面片段输出分位数,帮助快速圈定扫描范围:

valid = refl[~nodata_mask]
for q in (50, 75, 90, 95, 99):
    print(f"P{q} = {np.percentile(valid, q):.3f}")

若 P90 约为 0.22、P99 约为 0.45,说明高反射端存在厚云聚集,可把扫描区间定在 0.20–0.36。分位数只用于缩小范围,最终仍以目视判读为准。

结果检查与通过条件

  • 云区连续性:厚云主体内部不应出现大面积空洞;若出现,说明阈值偏高。
  • 暗地表洁净度:水体、浓密植被区不应成片进入掩膜;若成片,说明阈值偏低或定标口径有误。
  • 亮地表误判:裸沙、建筑屋顶、雪若被大量纳入,需记录并在后续案例中用亮温或光谱指数修正,本例只做记录不做处理。
  • 可复现性:记录波段号、定标系数来源、阈值、扫描候选集与判读截图,保证他人可复算。
本例产出的“厚云候选掩膜”是初筛结果,允许存在误检,它的价值在于把后续精细判据的计算范围压缩到云区附近;不要用最终云掩膜的标准来要求它。
若影像含大量 NoData 或已做地形校正,反射率分布会偏移,阈值需重新扫描;直接套用其他景的阈值是最常见的失败原因。