Skip to content

18 - Sensor overview

A sensor describes from where, in what way and in which bands the scene is observed. This chapter covers what all sensors have in common: projections, bands, sampling and results. The following chapters introduce the optical, radiation-measurement, LiDAR, thermal, fluorescence and microwave sensors.

What an imaging sensor consists of

An imaging sensor combines a projection and a set of bands:

import less

sensor = less.OpticalImager(
    less.Orthographic(image_size=128),   # projection
    bands=[650, 550, 450],               # bands (nm)
    quality=32,                          # samples per pixel
)

The same projections are used for optical, thermal and fluorescence imaging.

Projections

Orthographic

All viewing rays are parallel and the pixel grid is fixed on a horizontal reference plane above the ground. The result is a map-like image with north up and east to the right:

nadir = less.Orthographic(image_size=256)                     # 256 × 256 pixels
fine = less.Orthographic(resolution=0.1)                      # 0.1 m per pixel
subset = less.Orthographic(image_size=128, extent=20, center=(25, 25))
oblique = less.Orthographic(image_size=128, view_zenith=30, view_azimuth=120)
Parameter Meaning
image_size Number of pixels, an integer or (width, height)
resolution Ground resolution (m), instead of image_size
extent Imaged area (m), the whole scene by default
center Image centre (east, south), the scene centre by default
view_zenith, view_azimuth Viewing zenith and azimuth for oblique views
terrain_following On uneven terrain, each pixel corresponds to the ground below it

For oblique views the horizontal plane holding the pixel grid is set by scene.measurement_plane: by default ("auto") it is the top of the scene, which suits canopy reflectance; with 0 it is the ground, and objects are displaced in the image along the viewing direction according to their height:

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

Orthographic projection

Perspective

A normal camera, where nearer objects look larger:

camera = less.Perspective(resolution=512, fov=35,
                          position=(25, 60, 20),   # camera position
                          target=(25, 25, 5))      # point the camera looks at

fov is the field of view in degrees.

Fisheye

Hemispherical views, often used to simulate hemispherical canopy photographs:

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

orientation="up" looks at the sky and "down" at the ground; projection can be "equisolid" (equal solid angle, default), "equidistant", "orthographic" or "stereographic".

Pushbroom

Satellite or airborne pushbroom imaging, see chapter 20.

Sampling method

Choose a sampling policy for the scene:

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

Supported imaging and photon-emission workflows use "sobol" by default. "independent" selects independent random sampling; "stratified" uses stratification. "sobol" uses randomized low-discrepancy points and works best with power-of-two sample counts. The sensor still sets quality or num_photons; the sampler determines how these samples are distributed. Low-discrepancy modes apply to within-pixel locations in optical, thermal, fluorescence and passive microwave images, and initial photon emission for optical BRF, irradiance maps and forward radiation fields. Subsequent scattering uses independent random samples. Other workflows do not yet accept low-discrepancy modes. LiDAR, active microwave and processes such as energy balance retain their existing sampling schemes. Optical standard_error requests use independent sampling when no sampling method is specified, as required by that estimator. To reproduce independent random streams, set scene.sampler = less.Sampler("independent").

seed=None inherits the workflow's existing seed. An explicit integer also controls transport random streams in workflows supporting this setting. Repeat simulations with different seeds and sample counts to assess stability: low-discrepancy sampling does not improve convergence in every scene. Set scene.sampler = None to restore the defaults. For microwave images without separate projection sampling settings, the sensor's seed also controls the Sobol digital shift. An explicit scene seed takes priority.

Sampling within pixels

Projection settings can instead change only within-pixel locations while preserving transport random streams. When scene.sampler is set, its method takes priority over projection settings; an explicit scene seed also takes priority.

When pixels contain a mixture of leaves, gaps or shadows, more evenly distributed sample locations may improve convergence:

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

pixel_sampling=None follows the defaults above. Explicit "independent" selects independent random samples. "stratified" jitters one sample within each equal-area cell and accepts any positive integer quality. "sobol" uses digitally shifted Sobol points; powers of two are recommended for quality. These options also apply to thermal, fluorescence and passive microwave images and to other passive imaging projections. Active microwave continues to use its sensor's seed.

sampling_seed changes only the locations within pixels, leaving subsequent transport random inputs unchanged. Repeating with different seeds assesses pixel-quadrature variability, rather than uncertainty in the entire transport process. Stratified and Sobol samples are correlated, so the optical standard_error product requires independent sampling. Convergence still depends on scene boundaries and scattering; check stability as quality increases.

Bands

rgb = [650, 550, 450]                          # list of band centres (nm)
sentinel = less.Sentinel2A()                   # Sentinel-2A spectral response functions
landsat = less.Landsat8_OLI()                  # Landsat 8 OLI
hyperspectral = less.Hyperspectral(start=400, stop=1000, step=10)

With a list of band centres, each band is computed at a single wavelength. With a satellite instrument, LESS samples each band across its spectral response and weights the samples; spectral_resolution is the sampling interval (nm):

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

Bands in the result keep the order in which they were given.

Sampling

quality is the number of samples per pixel. Monte Carlo results contain random noise, roughly inversely proportional to the square root of the number of samples: four times as many samples halves the noise. Check a scene with small values, increase them for final results, and compare results at different sample counts to make sure they are stable.

quality Use
16–64 Previews
128–256 General analysis
512 and above Quantitative work

Non-imaging sensors have their own sampling parameters, such as num_photons for multi-angle reflectance.

Sensors at a glance

Sensor Result Chapter
OpticalImager Optical images 19, 20
BRFSensor Multi-angle reflectance 21
IrradianceMapSensor Upwelling and downwelling irradiance maps 23
IrradianceRadiometer Point irradiance 24
LiDARSurvey Point clouds, waveforms 25
ThermalImager Thermal images 26
SIFImager Fluorescence images 27
RadarScatterometer Backscattering coefficients 29
MicrowaveRadiometer Brightness temperatures 30

Results

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)          # (rows, columns, bands)
image.save("image.png")          # for viewing
image.save("image.tif")          # keeps the values
image.show()                     # display with matplotlib

Image values are spectral radiance (W m⁻² sr⁻¹ nm⁻¹); image.to_brf() converts them to reflectance factor.

Next