Measures the material held in each stockpile of a yard from the yard's own cameras. Every in_0 Image is placed against the camera views of the site bundle bound to site; its in_1 Mask list of material and its in_2 Mask list of open ground are read against a carried yard surface seeded from the survey bound to survey, and the yard is solved again: cells a camera sees keep their height, cells a camera sees open ground on are lowered to the pad, and every cell no camera reaches is rebuilt from what was seen at the material's angle of repose. Each frame yields one measurement on out_0 -- volume, tonnes, a low-to-high range and the seen share per pile, the outline of each pile's seen part in that frame, the camera's pose, and every few frames a height map of the whole yard -- and on out_1 the frame itself, corrected for the lens, with each pile's material tinted in that pile's colour.
Typical backends
A recorded or live pan camera and a fixed camera are decoded at about one frame a second and merged into one stream. Each frame is segmented twice by any segmenter that emits a mask list -- SAM 3 with "coal pile" for the material and with "ground, concrete floor, road" for open ground is one example -- and measured; the record goes out as JSON and the painted frames as a video stream, so a viewer can redraw the yard in 3D from the height map and lay each frame over it from the camera's pose.
Caveats
- Hard constraintThe site bundle is a numpy archive commissioned for one yard: the pad under each pile, the area each pile may occupy, the surveyed elevation of everything that is not stockpile, the repose angle with its uncertainty, the commissioned bulk density, and every camera with its centre, intrinsics and reference views. The survey must be made on that same bundle's grid; a survey from another bundle is refused at start-up.
- Hard constraintFrames must be the size their camera was calibrated at, and every mask must be the size of its frame; a mismatch raises instead of rescaling. A site may hold at most 64 reference views; a bundle with more is refused at start-up.
- I/O contractEvery frame yields exactly one record and one painted frame. A frame that matches no reference view, or carries no material mask above the noise floor
min_mask_px, is reported as skipped with the reason and the figures last solved, an empty pose, and the frame passed on as it came, neither corrected nor painted; it changes nothing. Until the first frame after a start is placed there are no figures: the piles list is empty, the totals are 0 and no yard map goes out. - I/O contractThe pose and the outlines describe the painted frame: a pinhole camera at the pose's position, turned by its rotation (world to camera, rows pointing right, down and forward in the frame) with the pose's focal length and centre, lands every yard point on its pixel. World coordinates are the site bundle's easting, northing and height in metres.
- I/O contractThe yard height map goes out on the first placed frame after a start and then every
model_every_frames frames, at model_cell_m cells, north up: each cell's height in centimetres above the datum (0 where nothing was surveyed), the pile it belongs to (0 for none), and whether a camera measured it or it was rebuilt, with the position of every camera. Each map is complete on its own, so a consumer that joins late only waits for the next one. A surveyed structure that stands over coal, such as a conveyor, stays in the map above it. On a JSON output an empty list (no pose, no yard map, no outline) arrives as null, so a consumer reads null as empty. - I/O contractOnly open ground is evidence that a pile is gone. A pixel on a machine, a conveyor, a wall or a fence in front of a pile is in neither list and says nothing about the pile behind it; where the two lists overlap the pixel counts as material.
- AccuracyThe figure stands on what the cameras see. Hidden ground is rebuilt at the repose angle -- a cone rolled from the seen cells, the seen near flank mirrored across the ridge, held below what the angle allows from the pile's toe and below the pile's own seen summit -- so a face cut steeper than repose by a machine and hidden from every camera reads low. Pile areas that touch are read as one continuous heap: the slope rolled from a pile's measured cells carries on across a shared boundary into a neighbour's hidden cells, held there by the neighbour's own toe and seen summit. The seen share per pile says how much of the figure the cameras stood behind. On the ZETES-3 yard on 24.06.2026 the rebuild from the study's seen cells gives 58,292 m3 against a same-day laser survey of 60,491 m3, and one pass of the recorded pan camera read through SAM 3 material and ground masks gives 59,469 m3 at 57% of the footprint seen.
- AccuracyThe low and high volumes span the same solve at the repose angle and at that angle minus and plus its commissioned uncertainty; a shallower angle can read more on one pile and less on another, so each pile's range is the smallest and largest of the three, and the yard's low and high are the sums of the piles' lows and highs, wider than any one solve. They do not cover a face cut steeper than repose that no camera sees, nor the uncertainty of bulk density.
- AccuracyHeights a camera sees are the carried surface's: the survey's, until a camera sees open ground on a cell. Material piled on ground the surface holds as bare is counted, but its height is rebuilt rather than read, so stacking on top of a seen pile is not measured until the next survey. The rebuild rolls from cells that hold material: a whole pile set down where the surface held none reads 0 m3 until a survey that covers it is bound.
- Parameter interactionA cell is lowered to the pad, or taken in as new material, only after
confirm_votes different reference views contradict what the surface carries there, each from a pixel at least edge_margin_px inside its mask; a segmenter that misses or spills material on one view can neither empty a pile nor grow one. - State lifetimeThe carried surface -- heights, which cells are still survey-anchored, sweep marks and pending votes -- is persisted state and survives a restart. Binding a different survey re-anchors it. A cell counts as seen when a view saw material on it in the current or the previous sweep, so figures fill in over the first sweep after a re-anchor and do not dip when a new sweep starts.
- LimitationMachines and plant block sight lines at their surveyed height; a machine that has moved since the survey still blocks where it stood. A cell counts as measured only where its pixel shows material, so cells a machine, a conveyor or a fence hides are rebuilt from what the cameras do see.
- LatencyThe yard is solved again only when a frame reaches a view not read since the last solve, flips a cell, or opens a sweep; each solve rebuilds the hidden ground three times and takes about a second on a 0.5 m grid of half a million cells. Other frames cost the placement and the read, a few tenths of a second.