20 - Satellite pushbroom imaging¶
Pushbroom imaging links the 3-D scene, the atmosphere and the instrument into one chain. Besides radiance, the results include the electrons collected by the detector, the digital numbers (DN) after analogue-to-digital conversion, and the observation position and time of every pixel. Typical uses are comparing sensor designs, analysing how images form and producing test data for algorithms.
Pushbroom imaging describes a stretch of flight track in a local planar coordinate system, which suits local scenes. If you need full orbits, Earth curvature or rigorous geometric correction, generate the observation geometry with an orbit tool first.
Three parts¶
| Part | Class | Content |
|---|---|---|
| Observation geometry | Pushbroom |
Altitude, heading, swath width, ground speed, line rate, scan time |
| Spectrum and atmosphere | OpticalImager |
Bands, samples, observation level, adjacency effect |
| Instrument | Instrument |
Aperture, integration time, optical transmission, quantum efficiency, modulation transfer function, noise, digitisation |
Example¶
import less
scene = less.Scene()
scene.size = 1000.0
scene.terrain = less.Terrain(property=less.Lambertian(reflectance=0.20))
scene.illumination = less.Illumination(
source=less.Sun(zenith=30, azimuth=150),
atmosphere=less.Atmosphere.standard(
"midlatitude_summer", aerosol="continental", aot550=0.10, sky_mode="anisotropic"),
)
projection = less.Pushbroom(
resolution=64, # pixels per scan line
num_lines=64, # scan lines along track
altitude=700000, # altitude (m)
swath_width=1000, # swath width (m)
heading=180, # heading, clockwise from north
ground_speed=7000, # ground speed (m/s)
line_rate=441, # lines per second
start_time=0.0,
)
instrument = less.Instrument(
aperture_diameter=0.20, # m
integration_time=0.001, # s
optical_transmission=0.70,
quantum_efficiency=0.75,
read_noise=4.0, # electrons
dark_current=20.0, # electrons per second
full_well=80000, # electrons
gain=5.0, # electrons per DN
bit_depth=14,
mtf_nyquist=0.30,
smear=0.2, # along-track smear (pixels)
seed=42,
)
sensor = less.OpticalImager(
projection=projection,
bands=less.Sentinel2A(),
spectral_resolution=20,
quality=16,
observation_level="toa",
adjacency_sigma=1.0,
instrument=instrument,
)
product = scene.simulate(sensor)
observation_level="toa" uses the scene's atmosphere model to carry the radiance leaving the surface up to the top of the atmosphere before it enters the instrument.
Scan time and coverage¶
When both ground_speed and line_rate are given, the along-track coverage is
where v is the ground speed, N the number of scan lines and f the line rate. You can also give the coverage directly with ground_track_length, which then takes precedence. Scan line k is recorded at start_time + k / line_rate.
altitude only sets the geometric start of the rays; where atmospheric transmission ends is set by observation_level or observation_altitude_km.
The instrument model¶
For each band, the radiance is converted to the number of photons reaching the detector using the effective bandwidth, entrance-pupil area, pixel solid angle, integration time and optical transmission, and multiplied by the quantum efficiency to obtain electrons. Then, in order:
- point spread function, modulation transfer function, jitter and along-track smear;
- photon shot noise, dark current and read noise;
- full-well clipping, gain and quantisation by the analogue-to-digital converter.
With spectral response functions the effective bandwidth is computed automatically. A fixed seed gives reproducible noise; noise=False shows the result without noise.
Results¶
product.source_radiance # radiance at the entrance pupil
product.radiance # radiance after the spatial response
product.electrons # electrons
product.dn # digital numbers, the same as product.data
product.geolocation # x, y, view zenith, view azimuth and time of every pixel
product.save("satellite_product.npz") # all intermediate quantities
product.save("satellite_dn.tif") # digital numbers and geolocation
product.save("satellite_preview.png", bands=[3, 2, 1])
When the scene has map coordinates, each pixel's position also includes easting, northing and coordinate system, and the GeoTIFF records the pushbroom geometry with ground control points:
scene.georeference = {"crs": "EPSG:32650", "origin": (500000.0, 4001000.0)} # north-west corner of the scene
The scene's y axis points south, so northing decreases southwards from the origin.
Adjacency effect¶
With adjacency_sigma (pixels) greater than 0, neighbouring pixel radiances are mixed according to the molecular and aerosol scattering optical thickness along the viewing path. This approximation leaves the radiance of uniform scenes unchanged and gives a quick estimate of the adjacency effect near bright–dark edges.
Built-in example¶
Scope¶
Pushbroom imaging includes platform motion along a local track, cross-track scanning, per-pixel viewing angles, a 1-D layered atmosphere at any observation level, surface–atmosphere coupling, an adjacency approximation, spectral responses and the detector chain. It does not include orbit dynamics, Earth curvature, attitude time series, scenes that change over time, 3-D cloud radiative transfer or polarisation, so the results are not equivalent to geometrically processed operational satellite products.