-
Decode only what we need
The files are 4K H.264 High 4:2:2, 10-bit at ~147 Mb/s. NVDEC cannot decode 4:2:2 10-bit, so decoding is on the CPU and is the bottleneck. With PyAV we decode only the reference frames of the IBBP GOP (every 3rd frame, ≈10 fps) and convert straight to 1920×1080. Decoding runs in a background thread so it overlaps GPU work.
-
Detect and track
YOLO26-L (COCO weights, FP16, image size 1280, batch 8, confidence 0.10) detects people, bicycles, cars, motorcycles, buses, trucks and animals. ByteTrack (high/low thresholds 0.25/0.10, 3 s buffer for occlusion by buses and the sign gantry) links detections into tracks.
-
Register to one reference frame
Every 5 s the frame is registered to a reference frame with SIFT features and a RANSAC homography, against a bank of three lighting references (noon, evening sun, dusk). The camera is re-mounted between recordings (shifts up to ~60 px) and drifts ~10 px during the first half-minute of a clip. All geometry lives in the reference frame.
-
Draw the scene once
On the reference image we drew the approach and outbound carriageways, the median, the islands, three zebra crossings, the approach stop line, the solid lane dividers (as rays from the road's vanishing point) and the traffic-signal lamps. A flow field, the dominant motion direction in every 16-px cell, is learned from all sample tracks.
-
Read the traffic signal
The main-road phase comes from the three lamps of the vehicle signal head on the median tip, with per-lamp brightness normalisation and handling for flashing green and occlusion. A pedestrian head that runs in phase is the fallback. The plan is fixed-time: a 75 s cycle at noon (red 36 s, green 36 s, yellow 3 s), 80 s in the evening and dusk clips.
-
Apply the event rules
Each class is one rule on trajectories, the layout and the signal (see the class list below). road_obstacle, fire_smoke and the second branch of accident ("crashed car") use the open-vocabulary detector YOLOE-26L with baked-in text prompts once per second and require strict persistence.
-
Post-process segments
Overlapping segments of the same class are merged into one (the annotation convention), with small per-class gaps (0–6 s), then clipped to the clip duration. Segments shorter than 0.2 s are dropped.
-
Online perception
The same detector at image size 960 on every 3rd frame, online ByteTrack and registration every 5 s. The score at time t uses only frames up to t.
-
Conflict cues
Each mapped to [0, 1]: crossing paths (time-to-collision from predicted footprint overlap), rear-end (fast closing in the same lane, lane identity from the vanishing-point angle), pedestrian conflict (a pedestrian on the carriageway about to be reached by a moving vehicle) and hard braking.
-
Combine and smooth
The cues are combined as independent evidence and smoothed with a fast-attack / slow-release filter, so the score rises quickly and decays slowly.
-
Learned anticipation
20 scale-free kinematic features per frame (the cues, time to contact under constant velocity and constant acceleration, pedestrians and two-wheelers near moving cars, proximity, closing speed, braking, swerving, speed, counts) feed five small networks (with their last 1–3 s of history) and five causal temporal convolutions (the last ~6 s). Their averaged probability of a crash within 5 s is the output. Trained on 200 real CCTV crashes we timed plus ordinary traffic; on held-out clips Score B is 0.47 (0.12 with the cues alone), with alarms ~2.8 s before contact.
-
Calibrate
A monotone mapping sends the lowest probability that raises no false alarm on held-out sample videos to 0.5, the official alarm threshold; once an alarm starts, a new one cannot start for 10 s. On the 18.4 min of sample traffic the output raises no alarm. The hand-made cue score, with its immediate alarm when two vehicles are about to touch, is the fallback when no model file is present.