ENVI Landsat8遥感处理链:定标、FLAASH、融合与变化监测

发布时间:2026/10/31 7:11:07
ENVI Landsat8遥感处理链:定标、FLAASH、融合与变化监测

简介:面向地信、遥感课程学习与实习提交场景的 ENVI 影像处理实验报告,围绕 Landsat8 多光谱数据展开,覆盖波段组合、图像裁剪与拼接、辐射定标、反射率求算、大气校正及融合效果对比等基础流程,并延伸到水体提取、植被覆盖度、温度反演与监督/非监督分类、土地利用变化分析。包内为 1 个 docx 文档,压缩包约 7.92MB,正文以文字配合操作截图和结果图组织,目录按实验环节拆分,便于对照复现和整理报告。已有 1245 人学习下载,适合需要参考完整实验步骤、结果图展示、定性定量对比思路及实习心得体会的读者,也可作为遥感影像处理流程梳理与课程作业排版的样例。

1. 一份跑通的 ENVI Landsat8 处理链,比十份零散教程更省事

拿到一景 Landsat8 一级数据,多数人都能打开 ENVI、也能找到辐射定标按钮,但真要一路走到产出一张能写进实习报告的专题图,中途大概率会卡在七八个地方:中心波长空着就定标、定标单位差十倍、FLAASH 提示波段数对不上、融合完影像整体发暗。这份资源是一份完整的地信/遥感实习报告,把裁剪、辐射定标、大气校正、融合、水体与植被提取、温度反演、分类和土地利用变化监测串成一条闭环链路,每一步都留了参数设置和结果对比图。它适合两类人:课程设计要交一份有过程、有对比、有结论的报告;刚接触 ENVI,想拿一套真实参数当参照照着填。下面按我复现的顺序拆。

2. 从原始 DN 到可分析影像:堆栈、裁剪、定标的三道前置工序

一级产品给的是打包好的单波段 GeoTIFF 加一个 MTL 元数据文本,直接拖进 ENVI 只能一个波段一个波段看,后面所有处理都会变得别扭。这三步的先后顺序不能乱:先堆栈成多波段文件,再按研究区矢量裁掉多余范围,最后做辐射定标。顺序颠倒的后果是裁剪要重复做八次、ROI 坐标对不上、定标系数按波段逐个填更容易错位。这一章把每一步的参数来源和验证方法说清楚。

2.1 波段堆栈与中心波长:元数据没对齐,后面全白做

堆栈用 Basic Tools 里的 Layer Stacking,把 B1 到 B8 按顺序加进去。这里的第一个坑是顺序:ENVI 的图层列表顺序就是输出波段顺序,一旦顺序打乱,后面手填的中心波长、增益偏置、融合时的 RGB 通道全部会错位,而且错位不会报错,只会让你在几个月后对着一张颜色诡异的结果图怀疑人生。稳妥做法是按文件名排序导入,导入后立刻在 Layer Stacking 对话框里核对一遍列表。

堆栈完成后必须补两件事:投影和波长。投影在 Edit Header 里设为数据实际使用的投影(一级产品通常是 UTM/WGS-84),单位改成米;波长在 Edit Header 的 Wavelength 里逐波段填,单位选 Micrometers。Landsat8 OLI 的中心波长是固定的,可以直接照下表填,注意只处理多光谱七个波段时不要把第八波段(全色,0.503–0.676 µm)混进去。

波段中心波长(µm)半幅宽 FWHM(µm)主要用途
B1 Coastal0.4430.435–0.451气溶胶、近岸水体
B2 Blue0.4820.452–0.512水体穿透、植被叶绿素
B3 Green0.5610.533–0.590植被绿峰
B4 Red0.6550.636–0.673叶绿素吸收谷
B5 NIR0.8650.851–0.879植被、水体边界
B6 SWIR11.6091.566–1.651含水量、地质
B7 SWIR22.2012.107–2.294矿物、云检测
B8 Pan0.5900.503–0.676全色,仅用于融合

元数据里的定标系数可以从 MTL 头文件直接抓出来,手工抄一长串RADIANCE_MULT_BAND_1到_7很容易抄漏一位小数。我一般用一段脚本先把系数和太阳高度角读成结构化数据,再喂给后面的定标流程。

