跳转至

16 - 光照与大气

场景的光照由两部分组成:太阳(less.Sun)给出太阳的方向和大气层顶的太阳光谱;大气模型计算到达地面的直射光和天空散射光,有的模型还能计算从地面到传感器的大气影响。

import less

scene = less.Scene()
scene.size = 20
scene.terrain = less.Terrain(property=less.Lambertian(reflectance=0.2))
scene.illumination = less.Illumination(
    source=less.Sun(zenith=30, azimuth=150),
    atmosphere=less.SimpleSpectralAtmosphere(turbidity=2.5),
)

Sun 不指定光谱时使用内置的大气层顶太阳光谱。Sun(wavelengths=..., irradiance=...) 可以给出自己的光谱,单位为 W m⁻² nm⁻¹,表示大气层顶垂直于太阳光方向的辐照度。

选择大气模型

模型 适用 说明
less.Atmosphere 卫星和航空影像、大气层顶反射率 分层大气辐射传输,可计算地面光照和到传感器的大气传输
less.SixSAtmosphere 习惯使用 6S 参数 需要安装 less3d[atmosphere]
less.PrescribedAtmosphere 已知直射和散射的透过率 直接给出透过率
less.SimpleSpectralAtmosphere 快速的宽波段模拟 简化的光谱衰减,各向同性天空光
less.HosekWilkieAtmosphere 可见光、需要真实的天空亮度分布 320–720 nm
less.NoAtmosphere 不考虑大气 太阳光不衰减,没有天空光

分层大气 Atmosphere

scene.illumination = less.Illumination(
    source=less.Sun(zenith=30, azimuth=150),
    atmosphere=less.Atmosphere.standard(
        "midlatitude_summer",
        aerosol="continental",
        aot550=0.10,
        ground_altitude_km=0.0,
        streams=8,
        sky_mode="anisotropic",
    ),
)

标准大气廓线:

名称 典型条件
"tropical" 热带
"midlatitude_summer" 中纬度夏季
"midlatitude_winter" 中纬度冬季
"subarctic_summer" 亚北极夏季
"subarctic_winter" 亚北极冬季
"us_standard"、"us76" 1976 年美国标准大气

气溶胶类型有 "continental"、"maritime"、"urban"、"desert"、"biomass_burning" 和 "stratospheric"。aot550 是 550 nm 的气溶胶光学厚度,越大直射光衰减越强。ground_altitude_km 是地面海拔。sky_mode="anisotropic" 保留天空亮度随方向的变化,"isotropic" 则把天空光当作各方向均匀。

自定义廓线

profile = less.AtmosphericProfile.standard("us76")
print(profile.surface_pressure(0.0))                       # hPa
print(profile.column("h2o", ground_altitude_km=0.5))

custom = less.Atmosphere(profile=profile, aerosol="maritime", aot550=0.05)

自定义 AtmosphericProfile 时,高度单位为 km,气压为 hPa,温度为 K,气体数密度为 cm⁻³。

单独计算大气

不建场景也可以计算大气的光照和透过率:

import numpy as np

atmosphere = less.Atmosphere.standard("us76", aot550=0.10)
wavelengths = np.arange(400.0, 1001.0, 5.0)
result = atmosphere.solve(wavelengths, sun_zenith=40, output_altitudes_km=[2.0, 8.0, 20.0])

direct = result.direct_normal_irradiance          # 地面法向直射辐照度
diffuse = result.diffuse_horizontal_irradiance    # 地面水平天空散射辐照度
up = result.upward_transmittance(view_zenith=10, observer_altitude_km=8.0)
结果 含义
direct_normal_irradiance 地面上垂直于太阳光的直射辐照度
diffuse_horizontal_irradiance 地面水平面上的天空散射辐照度
direct_transmittance 太阳直射透过率
upward_transmittance(...) 地面到某一高度的方向透过率
path_radiance(...) 观测方向上的大气程辐射
to_observer(...) 把地面辐亮度传到某一高度
directional_sky_radiance(...) 天空各方向的辐亮度

辐照度单位为 W m⁻² nm⁻¹,辐亮度为 W m⁻² sr⁻¹ nm⁻¹。

航空和卫星高度的影像

使用 Atmosphere 时,光学传感器可以给出某一海拔高度或大气层顶的辐亮度:

projection = less.Orthographic(image_size=64, view_zenith=10, view_azimuth=180)

airborne = scene.simulate(less.OpticalImager(
    projection, bands=less.Sentinel2A(), spectral_resolution=20, quality=16,
    observation_altitude_km=8.0))

top_of_atmosphere = scene.simulate(less.OpticalImager(
    projection, bands=less.Sentinel2A(), spectral_resolution=20, quality=16,
    observation_level="toa"))

observation_altitude_km 是海拔高度,与投影在场景中的几何高度无关。大气对其他传感器同样起作用:荧光影像计入发射波段的向上透过率,热红外影像计入大气向下的长波辐射和大气自身的发射,激光雷达计入往返两次的大气衰减。

6S

pip install "less3d[atmosphere]"
six_s = less.SixSAtmosphere(
    atmosphere_profile="midlatitude_summer",
    aerosol_type="continental",
    aot550=0.1,
    ground_altitude=0.0,
)

廓线名称与上表相同,气溶胶类型有 no_aerosols、continental、maritime、urban、desert 和 biomass_burning。把它作为 Illumination(atmosphere=...) 使用即可。

给定透过率

已经知道大气的直射和散射透过率时:

scene.illumination = less.Illumination(
    source=less.Sun(zenith=40, azimuth=160,
                    wavelengths=[450, 550, 650],
                    irradiance=[1.85, 1.88, 1.55]),
    atmosphere=less.PrescribedAtmosphere(
        wavelengths=[450, 550, 650],
        direct_beam_transmittance=[0.60, 0.70, 0.78],
        diffuse_horizontal_transmittance=[0.20, 0.14, 0.09],
    ),
)

两个系数的定义不同:

  • direct_beam_transmittance = 地面直射辐照度(垂直于光线)/ 大气层顶太阳辐照度(垂直于光线);
  • diffuse_horizontal_transmittance = 地面水平面上的天空散射辐照度 / 大气层顶太阳光在水平面上的辐照度。

即对于太阳天顶角 θ、大气层顶辐照度 E:

地面直射辐照度(垂直于光线) = E × direct_beam_transmittance
地面水平散射辐照度           = E × cos θ × diffuse_horizontal_transmittance

两个系数可以是数值或光谱数组,同一波长上两者之和不超过 1。

简化模型

quick = less.SimpleSpectralAtmosphere(turbidity=2.5)   # 300–2500 nm,各向同性天空
visible_sky = less.HosekWilkieAtmosphere(turbidity=2.5)  # 可见光,天空亮度随方向变化
vacuum = less.NoAtmosphere()

turbidity 是大气浑浊度,晴朗天空约为 2,浑浊天空可达 5 以上。

热红外中的天空

热红外模拟还需要天空的长波辐射。less.Atmosphere 会自己计算;NoAtmosphere 表示没有天空辐射;其他大气模型需要给出天空的亮度温度,或者在模拟时提供微气象条件:

clear_sky = less.SimpleSpectralAtmosphere(turbidity=2.0, sky_temperature=260.0)  # K

使用能量平衡时,less.Microclimate 中的向下长波辐射(不给出时由气温和湿度估算)同时用作热红外的天空。详见第 26 章。

下一步