跳转至

18 - 传感器概览

传感器描述“从哪里、以什么方式、在哪些波段观测场景”。本章介绍各类传感器共用的部分:投影方式、波段、采样数和结果。后面几章分别介绍光学、辐射测量、激光雷达、热红外、荧光和微波传感器。

成像传感器的组成

成像传感器由投影方式和波段组成:

import less

sensor = less.OpticalImager(
    less.Orthographic(image_size=128),   # 投影方式
    bands=[650, 550, 450],               # 波段(nm)
    quality=32,                          # 每个像元的采样数
)

同一种投影可以用于光学、热红外和荧光成像。

投影方式

正射投影

所有观测光线互相平行,像元网格固定在地面上方的一个水平参考面上,结果是“北在上、东在右”的地图式影像:

nadir = less.Orthographic(image_size=256)                     # 256 × 256 像元
fine = less.Orthographic(resolution=0.1)                      # 0.1 m 一个像元
subset = less.Orthographic(image_size=128, extent=20, center=(25, 25))
oblique = less.Orthographic(image_size=128, view_zenith=30, view_azimuth=120)
参数 含义
image_size 像元数,可以是整数或(宽, 高)
resolution 地面分辨率(m),与 image_size 二选一
extent 成像范围(m),默认是整个场景
center 成像中心(东, 南),默认是场景中心
view_zenith、view_azimuth 观测天顶角和方位角,用于斜视
terrain_following 在起伏地形上让每个像元对应其下方的地面

斜视时,像元网格所在的水平面由 scene.measurement_plane 决定:默认("auto")是场景顶部,适合冠层反射率;设为 0 时是地面,地物在影像中的位置按其高度沿观测方向偏移:

scene = less.Scene()
scene.measurement_plane = 0.0

正射投影

透视投影

模拟普通相机,近大远小:

camera = less.Perspective(resolution=512, fov=35,
                          position=(25, 60, 20),   # 相机位置
                          target=(25, 25, 5))      # 对准的点

fov 是视场角(度)。

鱼眼投影

半球观测,常用于模拟冠层半球照片:

hemispherical = less.Fisheye(resolution=512, position=(25, 25, 0.5), orientation="up", fov=180)

orientation="up" 时向上看天空,"down" 时向下看地面;projection 可以是 "equisolid"(等立体角,默认)、"equidistant"(等距)、"orthographic" 或 "stereographic"。

推扫

卫星或机载推扫成像,见第 20 章。

采样方式

可以为场景统一选择采样方式:

scene.sampler = less.Sampler("sobol", seed=17)
image = scene.simulate(less.OpticalImager(
    less.Orthographic(image_size=128), bands=[550, 850], quality=256))

支持低差异采样的成像和光子发射默认使用 "sobol"。它采用随机化的低差异序列, 建议采样数取 2 的整数次幂。"independent" 使用独立随机采样; "stratified" 使用分层采样。 quality 和 num_photons 仍由传感器设置,采样器只决定如何分布这些样本。 低差异采样适用于光学、热红外、荧光和被动微波影像的像元内位置, 以及光学 BRF、辐照度图和正向辐射场的光子初始发射。 后续散射路径继续采用独立随机采样;其他工作流尚不接受低差异模式。 LiDAR、主动微波和能量等过程保留各自的独立采样方案。 请求光学 standard_error 且未指定采样方式时,采用独立随机采样,以满足标准误差的定义。 需要重现独立随机流时,设置 scene.sampler = less.Sampler("independent")。

seed=None 沿用各工作流已有的种子;显式指定整数时,同时控制支持该设置的 工作流输运随机流。不同种子下重复模拟,可用于评价结果的采样稳定性。 低差异采样不保证每个场景都更快收敛,仍应比较多个采样数和种子。 scene.sampler = None 恢复默认设置。 微波影像未单独指定投影采样时,传感器的 seed 也控制 Sobol 的数字移位; 显式指定的场景种子优先。

像元内采样

也可以只设置投影的像元内采样,保持输运随机流不变。 当 scene.sampler 已设置时,其采样方式优先于投影设置;显式指定的场景种子也优先。

像元同时包含叶片、间隙或阴影时,可以选择更均匀的位置采样:

projection = less.Orthographic(
    image_size=128, pixel_sampling="sobol", sampling_seed=17)
sensor = less.OpticalImager(projection, bands=[550, 850], quality=256)

pixel_sampling=None 表示使用上述默认规则;显式设置 "independent" 选择独立随机采样。 "stratified" 在等面积小格中随机取样, 支持任意正整数采样数;"sobol" 使用随机数字移位的 Sobol 序列,建议将 quality 设为 2 的整数次幂。 这些设置也适用于热红外、荧光和被动微波成像,以及其他被动成像投影。 主动微波仍使用传感器自己的 seed。

sampling_seed 只改变像元内的观测位置,不改变后续散射路径的随机输入。 用不同值重复模拟,可以检查位置采样的稳定性;它不能代替整个输运过程的不确定性评估。 分层和 Sobol 样本之间存在相关性,因此光学 standard_error 产品仅允许独立随机模式。 边界更平滑通常会更快收敛;遮挡和多次散射较强时,仍需增加采样数并检查结果。

波段

rgb = [650, 550, 450]                          # 中心波长列表(nm)
sentinel = less.Sentinel2A()                   # Sentinel-2A 光谱响应函数
landsat = less.Landsat8_OLI()                  # Landsat 8 OLI
hyperspectral = less.Hyperspectral(start=400, stop=1000, step=10)

用中心波长列表时,每个波段按单一波长计算。用卫星传感器时,LESS 在每个波段的光谱响应范围内采样并加权积分,spectral_resolution 是积分的采样间隔(nm):

s2 = less.OpticalImager(less.Orthographic(image_size=64), bands=less.Sentinel2A(),
                        spectral_resolution=5, quality=16)

结果的波段顺序与给出的顺序一致。

采样数

quality 是每个像元的采样数。蒙特卡洛结果带有随机噪声,噪声大致与采样数的平方根成反比:采样数增加 4 倍,噪声减半。可以先用较小的值检查场景,正式计算时增大采样数,并比较不同采样数的结果是否已经稳定。

quality 用途
16–64 预览
128–256 一般分析
512 以上 定量研究

非成像传感器使用自己的采样参数,例如多角度反射率的 num_photons。

传感器一览

传感器 结果 章节
OpticalImager 光学影像 19、20
BRFSensor 多角度反射率 21
IrradianceMapSensor 上下行辐照度图 23
IrradianceRadiometer 点式辐照度 24
LiDARSurvey 点云、波形 25
ThermalImager 热红外影像 26
SIFImager 荧光影像 27
RadarScatterometer 后向散射系数 29
MicrowaveRadiometer 亮温 30

结果

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

image = scene.simulate(sensor)
print(image.data.shape)          # (行, 列, 波段)
image.save("image.png")          # 用于查看
image.save("image.tif")          # 保留原始数值
image.show()                     # 用 matplotlib 显示

影像的数值是光谱辐亮度(W m⁻² sr⁻¹ nm⁻¹)。image.to_brf() 把它换算为反射率因子。

下一步