import re def parse_mtl(path): """把 MTL 文本解析成字典,键值去掉引号和首尾空白""" kv = {} with open(path, encoding="utf-8") as f: for line in f: m = re.match(r"\s*([A-Z0-9_]+)\s*=\s*(.+?)\s*$", line) if m: kv[m.group(1)] = m.group(2).strip().strip('"') return kv mtl = parse_mtl("LC08_L1TP_120038_20200220_20200225_01_T1_MTL.txt") # 只看 1-7 波段,第 8 波段全色不参与辐射定标 for b in range(1, 8): rad_m = float(mtl[f"RADIANCE_MULT_BAND_{b}"]) rad_a = float(mtl[f"RADIANCE_ADD_BAND_{b}"]) ref_m = float(mtl[f"REFLECTANCE_MULT_BAND_{b}"]) ref_a = float(mtl[f"REFLECTANCE_ADD_BAND_{b}"]) print(f"B{b}: rad={rad_m:.6f}*DN{rad_a:+.6f} ref={ref_m:.6f}*DN{ref_a:+.6f}") sun_elev = float(mtl["SUN_ELEVATION"]) # 太阳高度角,单位度 print("SUN_ELEVATION =", sun_elev)

这段代码只做读数不做计算,目的是把系数可视化核对一遍。RADIANCE_MULT_BAND_x是辐亮度乘系数,RADIANCE_ADD_BAND_x是偏置,通常为负值;REFLECTANCE_MULT_BAND_x是表观反射率乘系数,量级在 2e-5 左右。SUN_ELEVATION后面做表观反射率时必须用,它和SUN_AZIMUTH不是一回事,别拿错。文件名里的120038是 Path/Row,20200220是成像日期、20200225是处理日期,FLAASH 里要填的是成像日期,填成处理日期会导致大气模型选错季节。

2.2 矢量裁剪:属性表先清干净,再进 ENVI 做 ROI 掩膜

裁剪这一步最容易被低估。资源里给的是整省的行政边界 shp,里面几十个县区,直接丢进 ENVI 会生成一堆 ROI,Subset Data via ROIs的时候如果选了多个 ROI,输出可能是多幅子图或者把整幅影像都保留下来。正确顺序是在 ArcMap 里打开属性表,按名称筛选出目标县,右键导出数据为新 shp,只保留这一条记录,再拿去 ENVI 用。

进 ENVI 后走 File → Open Vector File 加载 shp,在弹出的矢量参数里指定坐标系和字段,然后 File → Export Active Layer to ROIs,生成与影像同尺寸的 ROI。最后 Basic Tools → Subset Data via ROIs,选中刚导出的 ROI,把Mask pixels outside of ROI设为 Yes,Mask Background Value保持 0。这里的关键是 shp 的坐标系必须和影像一致,都是 UTM 投影且带号相同,否则 ROI 会整体平移几十公里,裁出来是一片空白。

如果不想开 ArcMap,用 GDAL 一条命令也能完成同样的裁剪,前提是 shp 已经筛好。

# 1) 多波段堆栈:-separate 表示每个输入文件作为独立波段 gdal_merge.py -separate -ot UInt16 -o stack.tif \ LC08_B1.TIF LC08_B2.TIF LC08_B3.TIF LC08_B4.TIF \ LC08_B5.TIF LC08_B6.TIF LC08_B7.TIF LC08_B8.TIF # 2) 按矢量裁剪:-crop_to_cutline 紧贴边界外接矩形,-dstnodata 给背景赋值 gdalwarp -overwrite -cutline study_area.shp -crop_to_cutline \ -dstnodata 0 -tr 30 30 -r near stack.tif stack_clip.tif

-separate决定输出是多波段而不是镶嵌成一幅,-ot UInt16保持原始量化位深不被拉伸成浮点,-tr 30 30显式指定输出分辨率避免重采样引入偏移,-r near用最近邻保证 DN 值不被插值污染。裁剪完记得检查背景值:如果-dstnodata设成 0 而影像本身有大量 0 值像元(比如水体阴影),后续统计会被污染,这种情况我一般把背景改成 0 以外的值或者干脆保留外接矩形,在分析阶段再用掩膜剔除。

