# Motion Detection Tuning

## Overview

Motion detection must reliably detect jumpers while ignoring environmental changes (wind, lighting, snow). Tuning involves balancing sensitivity against false triggers.

## Tuning Strategy

1. Start with defaults — the sample settings work for typical conditions
2. Enable debug output — set `debug_motion=1` to see detection diagnostics
3. Test with file playback — use the file player for repeatable testing
4. Adjust one parameter at a time — change, test, evaluate

## Motion Regions

The most effective tuning step is narrowing the motion region to exclude areas where non-jumper motion occurs (trees, spectators, wind-blown objects).

    # Only monitor the landing hill area in feed 1
    motion_start_x[1]=200
    motion_start_y[1]=100
    motion_end_x[1]=1700
    motion_end_y[1]=900

Use the viewer with `showing_motion=1` to visualize what the detector sees.

## Threshold Tuning

### Per-Pixel Thresholds

These control what counts as a "changed" pixel between frames:

- `ydiff_min[N]` — minimum brightness change to count as different (default 10). Increase if sensor noise causes false pixels. Decrease if the jumper is hard to detect against similar background.
- `udiff_min[N]`, `vdiff_min[N]` — same for color channels. Color changes help detect jumpers wearing colored suits against white snow.

### Frame-Level Thresholds

These filter out whole-frame changes (lighting shifts, camera shake):

- `max_diff_y%` — if more than this percentage of pixels changed, reject the frame (probably a lighting change, not a jumper). Default 0.5%.
- `min_diff_y%` — if fewer than this percentage changed, reject (just noise). Default 0.01%.

Tip: If the system triggers on clouds passing over the hill, lower `max_diff_y%`. If it misses jumpers in low contrast conditions, lower `ydiff_min`.

## Blob Detection Tuning

### Blob Size

- `min_blob_sizes[N]` — blobs smaller than this are noise (default 30 pixels). A jumper at distance typically produces blobs of 50–500 pixels.
- `max_blob_size` — blobs larger than this are rejected (default 50000). Prevents triggering on large lighting changes that pass the percentage filter.

### Blob Merging

Nearby blobs are merged into one. Adjust merge tolerance:

- `blob_fuzz_x` / `blob_fuzz_y` — merge blobs within this many pixels (default 30). Increase if the jumper appears as multiple scattered blobs.

### Blob Movement

- `min_blob_distance[N]` — minimum blob movement per frame (default 2 pixels). Filters out stationary noise blobs.
- `max_blob_distance[N]` — maximum blob movement per frame (default 200 pixels). Filters out random blobs that appear in different locations.

## Trigger Tuning

### Sustained Motion Count

The trigger requires multiple consecutive frames of motion to fire:

- `min_motion_count[N]` — frames of motion needed to start recording (default 3). Increase to reduce false triggers; decrease for faster response.
- `min_nomotion_count[N]` — frames without motion to stop recording (default 10). Increase to avoid premature clip ending if jumper briefly leaves the motion region.

### Neighbor Filter

- `min_blob_neighbors` — minimum neighboring changed pixels for a pixel to be kept (default 2). This removes isolated noise pixels. Increase for noisy cameras; decrease if thin features (ski edges) are lost.

## Common Scenarios

Problem | Adjustment
--- | ---
False triggers on wind/trees | Narrow `motion_start/end` to exclude trees. Increase `min_blob_sizes`.
False triggers on lighting changes | Lower `max_diff_y%` (e.g., 0.3). Increase `min_blob_sizes`.
Misses jumpers in fog/flat light | Lower `ydiff_min` (e.g., 5). Lower `min_blob_sizes` (e.g., 15).
Clips end too early | Increase `min_nomotion_count` (e.g., 20).
Clips start too late | Decrease `min_motion_count` (e.g., 2). Increase `movie_pad`.
Too many small noise blobs | Increase `min_blob_neighbors` (e.g., 3). Increase `min_blob_sizes`.
Jumper splits into multiple blobs | Increase `blob_fuzz_x` and `blob_fuzz_y` (e.g., 50).
Triggers on spectators | Narrow motion region to exclude spectator areas.

## Debug Output

Enable diagnostics to see what the detector is doing:

    debug_motion=1
    debug_distance=1

This prints per-frame information to the console:

- Number of changed pixels per plane
- Threshold values (adaptive)
- Blob count, sizes, centroids
- Movement distance and direction
- Trigger state (motion_count, nomotion_count)

## See Also

- Motion Detection — algorithm details
- Settings Reference — all threshold parameters
- Testing with Video Files — repeatable tuning workflow