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¶
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 表示没有天空辐射;其他大气模型需要给出天空的亮度温度,或者在模拟时提供微气象条件:
使用能量平衡时,less.Microclimate 中的向下长波辐射(不给出时由气温和湿度估算)同时用作热红外的天空。详见第 26 章。