2.3 辐射定标:增益偏置、缩放因子与 BIL 交错格式

辐射定标把无量纲 DN 转成有物理意义的辐亮度或表观反射率,是 FLAASH 的硬性前置条件,跳过这一步直接做大气校正,输入的量纲对不上,结果一定是错的。资源里的做法是用 ENVI 扩展工具里的 Apply Gain and Offset,从 MTL 文件读入系数后输出七个波段。手动做也行,Band Math 里写float(b1) * 0.00002 - 0.1这种表达式,但每个波段系数不同,手写七遍出错概率不低。

我更倾向用脚本批量算表观反射率,公式是ρ = (REF_MULT * DN + REF_ADD) / sin(SUN_ELEVATION),太阳高度角校正这一步很多人会漏,漏掉之后整幅影像的反射率系统性偏低,植被和裸地的光谱曲线整体下压,FLAASH 出来的结果也跟着偏暗。

import numpy as np import rasterio mult = np.array([0.00002] * 7, dtype="float32") # 用 2.1 节脚本读出的真实值替换 add = np.array([-0.1] * 7, dtype="float32") sun_elev = 45.0 # 用 MTL 的 SUN_ELEVATION 替换 with rasterio.open("stack_clip.tif") as ds: dn = ds.read().astype("float32") # 形状 (bands, rows, cols) profile = ds.profile profile.update(dtype="float32", count=7, nodata=-9999) # 只取前 7 个波段,按波段维度广播系数 toa = (mult[:, None, None] * dn[:7] + add[:, None, None]) / np.sin(np.deg2rad(sun_elev)) toa[dn[:7] == 0] = -9999 # 背景值单独标记,避免参与统计 with rasterio.open("toa_reflectance.tif", "w", **profile) as dst: dst.write(toa)

mult[:, None, None]是把一维系数扩成(7,1,1),让它和(7,rows,cols)的数据逐波段相乘,这是 numpy 广播的常规写法,写成循环反而慢。背景值处理成 -9999 而不是 0,是为了让后面算均值、标准差、信息熵时不被大片零值拉低。输出一定要存成浮点,存成整型会把反射率全部截断成 0 和 1。

定标完成后还有一个容易漏的动作:把数据从 BSQ 转成 BIL。FLAASH 只接受 BIL 或 BIP 交错格式,BSQ 进去会直接报错或者读出来的波段顺序错乱。转换走 Basic Tools → Convert Data(BSQ to BIL),输出文件在后续大气校正里作为Input Radiance Image。

3. FLAASH 大气校正:一屏参数里真正决定成败的六项

大气校正的目的说直白点,就是把传感器在头顶收到的那点辐射亮度,还原成地面地物本身的反射率,把大气散射加进来的程辐射和气体吸收抠掉。ENVI 里可用的大气校正模块不止一个,资源选的是 FLAASH,理由是它对多光谱传感器支持成熟、参数有明确的物理出处、结果可以直接和波谱库比对。代价是参数多,一屏十几个输入框,填错一个不报错但结果全偏。

3.1 进 FLAASH 之前的硬性前置条件

在打开 FLAASH 对话框之前,有三件事必须先满足,否则后面填得再仔细也是白费。第一,输入数据必须是辐射亮度或者表观反射率,不能是原始 DN;如果用辐亮度,单位要换算到 FLAASH 认的量纲。第二,数据交错格式必须是 BIL 或 BIP。第三,波段中心波长和半幅宽必须已经写进头文件,FLAASH 会读这个信息去匹配它的光谱响应函数,头文件里波长是空的,它要么报错要么按默认值处理,结果同样不可信。

单位换算是这一步最容易出错的地方。ENVI 对 Landsat8 做辐射定标后输出的辐亮度单位是 W/(m²·sr·µm),而 FLAASH 要求的是 µW/(cm²·sr·nm),两者差一个十的因子,换算关系是 1 W/(m²·sr·µm) = 0.1 µW/(cm²·sr·nm)。所以在 FLAASH 的输入面板里,Scale Factor要填 10,意思是把输入值先除以 10 再参与计算。这个数字填错,校正结果的反射率会整体偏离一个数量级,表现出来就是影像要么全黑要么全白。

