Skip to content

使用 gdal_calc 重分类栅格

来源: https://spatialthoughts.com/2019/12/28/gdal-calc/

gdal_calc 是 GDAL 实用程序中使用较少的工具之一。在实际应用中没有太多使用它的例子,一些高级功能也没有很好的文档记录。我发现自己最近经常使用它,并发现了一些非常强大的用例。

处理多波段栅格

gdal_calc 指定输入的语法很独特。如果你想使用 2 个图像 —— input1.tif 和 input2.tif,你可以像下面这样指定它们:

gdal_calc -A input1.tif -B input2.tif ...

但是,如果你想做一些波段运算(band math)或者分别使用输入的每个波段怎么办?如果你的 input.tif 有 4 个波段,你可以这样指定它们:

gdal_calc -A input.tif --A_band=1 -B input.tif --B_band=2 -C input.tif --C_band=3 -D input.tif --D_band=4 ...

表达式语法

gdal_calc 使用 numpy 语法来指定计算。编写表达式有许多不同的方式。这里有一些我首选方法的例子。

假设你有一个单波段图像 input.tif,并且你想找到所有值 > 100 的像素。下面的表达式将在每个像素处进行评估。在像素值通过表达式测试的地方结果将为 1,其他地方为 0。

gdal_calc -A input.tif --calc="A>100" --outfile output.tif

所以这为我们进行重分类提供了基础模块。假设你的目标是将 input.tif 重分类如下:

  • 0-100 → 1
  • 101-200 → 2
  • 200 → 3

我们可以在表达式中添加 3 个条件,并将结果乘以相应的重分类值以获得结果。

gdal_calc -A input.tif --calc="(A<=100)*1 + (A>100)*(A<=200)*2 + (A>200)*3" --outfile output.tif

你也可以使用 logical_orlogical_and 函数来达到同样的结果。

gdal_calc -A input.tif --calc="(A<=100)*1 + logical_and(A>100,A<=200)*2 + (A>200)*3" --outfile output.tif

但是 logical_andlogical_or 只接受 2 个参数。因此,如果你有多个条件(正如我们在下面的例子中将看到的),表达式的编写就会变得比较棘手。所以我更喜欢使用我们之前使用的乘法语法。但是 gdal_calc 可以使用 numpy 库提供的全套函数。查看 例程文档 了解所有可用函数。

重分类多波段栅格

现在我们可以尝试将这些概念应用于重分类多波段栅格。表达式会变得有点复杂,但如果你理解了上面的例子,它应该是有意义的。

假设我们想要将一个 4 波段的 input.tif 重分类如下:

  • (R, G, B, A) 值 (<=100, <=100, <=100, 255) → 1
  • (R, G, B, A) 值 (100-200, 100-200, 100-200, 255) → 2
  • (R, G, B, A) 值 (>=200, >=200, >=200, 255) → 3
  • 所有其他组合 → 0

表达式可以编写如下:

gdal_calc -A input.tif --A_band=1 -B input.tif --B_band=2 -C input.tif --C_band=3 -D input.tif --D_band=4 --outfile output.tif --calc="(A<=100)*(B<=100)*(C<=100)*(D==255) + (A>100)*(A<=200)*(B>100)*(B<=200)*(C>100)*(C<=200)*(D==255)*2 + (A>=200)*(B>=200)*(C>=200)*(D==255)*3"

你可以看到关于如何使用 gdal_calc 的其他示例,请查看我的 Mastering GDAL Tools 课程资料。