# How Kalman Filter Parameters Affect Tracking Accuracy in BoxMOT

> Discover how Kalman filter parameters in BoxMOT influence tracking accuracy. Learn to tune position and velocity weights, detection scaling, and more for optimal performance.

- Repository: [Mike/boxmot](https://github.com/mikel-brostrom/boxmot)
- Tags: deep-dive
- Published: 2026-03-07

---

**BoxMOT achieves multi-object tracking accuracy through five tunable Kalman filter parameters—position weight, velocity weight, detection confidence scaling, initial covariance, and process-noise scaling—that control the balance between motion model trust and detection responsiveness.**

BoxMOT unifies state-of-the-art trackers like ByteTrack and StrongSort under a single framework. In [`boxmot/motion/kalman_filters/aabb/base_kalman_filter.py`](https://github.com/mikel-brostrom/boxmot/blob/main/boxmot/motion/kalman_filters/aabb/base_kalman_filter.py), the linear-Gaussian Kalman filter implementation exposes scalar parameters that directly determine how quickly each tracker adapts to new detections versus smoothing trajectories, making understanding these Kalman filter parameters essential for optimizing tracking accuracy in BoxMOT.

## Position and Velocity Weights

### Position Uncertainty Scaling (_std_weight_position)

In `BaseKalmanFilter.__init__` at line 39 of [`boxmot/motion/kalman_filters/aabb/base_kalman_filter.py`](https://github.com/mikel-brostrom/boxmot/blob/main/boxmot/motion/kalman_filters/aabb/base_kalman_filter.py), the `_std_weight_position` parameter scales both process-noise and measurement-noise for the positional components (x, y, width, height).

- **Low values** (default 1/20): The filter treats detections as relatively noisy, trusting the constant-velocity motion model more heavily. This produces smoother trajectories but may cause lag during sudden direction changes or miss rapid accelerations.
- **High values** (e.g., 1/10): The filter reacts aggressively to new detections, reducing latency but potentially introducing jitter when the detector produces noisy bounding boxes.

### Velocity Uncertainty Scaling (_std_weight_velocity)

Defined at line 42 in the same file, `_std_weight_velocity` controls noise scaling for the velocity components (dx, dy, dw, dh).

- **Low values**: Assumes precise velocity estimates, causing aggressive extrapolation that may overshoot during abrupt stops or direction reversals.
- **High values** (default 1/160): Allows greater velocity uncertainty, giving the filter flexibility to adapt to acceleration and deceleration. However, this increases state variance, potentially expanding gating distances and creating more opportunities for false associations.

## Detection Confidence Integration

The `confidence` parameter dynamically adjusts measurement noise based on detector quality. In `BaseKalmanFilter.project` (line 86) and `StrongSort`'s `KalmanFilter.project` (line 46 in [`boxmot/trackers/strongsort/strongsort_kf.py`](https://github.com/mikel-brostrom/boxmot/blob/main/boxmot/trackers/strongsort/strongsort_kf.py)), the implementation scales the measurement standard deviation by `(1 - confidence)`.

High-confidence detections receive proportionally lower measurement noise, pulling the state estimate strongly toward the observation. Low-confidence detections are down-weighted to prevent noisy bounding boxes from destabilizing the track. Ignoring this factor by setting uniform confidence values causes the filter to treat all detections equally, allowing low-quality detections to corrupt the state estimate and degrade tracking accuracy.

## Initialization and Process Noise Tuning

### Initial Covariance Settings (_get_initial_covariance_std)

Tracker-specific overrides like `KalmanFilterXYWH._get_initial_covariance_std` in [`boxmot/motion/kalman_filters/aabb/xywh_kf.py`](https://github.com/mikel-brostrom/boxmot/blob/main/boxmot/motion/kalman_filters/aabb/xywh_kf.py) (lines 18-28) set the starting uncertainty based on the initial bounding box dimensions. 

- **Small initial variances**: Cause the filter to cling to potentially inaccurate initial poses, making it difficult to recover from early mis-detections.
- **Excessively large values**: Make the filter overly responsive to the first few frames of measurement noise, causing temporary trajectory instability before convergence.

### Size-Dependent Process Noise

The `_get_process_noise_std` and `_get_multi_process_noise_std` methods (lines 30-44 in [`xywh_kf.py`](https://github.com/mikel-brostrom/boxmot/blob/main/xywh_kf.py)) compute process noise proportional to current box dimensions (`mean[2]`, `mean[3]`). Larger objects inherently receive larger absolute process noise allowances, matching the intuition that bigger objects can traverse more pixels between frames without violating the constant-velocity assumption. The multipliers (typically `2×` and `10×` factors found in the source) directly control how quickly the filter adapts to size-dependent motion changes.

## Practical Code Examples

### Customizing Filter Weights for Fast-Moving Scenes

```python
from boxmot.motion.kalman_filters.aabb.xywh_kf import KalmanFilterXYWH

kf = KalmanFilterXYWH()

# Default weights (1/20 for position, 1/160 for velocity)

print(kf._std_weight_position, kf._std_weight_velocity)

# Customizing for a fast-moving scene

kf._std_weight_position = 1.0 / 10   # more trust in detections

kf._std_weight_velocity = 1.0 / 80     # allow larger velocity variations

```

### Incorporating Detection Confidence in Updates

```python
import numpy as np

# Initialization from a detection (x, y, w, h)

measurement = np.array([200., 150., 80., 200.])
mean, cov = kf.initiate(measurement)

# Predict one frame ahead

mean, cov = kf.predict(mean, cov)

# New detection with a confidence score of 0.3 (30%)

new_meas = np.array([210., 155., 78., 195.])
confidence = 0.3
mean, cov = kf.update(mean, cov, new_meas, confidence=confidence)

```

### Adjusting Initial Covariance for Permissive Startup

```python

# Override the method to use a larger initial uncertainty

def larger_init_std(self, measurement):
    # Double the default standard deviations

    base = self._get_initial_covariance_std(measurement)
    return [2 * s for s in base]

KalmanFilterXYWH._get_initial_covariance_std = larger_init_std

```

## Summary

- **`_std_weight_position`** controls positional noise; lower values smooth trajectories but increase lag, while higher values improve responsiveness at the cost of potential jitter.
- **`_std_weight_velocity`** governs velocity uncertainty; tuning this affects how the filter handles acceleration and the size of association gating distances.
- **`confidence` scaling** in the `project` method automatically down-weights low-quality detections, preventing detector noise from destabilizing tracks.
- **`_get_initial_covariance_std`** determines startup behavior; overly conservative values prevent recovery from initial mis-detections.
- **Size-dependent process noise** in `_get_process_noise_std` couples filter uncertainty to object scale, allowing larger absolute motion for bigger objects.

## Frequently Asked Questions

### What happens if `_std_weight_position` is set too low?

Setting `_std_weight_position` too low (e.g., 1/50) causes the filter to treat every detection as highly noisy. The predicted trajectory will jitter because each new measurement heavily overwrites the prior state, and the filter may fail to smooth out detector noise, reducing tracking accuracy in BoxMOT.

### How does detection confidence affect the Kalman update?

According to the source code in [`boxmot/motion/kalman_filters/aabb/base_kalman_filter.py`](https://github.com/mikel-brostrom/boxmot/blob/main/boxmot/motion/kalman_filters/aabb/base_kalman_filter.py) line 86, the detection confidence scales the measurement noise standard deviation by `(1 - confidence)`. High-confidence detections receive lower measurement noise, pulling the state estimate closer to the observation, while low-confidence detections are effectively ignored to maintain track stability.

### Why does BoxMOT scale process noise by bounding box size?

The `_get_process_noise_std` implementation in [`boxmot/motion/kalman_filters/aabb/xywh_kf.py`](https://github.com/mikel-brostrom/boxmot/blob/main/boxmot/motion/kalman_filters/aabb/xywh_kf.py) multiplies noise by the current width and height (`mean[2]`, `mean[3]`). This design reflects the physical intuition that larger objects can move greater absolute distances between frames without changing their apparent motion model, allowing the filter to adapt appropriately to scale-dependent dynamics.

### Which file should I edit to tune Kalman parameters for all trackers?

For trackers using the AABB (axis-aligned bounding box) filter family, edit [`boxmot/motion/kalman_filters/aabb/base_kalman_filter.py`](https://github.com/mikel-brostrom/boxmot/blob/main/boxmot/motion/kalman_filters/aabb/base_kalman_filter.py) to change `_std_weight_position` and `_std_weight_velocity` defaults. For StrongSort specifically, modify [`boxmot/trackers/strongsort/strongsort_kf.py`](https://github.com/mikel-brostrom/boxmot/blob/main/boxmot/trackers/strongsort/strongsort_kf.py), which maintains a separate Kalman filter implementation with identical parameter semantics.