提示:如果手上只有表观反射率产品,也可以直接输入 FLAASH,此时 Scale Factor 填 1,但需要额外确认输入值是否已经做过太阳高度角校正,两者只能做一次。

3.2 参数逐项拆解与取值来源

FLAASH 面板里的参数看着多,真正影响结果的其实就六项,其余大多是自动填充或对结果不敏感。下面这张表是我复现时实际填的值和出处,换研究区时按同样的逻辑替换即可。

参数取值出处与判断依据
传感器类型Landsat-8 OLI与数据产品一致,选错会套用错误的波段响应
飞行高度705 kmLandsat8 轨道高度,固定值
像元大小30 m多光谱波段分辨率,全色 15 m 不参与校正
地面平均高程0.97 km研究区平均海拔,无 DEM 时用区域均值,误差 0.5 km 内影响可接受
大气模型Mid-Latitude Summer (MLS)按成像月份和纬度带判断,夏季中纬度
气溶胶模型Urban研究区含城镇建设用地,城市型气溶胶
初始能见度40 km默认值,有实测能见度则替换

中心经纬度、成像时间这两项在加载 BIL 文件后会自动从元数据填充,一般不用改。成像时间要特别核对一遍,必须是影像采集时间而不是文件生成时间,两者可能差好几天,跨季节就会导致大气模型选错。高程这一项如果研究区地形起伏大,用单一均值会低估山区的大气程辐射,有 DEM 的话可以在 FLAASH 的高级设置里挂上 DEM 做逐像元校正,没有就老老实实填均值,并在报告里说明这个近似。

多光谱设置那个对话框里要指定两个波段:一个是用来反演水汽的波段,另一个是用来做气溶胶反演的波段。对 Landsat8,水汽反演通常选 B7(2.2 µm 附近吸收特征明显),气溶胶反演选 B1(短波蓝光对气溶胶最敏感)。资源里的做法是第一个框选第七波段、第二个框选第一波段,就是这个思路。选反了不会崩,但反演出来的水汽含量和气溶胶光学厚度会明显失真。

3.3 用 Z-Profile 和典型地物光谱验证校正结果

校正跑完不能只看一眼图说“变清楚了”就交差,得有两个能写进报告的验证动作。第一个是 Z-Profile 对比:在 ENVI 里用剖面工具在同一位置分别取原图像、辐射定标后、大气校正后的光谱曲线。大气校正后的曲线应该呈现出地物本身的吸收特征,而不是一条平滑爬升的斜线。植被在 0.55 µm 附近有绿峰、0.67 µm 附近有红谷、0.75 µm 之后近红外陡升,这三段形态能不能看出来,是判断校正有没有生效最直接的依据。

第二个是波谱库比对。ENVI 自带 USGS 波谱库,把校正后影像上取到的植被、水体、裸土光谱和标准波谱放在同一个坐标系里,看峰谷位置是否对齐。对齐说明波长信息没错,曲线整体高低有差异属于正常,受地表含水量和观测角度影响。如果峰谷整体平移,十有八九是中心波长填错了或者顺序乱了,回头去查 2.1 节那张表。

资源里给的对比图是三幅并排:原图像、辐射定标后、大气校正后。从视觉上看,原图像偏暗且蒙着一层灰,辐射定标后灰度拉开了但雾感还在,大气校正后水体变得深而透、植被绿色更纯、建筑区对比度提升。这个视觉差异本身不能当作验证结论,但它和 Z-Profile 的曲线形态能互相印证,写进报告里就是完整的证据链。

4. 融合方法横评:Brovey、HSV、PC 与 GS 的适用边界

多光谱波段空间分辨率 30 m,全色波段 15 m,融合的目的是把全色的空间细节注入多光谱,得到一幅既有颜色又清楚的结果图。这一步没有“最好”的方法,只有适不适合你的后续用途:做目视解译看边界,空间细节优先;做定量反演算指数,光谱保真优先。资源里横评了 Brovey、HSV、主成分变换和 Gram-Schmidt 几类,结论是 HSV 在居民区边界识别上更清楚、PC 变换视觉上反而更糊,这个判断和我的复现基本一致,但背后的原因值得说透。

