跳转至

04 - LESS 的工作方式

这一章介绍 LESS 的整体结构:场景由哪些部分组成,属性如何设置,以及怎样用同一个场景得到各种模拟结果。具体用法在后面的章节中展开。

LESS 的主要对象

一个场景,多种模拟

import less

scene = less.Scene()
scene.size = 50.0
scene.terrain = less.Terrain(property=less.Lambertian(reflectance=0.15))
scene.illumination = less.Illumination(
    source=less.Sun(zenith=30, azimuth=150), atmosphere=less.NoAtmosphere())

tree = less.Object("ash", mesh=less.asset_path("FREX.obj"))
tree.set_property("leaves", less.Prospect(cab=40))
tree.set_property("stem_branch", less.Lambertian(reflectance=0.1))
scene.add(tree, positions=[[25, 25, 0]])

rgb = scene.simulate(less.OpticalImager(
    less.Orthographic(image_size=128), bands=[650, 550, 450], quality=32))
nir = scene.simulate(less.OpticalImager(
    less.Orthographic(image_size=128), bands=[850], quality=32))

场景只定义一次。两次 simulate() 使用不同的传感器,第二次直接复用已经建好的几何。

场景的组成

组成部分 设置方式 说明
场景范围 scene.size 地面的水平范围(m)
地形 scene.terrain = less.Terrain(...) 平地、栅格高程或三角网格地形
物体 scene.add(less.Object(...), positions=...) 树木、作物、建筑等,可放置多个实例
光照 scene.illumination = less.Illumination(...) 太阳与大气

一个 Object 由一个或多个组件组成。组件的几何有两种表示:

  • 三角网格(less.Mesh):保留模型中的每个三角形,适合叶片、枝干、建筑(第 11 章);
  • 统计植被(less.TurbidBoundary):只给出冠层的封闭外形,内部叶片用叶面积密度和叶倾角分布描述(第 12 章)。

两种组件可以出现在同一个物体中,例如统计树冠配三角网格树干。

属性

属性描述组件在某一类物理过程中的行为,按物理域分开设置:

物理域 作用 常用属性
光学 短波反射、透射、吸收 Lambertian、Prospect、Fluspect、OpticalVegetation
热 温度与发射率 ThermalProperty
微波 介电与散射特性 MicrowaveSoil、MicrowaveVegetation
生物物理 感热、潜热、土壤热通量的交换方式 BiophysicalProperty
生理 光合作用与气孔导度 Farquhar

同一个组件可以同时具有多个物理域的属性,每次 set_property() 只替换对应物理域的那一个。属性的完整介绍见属性系统。

传感器与过程

scene.simulate() 接受两类对象:

  • 传感器:从某个位置、按某种方式观测场景,得到影像、点云、波形等观测结果;
  • 过程:在场景中求解物理状态,例如每片叶子吸收的辐射、叶温或光合速率。
类别 对象 结果 章节
光学传感器 OpticalImager、BRFSensor 影像、多角度反射率 19–22
辐射测量 IrradianceMapSensor、IrradianceRadiometer 辐照度图、辐照度 23–24
激光雷达 LiDARSurvey 点云、波形 25
热红外 ThermalImager 热辐射影像 26
荧光 SIFImager 荧光影像 27
微波 RadarScatterometer、MicrowaveRadiometer 后向散射系数、亮温 28–30
过程 RadiationFieldProcess、EnergyBalanceProcess、PhotosynthesisProcess 辐射场、叶温、光合 31–33

过程的结果可以交给传感器使用。例如能量平衡求得的叶温可以直接用于热红外成像,光合作用求得的荧光可以用于荧光成像。

每种模拟需要哪些属性

下表中的“需要”只针对参与该模拟的组件。

模拟 光学 热 微波 生物物理 生理
光学成像、多角度反射率 需要 — — — —
激光雷达 需要 — — — —
辐射场 需要 — — — —
热红外成像(给定温度) — 需要 — — —
能量平衡 需要 需要 — 需要 可选
光合作用(给定叶温) 需要 需要 — — 需要
光合作用(同时求叶温) 需要 需要 — 需要 需要
荧光(给定量子产额) Fluspect — — — —
荧光(随光合变化) Fluspect 需要 — 需要 需要
雷达、被动微波 — 可选 需要 — —

缺少必需的属性时,LESS 在模拟开始前报错,并指出缺少的是哪个组件的哪一类属性。

场景的生命周期

场景生命周期

通常只需要调用 simulate():第一次调用时自动构建场景,之后的调用复用已有的几何和加速结构。

方法 作用 何时使用
scene.simulate(...) 必要时自动构建,然后模拟 日常使用
scene.build() 提前构建;场景未变化时不重复构建 单独统计构建耗时;动态更新实例前
scene.rebuild() 无条件重新读取几何并重建 在 LESS 之外修改了同一路径下的 OBJ 或 DEM 文件

修改光照、属性或传感器不需要重建:

scene.illumination = less.Illumination(
    source=less.Sun(zenith=50, azimuth=200), atmosphere=less.NoAtmosphere())
tree.set_property("leaves", less.Prospect(cab=20))
rgb_autumn = scene.simulate(less.OpticalImager(
    less.Orthographic(image_size=128), bands=[650, 550, 450], quality=32))

通过 scene.add()、scene.terrain = ... 等方式改变几何后,下一次 simulate() 会自动重新构建。

模拟结果

simulate() 返回一个结果对象。常用的操作有:

print(rgb.data.shape)       # NumPy 数组:(行, 列, 波段)
rgb.save("forest_rgb.png")  # 保存为图片
rgb.save("forest_rgb.tif")  # 保存原始数值
brf = rgb.to_brf()          # 辐亮度换算为反射率因子
模拟对象 结果 主要内容
OpticalImager 影像 各波段辐亮度,可换算为反射率因子
ThermalImager 影像 热辐亮度,可换算为亮温
BRFSensor 多角度反射率 各方向、各波段的反射率因子
LiDARSurvey 点云或波形 坐标、强度、回波序号或波形
EnergyBalanceProcess 能量平衡结果 温度、净辐射、感热、潜热

下一步