← All updates

Motion threshold that learns the scene

Replaced the fixed motion threshold with a percentile-over-decaying-histogram floor and a diurnal EMA. The detector adapts to each scene over time. No more 3 AM false triggers from wind in the trees.

Backend motionaccuracy

The biggest weakness of fixed-threshold motion detection is that no single number is right for every camera at every time of day. A driveway at noon is a different problem than the same driveway at 3 AM. So I stopped using one number.

What it does now

Two changes work together:

  1. Percentile floor over a decaying histogram. The detector keeps a

rolling distribution of the last 2 hours of motion-blob fractions and uses the 97th percentile as its "what's quiet here" floor. If wind has been moving leaves all night, the threshold rises to compensate. When the wind stops, the threshold falls again over the next hour.

  1. Diurnal EMA. A separate exponentially-weighted moving average tracks

the scene's typical noise by time of day. 3 AM and 3 PM get different baselines. The EMA learns over weeks.

Both values persist to the database (migration 0016) so the learning survives recorder restarts.

What it killed

Whole categories of false triggers, especially the slow-burn ones: tree shadows moving across a wall as the sun rises, headlight glare from passing cars, distant traffic on a far street. The detector adapts instead of demanding I hand-tune each camera.

Full design: docs/MOTION-ADAPTIVE-THRESHOLD.md. Tuning UI lives at Settings → Motion tuning in the admin console.

Don't miss the next one.

Email when something ships. Or grab the RSS.