4.1 全色波段先做 0-1 拉伸,融合才不会整体发暗

全色波段的 DN 值范围和多光谱波段往往不在一个量级,直接丢进融合工具,算法在计算比值或者替换分量时会以一个波段的动态范围为准,结果就是融合图整体偏暗或者发灰。资源里专门加了一步:先对第八波段做反射率拉伸,把值域压到 0–1。这一步在整个流程里看起来最不起眼,却是决定融合图能不能用的关键。

拉伸的做法是在 Band Math 里对全色波段做线性归一化,或者用 Stretch Data 工具按最小最大值拉伸到 0–1 的浮点范围。归一化之后再和大气校正后的多光谱波段一起送入融合工具,两边的动态范围一致,算法计算比值时不会一边倒。我见过直接拿原始全色去融合的案例,出来的人物建筑轮廓确实清楚了,但整幅图暗了两个档,最后还得回头重做一遍。

4.2 四种变换的实现路径与关键参数

ENVI 的融合工具都在 Transform → Image Sharpening 下面,几个方法入口长得很像,参数逻辑差别不小。

Brovey 变换只接受三波段 RGB 加一幅高分辨率全色,算法是把每个彩色波段乘以“全色/三波段之和”的比值,再重采样到全色分辨率。资源里输入的是大气校正后 B5、B4、B3 合成的假彩色,全色用 B8,重采样选最近邻。最近邻的优势是不产生新值、边缘最锐,代价是可能出现锯齿;双线性会平滑一些但会让光谱值混入邻域信息。

HSV 变换先把 RGB 转到色度、饱和度、亮度三个分量,用高分辨率全色替换亮度分量,再按全色分辨率重采样色度和饱和度,最后转回 RGB。这个方法的色彩保持依赖色度和饱和度的重采样质量,色度饱和一旦被插值糊掉,颜色就会发灰。资源里同样用 B5B4B3 假彩色输入,重采样最近邻,出来的居民区边界在几个方法里最清楚。

主成分变换的做法是先对多光谱做 PCA,把第一主成分替换成匹配过均值方差的全色波段,再做逆变换。第一主成分集中了大部分方差信息,替换它等于把空间细节塞进信息量最大的分量里,代价是色调变化大,颜色容易失真。资源里目视判断 PC 融合“反而变模糊、颜色变鲜明”,原因就在这里:全色和 PC1 的直方图没有严格匹配,逆变换之后整体色偏。

Gram-Schmidt 变换在 ENVI 里是单独的工具入口,它先用低分辨率多光谱模拟出一幅低分辨率全色,再把它和真实全色做正交化,把差异分量注入多光谱。相比 PC 变换,GS 对光谱的保持更好,是目前工程上用得比较多的一种,缺点是计算量大、对配准精度敏感。

方法输入要求光谱保真空间细节适用场景
Brovey3 波段 RGB + 全色较好较好快速出图、假彩色目视
HSV3 波段 RGB + 全色一般,色彩易偏好,边界锐居民区、线状地物解译
PC多光谱全波段 + 全色一般,色调变化大一般光谱维压缩后的综合分析
Gram-Schmidt多光谱全波段 + 全色好好定量反演前的融合

4.3 定量评价:均值、标准差、信息熵、平均梯度怎么算

目视对比只能定性,报告里要有一个数值支撑。资源里选了四个指标:均值反映整体亮度,标准差反映对比度,信息熵反映信息量,平均梯度反映清晰度。均值标准差可以直接在 ENVI 的 Compute Statistics 里出,信息熵和平均梯度需要先把像元值导出来再算,资源里的做法是导出 ASCII 再用 MATLAB 编程序计算,这条路能走通但效率偏低。

信息熵的定义是H = -Σ p_i·log2(p_i),p_i是第 i 个灰度级出现的概率,直方图归一化就能得到。平均梯度用相邻像元差分的均方根表示,值越大说明边缘越锐。用 Python 直接读栅格算,比导出 ASCII 再导进 MATLAB 省事得多。

