10 - Leaf optics¶
A leaf's reflectance and transmittance spectra determine how vegetation looks in optical images and how much light a leaf absorbs for photosynthesis. LESS offers three leaf optical properties:
| Property | Input | Use |
|---|---|---|
Prospect |
Leaf biochemistry | General optical simulation |
Fluspect |
Biochemistry and fluorescence quantum yield | When chlorophyll fluorescence is needed |
MeasuredSpectrum |
Measured reflectance and transmittance | When you have measured leaf spectra |
They can be assigned directly to mesh leaves or used as the representative leaf inside statistical vegetation (chapter 12).
PROSPECT¶
PROSPECT treats a leaf as a stack of plates and computes reflectance and transmittance from 400 to 2500 nm from the pigment, water and dry-matter contents:
| Parameter | Meaning | Typical range | Unit |
|---|---|---|---|
cab |
Chlorophyll a+b | 10–80 | µg cm⁻² |
car |
Carotenoids | 5–20 | µg cm⁻² |
canth |
Anthocyanins | 0–40 | µg cm⁻² |
cbrown |
Brown pigments | 0–1 | — |
cw |
Equivalent water thickness | 0.005–0.03 | cm |
cm |
Dry matter | 0.003–0.015 | g cm⁻² |
N |
Leaf structure parameter | 1.0–3.0 | — |
Where each parameter matters most:
| Wavelengths | Main parameters |
|---|---|
| 400–500 nm | Strong absorption by cab and car |
| 500–600 nm | Weaker cab absorption, the green peak |
| 600–700 nm | cab; canth absorbs green and red |
| 700–750 nm (red edge) | cab and N set the position and slope of the red edge |
| 750–1300 nm | N controls scattering in the mesophyll; cab has almost no effect |
| 1300–2500 nm | Water absorption bands (cw) and cm |
Some typical leaf states:
green = less.Prospect(cab=45, car=10, cw=0.012, cm=0.008, N=1.5)
yellow = less.Prospect(cab=5, car=15, cbrown=0.3, cw=0.008, cm=0.010, N=2.0)
red = less.Prospect(cab=3, car=5, canth=30, cbrown=0.15, cw=0.010, cm=0.009, N=1.8)
Compute and compare their spectra with evaluate():
import numpy as np
import matplotlib.pyplot as plt
wavelengths = np.arange(400, 2501, 5)
fig, ax = plt.subplots(figsize=(7, 4))
for name, model in [("green", green), ("yellow", yellow), ("red", red)]:
ax.plot(wavelengths, model.evaluate(wavelengths)["reflectance"], label=name)
ax.set_xlabel("Wavelength (nm)")
ax.set_ylabel("Reflectance")
ax.legend()
fig.savefig("leaf_spectra.png", dpi=150, bbox_inches="tight")
FLUSPECT¶
FLUSPECT extends PROSPECT with chlorophyll fluorescence. The parameters are nearly the same (anthocyanins are called can), plus the fluorescence quantum yield fqe:
fluorescent_leaf = less.Fluspect(cab=45, car=10, cw=0.012, cm=0.006, N=1.5, fqe=0.012)
print(fluorescent_leaf.evaluate([550, 850]))
- a single
fqevalue gives a fixed fluorescence yield; fqe=(0.002, 0.01)gives separate yields for photosystems I and II, so their fluorescence can be computed separately;fqe="dynamic"lets the photosynthesis model set the yield.
When fluorescence is not needed, both models serve equally well for optical simulation. Fluorescence calculations and imaging are covered in chapter 27 and chapter 33.
Measured spectra¶
For measured leaf spectra use MeasuredSpectrum:
measured = less.MeasuredSpectrum(
wavelengths=[400, 500, 550, 650, 700, 750, 850, 1650, 2200],
reflectance=[0.05, 0.07, 0.13, 0.07, 0.25, 0.45, 0.48, 0.32, 0.15],
back_reflectance=[0.07, 0.09, 0.15, 0.09, 0.28, 0.46, 0.49, 0.33, 0.17],
transmittance=[0.01, 0.04, 0.10, 0.03, 0.20, 0.42, 0.45, 0.35, 0.12],
)
reflectanceis the reflectance of the leaf's front face andback_reflectancethat of the back face; without it both faces are the same;- without
transmittancethe leaf is opaque; - spectra are linearly interpolated to the simulation wavelengths.
The front and back faces follow the orientation of the triangles (see chapter 5).
A measured spectrum does not say how much light each pigment absorbs. For photosynthesis, give a pigment partition model so that LESS can estimate the part absorbed by chlorophyll:
leaf_for_photosynthesis = less.MeasuredSpectrum(
wavelengths=[400.0, 550.0, 700.0],
reflectance=[0.08, 0.12, 0.18],
transmittance=[0.04, 0.08, 0.12],
absorption_partition=less.ProspectPartition(cab=45.0),
)
Leaves in the spectral library¶
Leaf spectra from the built-in library can be used directly:
Using leaf models in a scene¶
tree = less.Object("ash", mesh=less.asset_path("FREX.obj"))
tree.set_property("leaves", green)
tree.set_property("stem_branch", less.Lambertian(reflectance=0.08))
scene = less.Scene()
scene.size = 20.0
scene.terrain = less.Terrain(property=less.Lambertian(reflectance=0.12))
scene.illumination = less.Illumination(
source=less.Sun(zenith=35, azimuth=150), atmosphere=less.NoAtmosphere())
scene.add(tree, positions=[[10, 10, 0]])
sensor = less.OpticalImager(less.Orthographic(image_size=128),
bands=[650, 550, 450], quality=32)
summer = scene.simulate(sensor)
tree.set_property("leaves", red)
autumn = scene.simulate(sensor)