Skip to content

22 - Four-component classification

FourComponentImager classifies what the sensor sees in each pixel into four classes: sunlit leaves, shaded leaves, sunlit soil and shaded soil, and gives the visible area of each. The four components are widely used for unmixing thermal pixels, retrieving component temperatures and modelling directional brightness temperature.

How the classification works

Each pixel sends a number of viewing rays. Where a ray reaches the scene, two questions are asked:

  1. Did it land on the ground or on a leaf?
  2. Can that point see the sun? A ray is sent towards the sun; if it is blocked, the point is shaded.

Combining the answers gives four classes. Each pixel is labelled with its majority class, and the fraction of each class is kept as well, so the information in mixed pixels is not lost.

Label Component Meaning
0 background Hit nothing
1 sunlit_soil Sunlit soil
2 sunlit_leaf Sunlit leaves
3 shaded_soil Shaded soil
4 shaded_leaf Shaded leaves

For statistical vegetation, a ray counts as a leaf as soon as it enters the canopy boundary.

Example

import less

scene = less.Scene()
scene.size = 30.0
scene.terrain = less.Terrain(property=less.Lambertian(reflectance=0.15))
scene.illumination = less.Illumination(
    source=less.Sun(zenith=35, azimuth=180), atmosphere=less.NoAtmosphere())

maize = less.Object("maize", mesh=less.asset_path("maize.obj"))
maize.set_property(less.Lambertian(reflectance=0.45, transmittance=0.05))
scene.add(maize, positions=[(x, y, 0.0) for x in range(6, 25, 3) for y in range(6, 25, 3)])

sensor = less.FourComponentImager(
    less.Orthographic(image_size=256, extent=20.0, center=(15.0, 15.0)),
    num_samples=64)
product = scene.simulate(sensor)
print(product.summary())
product.save_classification("four_component.png")

Four-component classification uses orthographic projection only, so that the component areas have a clear geometric meaning. num_samples is the number of viewing rays per pixel and sets the precision of the fractions.

Results

Attribute or method Shape Meaning
product.labels (rows, columns), uint8 Majority class of each pixel
product.fractions (rows, columns, 4) Fractions of the four classes: sunlit soil, sunlit leaves, shaded soil, shaded leaves
product.pixel_area_m2 number Ground area of one pixel
product.summary() dictionary Visible area of each component (m²)
product.area(name) number Visible area of one component
product.save_classification(path) — Saves a colour classification map

Component areas are summed from the fractions:

\[A_c = \sum_{\text{pixels}} f_c \, A_{\text{pixel}}\]

where f is the fraction of the component in the pixel. The four areas add up to the imaged area, 20 m × 20 m = 400 m² here, which is a useful check:

areas = product.summary()
print(sum(areas[name] for name in ("sunlit_soil", "sunlit_leaf", "shaded_soil", "shaded_leaf")))

If the imaged area extends beyond the ground, the difference shows up as background.

Periodic scenes

With periodic boundaries, both viewing rays and shadow rays continue across the scene edges. When the sun is low, long shadows can come back from the other side of the scene, so the shaded soil area grows noticeably while the total soil area stays the same:

scene.repetitive = True
periodic = scene.simulate(sensor)
print(periodic.summary())

Next