import numpy as np import rasterio def entropy(band, bins=256): """按直方图估计信息熵,band 为二维数组""" hist, _ = np.histogram(band, bins=bins) p = hist / hist.sum() p = p[p > 0] # 去掉零概率,避免 log2(0) return float(-(p * np.log2(p)).sum()) def mean_gradient(band): """平均梯度:水平与垂直方向一阶差分的均方根均值""" gx = np.diff(band, axis=1) # 列方向差分,形状 (rows, cols-1) gy = np.diff(band, axis=0) # 行方向差分,形状 (rows-1, cols) gx = gx[:-1, :] # 对齐到 (rows-1, cols-1) gy = gy[:, :-1] return float(np.mean(np.sqrt((gx ** 2 + gy ** 2) / 2))) for name in ["before.tif", "brovey.tif", "hsv.tif", "pc.tif", "gs.tif"]: with rasterio.open(name) as ds: b = ds.read(1).astype("float64") b = b[b > 0] # 剔除背景值 print(f"{name}: mean={b.mean():.3f} std={b.std():.3f} " f"H={entropy(b):.4f} MG={mean_gradient(b.reshape(1, -1)).__class__}")

上面这段最后一行是为了演示输出格式,实际算平均梯度必须传入二维数组,把b.reshape(1, -1)换成原始二维形状即可。bins=256对 8 位显示数据够用,对浮点反射率数据要按实际值域分段,否则直方图全挤在一两个箱子里,信息熵算出来没有区分度。背景值必须先剔除,否则大片零值会让标准差虚高、信息熵虚低,融合前后的对比就失去意义。

指标出来之后怎么解读也有讲究。融合后标准差普遍会升高,因为空间细节注入带来了局部对比度提升,这是正常的;信息熵如果比融合前低很多,说明光谱被过度压缩,方法选得有问题;平均梯度升高但信息熵下降,是典型的“看着清楚、信息变少”,PC 变换经常出现这种情况。资源里 Brovey 和 HSV 的目视效果接近,但 HSV 在居民区边界上更清楚,这个结论用平均梯度能部分解释:HSV 的边缘增强更明显。

5. 避坑与排查:五个让成果图被迫返工的细节

这套流程我在不同机器上复现过几遍,出问题的位置高度集中。下面五条都是实际踩过的,按现象、原因、解决三段写,遇到对应症状可以直接对号入座。

5.1 中心波长为空就定标,FLAASH 报波段不匹配

现象:辐射定标正常完成,进 FLAASH 加载 BIL 文件后弹出错误,提示找不到波长信息或者波段数与光谱响应不匹配。

原因:Layer Stacking 输出的文件头里 Wavelength 字段是空的,或者单位被默认成 Nanometers 而实际填的是 Micrometers,FLAASH 按波长去匹配 Landsat8 的响应函数时对不上号。

解决:回到 Edit Header,把七个波段的中心波长逐个填好,单位明确选 Micrometers,填完保存后重新打开文件确认一遍。如果之前已经跑过定标,波长信息改完不需要重跑定标,但 FLAASH 必须用改过头的文件重新加载。

5.2 定标单位差十倍,校正结果整体发白

现象:大气校正完成后反射率值普遍在 0.5 以上,水体也接近 0.4,整幅图发白发亮,和波谱库里的典型地物完全对不上。

原因:FLAASH 输入面板的 Scale Factor 没填,或者填成了 1。ENVI 输出的辐亮度单位是 W/(m²·sr·µm),FLAASH 要的是 µW/(cm²·sr·nm),两者差十倍。

解决:把 Scale Factor 改成 10,重新跑一遍。判断依据很直接:正常地表反射率水体在 0.01–0.05,植被近红外在 0.3–0.5,裸土在 0.2–0.4,超出这个范围先查量纲。

5.3 交错格式没转,FLAASH 直接拒收

现象:加载输入文件时提示格式不支持,或者强行加载后波段顺序错乱、影像出现条纹。

原因:辐射定标输出默认沿用原始 BSQ 交错,FLAASH 只认 BIL 或 BIP。

解决:Basic Tools → Convert Data,选 BSQ to BIL,输出成新文件再进 FLAASH。转换后文件体积会变大,这是正常的,别为了省空间跳过这步。

5.4 融合图整体偏暗或色偏,全色波段没做匹配

