float(b5)-b4 那个 float 是为了整型除法不归零
一行表达式背后的类型系统、整数截断陷阱与遥感指数计算的工程实践
摘要:在 ENVI 的 Band Math 工具里,float(b5)-b4 是一行看起来平平无奇的表达式,但那个 float() 恰恰是很多人踩坑之后才补上的关键一步。本文以这一行表达式为线索,从 IDL 的类型系统与整型除法规则讲起,逐层展开波段运算中的类型提升、整数截断、数据范围与 NoData 处理、NDVI 等归一化指数的计算陷阱,再延伸到指数扩展、大区域分块处理、云平台与深度学习时代的波段运算演进。全文贯穿一条主线:波段运算的可靠性,取决于对底层数据类型与运算规则的精确控制,而不是对表达式的直觉想象。文中给出可复现的操作路径、参数设置与验证方法,并对常见误区做工程层面的辨析。
目录
1. 引子:一行表达式引发的困惑
很多遥感初学者在 ENVI 里做 NDVI,第一次写表达式时往往会直接写成 (b5-b4)/(b5+b4),然后发现结果图要么全黑、要么一片 0 和 1,要么出现大量莫名其妙的 0 值。等到翻教程、问同事,得到的答案往往是"前面加个 float"——于是表达式变成 float(b5)-b4 或者 float(b5-b4)/float(b5+b4),问题似乎就解决了。
但"加个 float 就好了"这种说法,其实掩盖了真正需要理解的东西:为什么加了 float 就不一样?不加会怎样?加了之后数据到底发生了什么变化?如果只是机械地记住"要加 float",那么换一个指数、换一种传感器、换一个平台,同样的坑还会再踩一遍。
本文的写作动机正来自这里。标题里的 float(b5)-b4 只是一个引子,真正要讲的是波段运算背后的类型系统与运算规则。笔者认为,把这一层讲透,比记住一百个表达式模板都有用。
本文评述:"加 float"是一种经验性补丁,而理解整型除法是一种可迁移的能力。前者解决一次问题,后者解决一类问题。技术文章的价值,恰恰在于把经验补丁还原为可推理的规则。
2. IDL 类型系统与整型除法的底层逻辑
2.1 ENVI 与 IDL 的关系
ENVI 的波段运算引擎建立在 IDL(Interactive Data Language)之上。ENVI 的 Band Math 表达式最终会被解析为 IDL 表达式并在 IDL 运行时中执行。因此,理解 Band Math 的行为,本质上就是理解 IDL 的表达式求值规则。这一点非常关键:Band Math 不是一套独立语言,而是 IDL 表达式的一个受控子集。
IDL 由 Harris Geospatial(原 ITT Visual Information Solutions,更早为 Research Systems Inc.)开发,是一种面向数组的科学计算语言。它的类型系统与 C 语言有相似之处,但在数组运算和类型提升上有自己的规则。ENVI 官方文档在 Band Math 章节中明确指出,表达式遵循 IDL 的运算规则,包括整数运算的截断行为(来源:NV5 Geospatial 官方文档,ENVI Band Math 帮助页)。
2.2 IDL 的基本数值类型
IDL 的数值类型大致可分为整数族和浮点族。整数族包括字节(BYTE,8 位无符号)、16 位有符号整型(INT)、16 位无符号整型(UINT)、32 位长整型(LONG)、32 位无符号长整型(ULONG)、64 位长整型(LONG64)等;浮点族包括 32 位浮点(FLOAT)、64 位双精度(DOUBLE),以及复数类型 COMPLEX 和 DCOMPLEX。
表 1:IDL 主要数值类型对照(来源:NV5 Geospatial IDL 官方文档,Data Types 章节;数值范围为标准 IEEE/整型定义)。
2.3 整型除法:截断而非四舍五入
在 IDL 中,当除法运算符 / 两侧都是整数类型时,结果仍然是整数类型,并且采用向零截断(truncation toward zero)的方式取整。例如:
IDL> print, 7/2
3
IDL> print, 1/2
0
IDL> print, 3/4
0
IDL> print, -7/2
-3
注意最后一行:-7/2 得到 -3 而不是 -4,说明是向零截断,而不是向下取整。这个细节在处理差值、比值时可能造成方向性偏差,值得留意。
那么关键问题来了:如果 1/2 等于 0,那么对于一个反射率数据来说,很多小于 1 的比值都会被截断成 0。这正是 NDVI 计算"归零"的根源。
笔者认为:整型除法本身没有错,它是计算机科学中一种高效且确定的运算。问题在于,遥感指数计算在数学上期望的是实数除法,而数据存储类型却往往是整数。当数学期望与存储类型不一致时,截断就发生了。float() 的作用,就是把这个不一致显式地纠正过来。
2.4 类型提升规则
IDL 在二元运算中遵循类型提升(type promotion)规则:当两个操作数类型不同时,结果类型取两者中"更高"的那一个。大致顺序为 BYTE < INT < UINT < LONG < ULONG < LONG64 < FLOAT < DOUBLE < COMPLEX < DCOMPLEX(具体顺序在不同版本中略有差异,以官方文档为准)。
这意味着:只要表达式中有一个操作数是 FLOAT,整个运算就会以浮点方式进行。所以 float(b5)-b4 中,float(b5) 把 b5 提升为浮点,b4 在与它相减时也被提升为浮点,结果自然是浮点。这就是"加 float 就好了"的技术原理。
3. Band Math 的类型提升与表达式解析机制
3.1 Band Math 如何读取波段
在 ENVI Classic 的 Band Math 中,用户输入表达式,用 b1、b2、b3…… 或 b5、b4 这样的占位符代表波段,然后在下方为每个占位符指定实际波段文件。ENVI 会按波段逐个读取数据块,代入表达式求值,再写出结果。
在 ENVI 5.x 及更新版本中,Band Math 以工具形式存在(Toolbox → Band Algebra → Band Math),交互方式有所变化,但表达式语义保持一致。ENVI 还提供 Band Math 的批处理版本和 API 接口,便于自动化。
需要强调的是:Band Math 读取波段时,会保留波段的原始数据类型。如果输入波段是 INT 或 UINT,那么 b5、b4 在表达式中就是整数;如果输入是 FLOAT,那它们本身就是浮点。这一点决定了表达式是否需要显式 float()。
3.2 表达式求值顺序与括号
IDL 的运算符优先级与多数语言类似:括号最高,其次是一元运算符、乘除、加减。因此 float(b5)-b4 先对 b5 取浮点,再与 b4 相减;而 float(b5-b4) 则先做整数减法,再整体转浮点。两者在结果上可能不同——前者避免了减法溢出,后者则可能先溢出再转换。
举个具体例子:假设 b5=100,b4=200,都是 BYTE 类型。float(b5)-b4 得到 100.0-200 = -100.0;而 float(b5-b4) 中 b5-b4 在 BYTE 运算下会下溢(BYTE 无负值),结果可能是 156(模 256),再转浮点得到 156.0。这是一个非常隐蔽的坑。
本文评述:float 的位置比 float 本身更重要。把 float 放在最外层,只能解决"结果是浮点"的问题,解决不了"中间过程溢出"的问题。正确的做法是:在可能产生负值或超出原类型范围的第一步运算之前,就完成类型提升。
3.3 输出类型的选择
Band Math 允许用户指定输出数据类型。如果表达式结果是浮点,但输出类型选了 BYTE 或 INT,那么写文件时又会发生一次截断或溢出。ENVI 通常会给出提示,但用户需要主动确认。对于 NDVI 这类取值范围在 -1 到 1 之间的指数,输出类型应选 FLOAT 或 DOUBLE;若希望节省空间,也可以先线性拉伸到 0-255 再存为 BYTE,但那是显示层面的处理,不应与计算混为一谈。
4. float(b5)-b4 到底在做什么:逐层拆解
4.1 从 NDVI 表达式说起
NDVI(归一化差值植被指数)的经典定义是:
NDVI = (NIR - Red) / (NIR + Red)
在 Landsat 8 OLI 中,NIR 对应 Band 5,Red 对应 Band 4。所以表达式写成 (b5-b4)/(b5+b4)。如果 b5 和 b4 都是 INT 或 UINT,那么分子和分母都是整数,除法就是整型除法。
假设某像元 b5=8000,b4=4000(典型反射率放大 10000 倍后的 DN 值)。分子 8000-4000=4000,分母 8000+4000=12000,整型除法 4000/12000=0。真实 NDVI 应该是 0.333,但结果是 0。这就是"归零"。
表 2:整型除法与浮点除法在 NDVI 计算中的对比(模拟数据,用于说明截断效应)。
可以看到,只要分子绝对值小于分母,整型除法结果就是 0。对于植被指数而言,绝大多数像元的 NDVI 都在 -1 到 1 之间,也就是分子绝对值小于分母,于是整幅图几乎全是 0。这不是算法问题,而是类型问题。
4.2 float(b5)-b4 与 float((b5-b4)/(b5+b4)) 的区别
两种写法都能得到浮点结果,但过程不同:
float(b5)-b4:先把 b5 转浮点,减法在浮点下进行,得到浮点差值。如果后面还要除以 (b5+b4),需要再确保分母也是浮点。float(b5-b4)/float(b5+b4):分子分母分别转浮点,再相除,全程浮点。float((b5-b4)/(b5+b4)):先做整数除法和整数减法,最后才转浮点。此时截断已经发生,float 只是把 0 变成 0.0,毫无意义。
所以标题里说"那个 float 是为了整型除法不归零",严格来说,float(b5)-b4 本身只保证了减法不溢出,真正让除法不归零的,是参与除法的操作数中至少有一个是浮点。在完整表达式里,通常写成 float(b5-b4)/float(b5+b4) 或 1.0*(b5-b4)/(b5+b4) 更稳妥。
笔者认为:标题里的 float(b5)-b4 之所以流传甚广,是因为它出现在很多教程的"正确示例"里,但它是被简化过的。真正严谨的写法应该把类型提升放在所有可能出问题的运算之前。工程实践中,宁可多写几个 float,也不要赌中间过程不溢出。
4.3 一个可复现的验证实验
读者可以用 ENVI 自带示例数据或任意 Landsat 影像做如下验证:
- 打开 Band Math,输入
(b5-b4)/(b5+b4),b5 选 NIR,b4 选 Red,输出类型选 FLOAT。观察结果统计:最小值、最大值、均值。 - 再输入
float(b5-b4)/float(b5+b4),同样输出 FLOAT。再次统计。 - 对比两次结果的直方图。第一次的结果会高度集中在 0 附近,第二次才会呈现 NDVI 典型的双峰分布(植被峰与土壤/水体峰)。
这个实验不需要复杂工具,几分钟就能完成,但它能把"类型"这个抽象概念变成肉眼可见的差异。笔者建议每一位遥感初学者都亲手做一遍。
5. NDVI 计算:整数截断最经典的翻车现场
5.1 NDVI 的数学性质
NDVI 由 Rouse 等人于 1973 年提出(Rouse et al., 1973, Third ERTS Symposium),最初用于监测植被覆盖。它的定义是近红外与红光反射率之差除以两者之和,取值范围理论上为 -1 到 1。健康植被在近红外强反射、红光强吸收,因此 NDVI 较高;水体、云、雪在红光和近红外都较高或都较低,NDVI 接近 0 或为负。
正因为 NDVI 是归一化比值,它的分子绝对值通常小于分母,这就使得整型除法几乎必然归零。换句话说,NDVI 是整型除法陷阱的"完美受害者"。
5.2 不同传感器的波段对应
表 3:常见传感器 NDVI 波段对应(来源:USGS Landsat 文档、ESA Sentinel-2 用户手册、NASA MODIS 产品说明)。
可以看到,不同传感器的 DN 范围差异很大。Landsat 5 TM 的 BYTE 数据在整型除法下几乎必然归零;Landsat 8 的 UINT 数据虽然范围大,但比值仍然小于 1,同样归零。所以无论哪种传感器,float 都不可省。
5.3 反射率定标与 NDVI 的关系
严格来说,NDVI 应基于反射率计算,而不是原始 DN。因为 DN 受太阳辐照度、大气、传感器增益等影响,直接算 NDVI 会引入误差。USGS 建议先做辐射定标(Radiometric Calibration)和大气校正(Atmospheric Correction),再计算指数。
但即使做了定标,如果反射率数据以 INT 存储(例如放大 10000 倍),整型除法问题依然存在。所以类型控制是贯穿整个预处理链路的,不是某一步的事。
本文评述:很多人把 NDVI 归零归咎于"没做大气校正",其实更直接的原因是类型。大气校正影响的是数值精度,类型截断影响的是数值是否存在。两者层级不同,不能混为一谈。
6. 从 NDVI 到指数家族:类型控制的通用范式
6.1 归一化差值类指数
NDVI 属于归一化差值指数(Normalized Difference Index)家族。同类还有 NDWI(归一化水体指数,McFeeters, 1996)、NDBI(归一化建筑指数,Zha et al., 2003)、NDMI(归一化湿度指数,Gao, 1996)、NDSI(归一化雪指数,Hall et al., 1995)等。它们的共同形式是:
NDx = (A - B) / (A + B)
因此它们面临完全相同的整型除法问题。只要 A、B 是整数,结果就归零。处理范式也完全一致:在分子分母计算前完成浮点提升。
6.2 比值类指数
比值指数(Ratio Index)如 SR(简单比值,Birth & McVey, 1968)定义为 NIR/Red。这类指数不需要减法,但除法同样面临整型截断。例如 NIR=8000,Red=4000,整型除法得到 2;如果 NIR=8000,Red=3000,整型除法得到 2(真实值 2.667)。截断发生在小数部分。
所以比值类指数也需要 float,只是症状不像 NDVI 那么极端(不会全归零,但会损失精度)。
6.3 土壤调节与大气抵抗类指数
SAVI(土壤调节植被指数,Huete, 1988)引入了土壤调节因子 L:
SAVI = (NIR - Red) * (1 + L) / (NIR + Red + L)
这里 L 通常取 0.5。如果 NIR、Red 是整数,L 是浮点,那么表达式中的运算会因为 L 的存在而部分提升为浮点。但要注意:(NIR - Red) 这个子表达式如果先算,仍然是整数减法,可能溢出。所以稳妥写法是 float(NIR - Red) * (1 + L) / (float(NIR) + Red + L)。
EVI(增强植被指数,Huete et al., 2002)更复杂,涉及蓝光波段和多个系数:
EVI = 2.5 * (NIR - Red) / (NIR + 6 * Red - 7.5 * Blue + 1)
这里系数 2.5、6、7.5、1 都是浮点,所以整个表达式会被提升为浮点。但同样要注意子表达式的整数溢出风险。EVI 的官方产品(如 MODIS MOD13)在算法文档中明确要求使用浮点运算(来源:NASA MODIS Vegetation Index Products User Guide)。
笔者认为:指数越复杂,类型问题越隐蔽。因为复杂表达式里往往混有浮点系数,让人误以为"已经是浮点了"。但子表达式的整数运算仍然可能先溢出。工程上的安全做法是:对每个可能产生负值或超范围的子表达式,都显式 float。
7. 数据范围、NoData 与掩膜处理的工程细节
7.1 反射率放大倍数的影响
许多反射率产品为了用整数存储小数,会把反射率乘以一个放大倍数(scale factor),例如 10000。这样 0.5 的反射率存为 5000。计算 NDVI 时,分子分母都带同一个倍数,理论上会约掉,所以不影响比值结果。但放大后的数值更大,整型除法的截断比例反而更明显(因为小数部分被放大后仍然是整数)。
例如反射率 0.8000 和 0.4000,放大 10000 倍后是 8000 和 4000。整型 NDVI = (8000-4000)/(8000+4000) = 4000/12000 = 0。如果不放大,0.8 和 0.4 是浮点,直接算得 0.333。可见放大倍数并不解决类型问题。
7.2 NoData 与背景值
遥感影像常有 NoData 值(如 0、-9999)或背景填充值。在 Band Math 中,这些值会参与运算,可能产生异常结果。例如 NoData=-9999,两个波段都是 -9999 时,NDVI = 0/0,结果是 NaN 或报错。
处理方式有几种:
- 在 Band Math 中用条件表达式排除,例如
(b5 ne 0) ? float(b5-b4)/float(b5+b4) : 0(IDL 三元运算符语法需按版本确认)。 - 先做掩膜(Masking),把 NoData 区域排除,再计算指数。
- 在 ENVI 的 Band Math 中设置"忽略值"(Ignore Value),但该功能在不同版本中支持程度不同。
ENVI 官方文档建议,对于含 NoData 的数据,先构建掩膜再运算,或使用 ENVI 的 Masking 工具。这一点在批量处理时尤其重要,因为 NoData 处理不当会导致统计结果严重偏差。
7.3 分母为零的处理
当 NIR + Red = 0 时,NDVI 分母为零。在浮点运算中,0.0/0.0 得到 NaN,x/0.0 得到 Inf。ENVI 在写出结果时可能将 NaN 写为特定值或报错。稳妥做法是在表达式中加一个小量,或显式判断分母。
; 加小量避免除零(需评估对结果的影响) float(b5-b4) / (float(b5+b4) + 1e-6) ; 或显式判断(伪代码,具体语法按 IDL 版本) (b5+b4) gt 0 ? float(b5-b4)/float(b5+b4) : 0
加小量会轻微改变结果,对于 NDVI 这种量级(0.001 级别)影响可忽略,但在高精度研究中应记录处理方式。
8. 大区域与多波段:分块、批处理与性能
8.1 分块处理
当影像很大(如整景 Landsat、Sentinel-2 或全国拼接影像)时,一次性读入内存可能导致溢出。ENVI 的 Band Math 支持分块处理(Tiling),但用户需要设置合适的块大小。ENVI 官方建议根据可用内存和影像大小调整。
分块处理时要注意:块边界处如果涉及邻域运算(如滤波),需要重叠缓冲;但波段运算通常是逐像元的,不涉及邻域,所以分块相对简单。
8.2 批处理与自动化
ENVI 提供多种批处理方式:
- ENVI Classic 的 Band Math 可保存表达式,配合 Batch 工具批量应用。
- ENVI 5.x 的 Modeler(可视化建模)可把 Band Math 作为节点,构建处理流程。
- IDL 脚本调用 ENVI API,实现完全自动化。
- ENVI Task 和 ENVI Services Engine 支持服务化部署。
在自动化流程中,类型控制更要显式化,因为没有人会逐个检查中间结果。建议在脚本中统一使用 float 或 double,并在输出时明确指定类型。
8.3 性能考量
浮点运算比整数运算慢,但在现代计算机上差异不大。对于大规模处理,瓶颈通常在 I/O 而非计算。因此,为了正确性而使用浮点,性能代价可以接受。如果确实需要优化,可以考虑:
- 使用 FLOAT 而非 DOUBLE,除非精度要求极高。
- 减少中间文件写出,尽量在内存中完成多步运算。
- 使用 ENVI 的多线程和 GPU 加速(部分版本支持)。
9. 云平台与深度学习时代的波段运算演进
9.1 Google Earth Engine 中的类型处理
Google Earth Engine(GEE)是当前最主流的云端遥感计算平台。在 GEE 中,影像波段默认是浮点类型(如 Landsat 反射率产品是 float),所以 normalizedDifference() 函数内部已经处理了类型问题。但 GEE 中仍有整数类型(如 uint16 的原始 DN),如果直接运算仍可能截断。
GEE 的 ee.Image.normalizedDifference() 是一个便捷函数,它内部会做类型转换。但用户自定义表达式时,仍需注意。GEE 文档明确指出,整数除法会截断(来源:Google Earth Engine Developer Guide, Image Arithmetic)。
9.2 Python 生态中的类型处理
在 Python 中,rasterio、xarray、numpy 等库处理栅格数据时,类型同样关键。numpy 的整型数组除法会得到浮点结果(Python 3 中 / 是真除法),但 // 是整除。如果从 IDL 迁移到 Python,要注意运算符差异。
例如 numpy 中:
import numpy as np b5 = np.array([8000], dtype=np.uint16) b4 = np.array([4000], dtype=np.uint16) # 错误:整数减法可能下溢 # 正确:先转浮点 ndvi = (b5.astype(np.float32) - b4) / (b5.astype(np.float32) + b4)
这里 astype(np.float32) 就相当于 IDL 的 float()。概念完全一致,只是语法不同。
9.3 深度学习与波段运算
近年来,深度学习在遥感领域应用广泛,如作物分类、地物分割、变化检测。深度学习模型通常以浮点张量为输入,所以数据预处理阶段就需要把 DN 转为浮点。这在一定程度上"顺带"解决了整型除法问题,但也带来新的类型问题:归一化方式、通道顺序、数据类型(float32 vs float64)等。
例如,许多模型要求输入归一化到 0-1 或 -1 到 1。如果归一化时用了整数除法,同样会归零。所以类型意识在深度学习流程中依然重要。
本文评述:工具在变,从 ENVI 到 GEE 到 PyTorch,但类型系统的基本规则没变。整数除法的截断行为是计算机科学的底层事实,不会因为平台升级而消失。掌握它,就能在新工具中快速定位同类问题。
9.4 前沿方向:类型感知的自动化流程
当前一些研究在探索"类型感知"的遥感处理流程,即在流程编排阶段就自动推断每步运算的输入输出类型,避免截断。例如,基于抽象语法树的表达式分析、基于数据流图的类型传播等。这类方法在编译原理中已有成熟理论,迁移到遥感处理流程中是自然延伸。
笔者认为,随着遥感数据量增大和流程复杂化,类型感知的自动化会越来越重要。人工检查每个表达式的时代终将过去,但理解原理的人,才能设计出正确的自动化规则。
10. 操作路径与验证清单
10.1 ENVI Band Math 操作步骤
- 打开 ENVI,加载影像。确认波段数据类型(可在 Layer Manager 或 Metadata 中查看)。
- 打开 Toolbox → Band Algebra → Band Math。
- 在表达式框中输入
float(b5-b4)/float(b5+b4)(或按本文建议的写法)。 - 点击"Add"或"OK",为 b5、b4 分别指定 NIR 和 Red 波段。
- 选择输出路径和输出数据类型(建议 FLOAT)。
- 运行,查看结果统计和直方图。
- 如需批处理,保存表达式并在 Batch 工具中复用。
10.2 验证清单
表 4:波段运算验证清单(笔者整理)。
10.3 延伸学习资源
- NV5 Geospatial 官方 ENVI 文档与教程:https://www.nv5geospatialsoftware.com/docs/ENVI.html
- IDL 官方文档(Data Types 与 Operators 章节):https://www.nv5geospatialsoftware.com/docs/IDL.html
- USGS Landsat 波段说明与 NDVI 教程:https://www.usgs.gov/landsat-missions
- Google Earth Engine 官方文档:https://developers.google.com/earth-engine
- NASA MODIS 植被指数产品说明:https://modis.gsfc.nasa.gov/data/dataprod/mod13.php
- ESA Sentinel-2 用户手册:https://sentinels.copernicus.eu/web/sentinel/user-guides/sentinel-2-msi
11. 结语:把 float 当成一种工程习惯
回到标题:float(b5)-b4 那个 float,表面上是语法,实质上是类型意识。它提醒我们:遥感数据不是抽象的数学符号,而是有具体存储类型、取值范围、精度限制的工程对象。忽略这些,再漂亮的算法也会在第一步就失真。
笔者认为,把 float 当成一种工程习惯,比记住某个表达式更有价值。这种习惯包括:
- 拿到数据先看类型,而不是先写表达式。
- 在可能产生负值、小数、超范围的运算前,主动提升类型。
- 输出时确认类型,不让截断发生在最后一步。
- 在批处理和自动化流程中,把类型控制写成规则,而不是靠人盯。
这些习惯不限于 ENVI,也不限于 NDVI。它们适用于任何遥感计算平台、任何指数、任何流程。掌握它们,才算真正跨过了波段运算的门槛。
12. 参考文献与延伸资源
本文涉及的参考文献与资料共 60 余项,涵盖经典指数文献、官方技术文档、平台指南与近年研究。以下列出主要参考文献 9 项,其余以延伸资源形式给出。
主要参考文献
- Rouse, J.W., Haas, R.H., Schell, J.A., Deering, D.W. (1973). Monitoring vegetation systems in the Great Plains with ERTS. Third ERTS Symposium, NASA SP-351, 309-317.
- Huete, A.R. (1988). A soil-adjusted vegetation index (SAVI). Remote Sensing of Environment, 25(3), 295-309.
- Huete, A., Didan, K., Miura, T., Rodriguez, E.P., Gao, X., Ferreira, L.G. (2002). Overview of the radiometric and biophysical performance of the MODIS vegetation indices. Remote Sensing of Environment, 83(1-2), 195-213.
- McFeeters, S.K. (1996). The use of the Normalized Difference Water Index (NDWI) in the delineation of open water features. International Journal of Remote Sensing, 17(7), 1425-1432.
- Zha, Y., Gao, J., Ni, S. (2003). Use of normalized difference built-up index in automatically mapping urban areas from TM imagery. International Journal of Remote Sensing, 24(3), 583-594.
- Gao, B.C. (1996). NDWI—A normalized difference water index for remote sensing of vegetation liquid water from space. Remote Sensing of Environment, 58(3), 257-266.
- NV5 Geospatial. (202
微信扫一扫分享
打开微信「扫一扫」,扫描二维码后在微信中分享给好友或朋友圈。
💬 评论 (0)
评论功能已关闭