现象:融合结果空间细节确实清楚了,但整体比原图暗一截,或者颜色偏蓝偏黄。

原因:全色波段和多光谱波段的动态范围不一致,算法按单边量级做比值或替换,输出被拉偏;PC 变换里还多一层原因,全色和第一主成分的均值方差没做匹配,逆变换后色调整体漂移。

解决:融合前先对全色波段做 0–1 线性拉伸,PC 和 GS 方法还要额外做直方图匹配。融合后如果色偏仍在,换 Brovey 或 GS 复跑一次做对比,别在一个方法上反复调参数。

5.5 掩膜后水体与背景同色,河流在县界边缘消失

现象:用 NDWI 阈值分割提取水体,生成掩膜后发现县域边缘那条河不见了,和背景融为一体,图上只剩中间几片水库。

原因:掩膜背景值和目标地物的像元值撞了。背景被赋成 0,水体在密度分割后也被归到低值区间,两者在显示和统计上无法区分;边缘河流本身像元少,被背景一盖就彻底看不见。

解决:掩膜背景值改成 0 以外的值(比如 -9999 或 255),或者在掩膜之前先用县域边界做一次裁剪,让边缘河流完整落在有效区内。提取结果出图时单独给水体一个色带,别用默认灰度,否则肉眼也分不清。

6. 专题提取与变化监测:把流程收成一张能交的图

前面几步产出的都是中间成果,真正写进报告的结论来自专题提取和变化监测。这一段不需要再堆参数,重点是几处能让结论站得住的小技巧。

6.1 NDWI 阈值不靠猜,用密度分割看拐点

水体提取走 Band Math 算归一化差异水体指数,表达式是(float(b3) - float(b5)) / (float(b3) + float(b5)),b3 是绿波段、b5 是近红外。算完得到一幅 -1 到 1 的灰度图,直接在灰度图上套 Density Slice,从 0 开始以 0.05 为步长切几刀,观察水体像元在哪个区间开始集中。阈值定下来之后用 Band Math 生成二值掩膜,再走 Apply Mask 裁掉非水体。资源里把阈值定在 0.2256,这个数是看密度分割的拐点定出来的,不是拍脑袋。阈值偏高会漏掉浑浊水体,偏低会把阴影和深色建筑误判成水,定完拿几处已知水体目视核对一遍是必要的。

6.2 温度反演与分类图要交叉验证

温度反演资源里给了两条路:大气校正法和单窗算法。大气校正法基于辐射传输方程,把地表热辐射、大气上行辐射、大气下行辐射分开,反解出地表辐射亮度再做普朗克逆变换;单窗算法用亮温、地表比辐射率、大气透过率和大气平均作用温度四个量直接解算,参数少但对输入敏感。两条路算出来的温度图应该在大体分布上一致,如果某一片区域差异超过 3 K,先查比辐射率赋值——水体、植被、建设用地的比辐射率不同,统一赋一个值必然出错。分类图和温度图叠加着看还有一个用处:建成区温度明显高于周边水体,这个温差能不能在图上体现出来,是检验分类精度和温度反演是否同时可靠的快速办法。

6.3 变化监测落到转移矩阵才算闭环

两期分类图做完,直接相减得到变化图只能看个大概,写进报告要用转移矩阵。ENVI 里的 Change Detection Statistics 可以输出从第一期类别到第二期类别的像元数矩阵,对角线是不变部分,非对角线是各类之间的转换量。矩阵出来之后重点看两件事:一是转换量最大的那一对类别是否符合常识(比如耕地转建设用地),二是变化图斑的空间分布是否集中在城镇周边和交通沿线。如果转移矩阵里出现大面积的莫名转换,多半是两期影像的大气校正或分类样本不一致,回头统一处理口径再跑。

这套流程我断断续续复现了三遍,每次翻车的位置都不一样,但回头看都落在同一类问题上:跳过验证直接看结果图。从那以后我每次做完大气校正,都强制先拉一条 Z-Profile 曲线,确认植被的绿峰红谷形态出来了,再往下走融合和反演。这条习惯救过我不少次,也省掉了返工时重新跑一遍全流程的时间。希望帮到你。

本文还有配套的精品资源,点击获取