# How to Implement Multi-Camera Tracking Synchronization in BoxMOT

> Learn to implement multi-camera tracking synchronization in BoxMOT using global identities and camera motion compensation for consistent predictions across moving camera streams.

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

---

**Multi-camera tracking synchronization in BoxMOT is achieved by sharing global identities through the `location` attribute in `BaseTrack` and applying Camera Motion Compensation (CMC) to maintain consistent predictions across moving camera streams.**

BoxMOT (mikel-brostrom/boxmot) supports multi-camera (MC) scenarios by synchronizing the state of individual trackers running on each video stream. The library provides dedicated hooks in `BaseTrack` and tracker implementations like StrongSort to maintain consistent global identities across cameras. This guide covers the three core synchronization mechanisms and provides a complete implementation based on the actual BoxMOT source code.

## Understanding the Location Attribute for Global Identity

The foundation of multi-camera synchronization lies in the `location` attribute defined in [`boxmot/trackers/basetrack.py`](https://github.com/mikel-brostrom/boxmot/blob/main/boxmot/trackers/basetrack.py) (lines 41-59). Every concrete track inherits from `BaseTrack`, which defines:

```python

# in boxmot/trackers/basetrack.py

location: tuple = (np.inf, np.inf)   # (camera_id, global_id)

```

This **2-tuple stores `(camera_id, global_track_id)`** for every track object. When a detection matches an existing track, the tracker copies the `location` from the matched track.

To synchronize identities across cameras:

- When a new object appears in camera A, assign a fresh global ID (e.g., `0`) and store it in `location`
- When the same object appears in camera B, **merge the two tracks by copying the `location`** from the known track in camera A
- Tracks belonging to the same real-world object share the same `global_track_id` regardless of the camera source

## Camera Motion Compensation for Consistent Predictions

Camera Motion Compensation (CMC) estimates affine or homography warps between consecutive frames to keep predictions stable when cameras move. In [`boxmot/trackers/strongsort/strongsort.py`](https://github.com/mikel-brostrom/boxmot/blob/main/boxmot/trackers/strongsort/strongsort.py) (lines 21-25), the tracker initializes a CMC object:

```python

# in boxmot/trackers/strongsort/strongsort.py

self.cmc = get_cmc_method("ecc")()

```

During each update cycle, if active tracks exist, the warp matrix is computed and applied to all tracks:

```python

# boxmot/trackers/strongsort/strongsort.py

if len(self.tracker.tracks) >= 1:
    warp_matrix = self.cmc.apply(img, xyxy)   # → 2×3 or 3×3 warp

    for track in self.tracker.tracks:
        track.camera_update(warp_matrix)

```

The per-track method `camera_update` (implemented in [`boxmot/trackers/strongsort/sort/track.py`](https://github.com/mikel-brostrom/boxmot/blob/main/boxmot/trackers/strongsort/sort/track.py), lines 39-49) transforms the track's center and size according to the warp matrix. This ensures that **world-coordinate predictions remain consistent** even when the camera undergoes motion.

## Implementing Multi-Camera Synchronization

To wire multiple cameras together, instantiate one tracker per camera via `create_tracker` from [`boxmot/trackers/tracker_zoo.py`](https://github.com/mikel-brostrom/boxmot/blob/main/boxmot/trackers/tracker_zoo.py) (lines 27-36) and maintain a shared global ID mapping.

### Step 1: Create Per-Camera Trackers

Initialize separate tracker instances for each camera stream:

```python
from pathlib import Path
import numpy as np
from boxmot.trackers.tracker_zoo import create_tracker

CAM_IDS = [0, 1]  # two cameras

trackers = {}

for cam_id in CAM_IDS:
    trackers[cam_id] = create_tracker(
        tracker_type="strongsort",
        reid_weights=Path("weights/reid.pt"),
        device="cpu",
        half=False,
    )

```

### Step 2: Maintain Global ID Bookkeeping

Create a mapping system to track `(camera_id, local_track_id)` pairs to global identities:

```python
global_id_counter = 0
global_id_map = {}  # (cam_id, local_track_id) → global_id

def assign_global_id(cam_id, local_track):
    """Assign or retrieve a global ID for a track."""
    global global_id_counter
    key = (cam_id, local_track.id)

    if key in global_id_map:
        return global_id_map[key]

    # New appearance: allocate fresh global ID

    global_id = global_id_counter
    global_id_counter += 1
    global_id_map[key] = global_id
    local_track.location = (cam_id, global_id)
    return global_id

```

### Step 3: Process Frames with Synchronized IDs

For each frame, update the tracker and propagate global identities through the `location` field:

```python
def process_frame(cam_id: int, img: np.ndarray, detections: np.ndarray):
    """
    Process detections and return results with global IDs.
    detections: Nx6 np.ndarray [x1, y1, x2, y2, conf, cls]
    """
    tracker = trackers[cam_id]
    tracks = tracker.update(detections, img, embs=None)
    
    results = []
    for trk in tracks:
        x1, y1, x2, y2, trk_id, conf, cls, _ = trk
        # Retrieve underlying Track object to access location

        strong_track = next(
            t for t in tracker.tracker.tracks if t.id == int(trk_id)
        )
        global_id = assign_global_id(cam_id, strong_track)
        
        results.append((global_id, (x1, y1, x2, y2), float(conf), int(cls)))
    return results

```

This implementation ensures that `process_frame` returns **global IDs consistent across all camera streams**, enabling downstream multi-camera fusion logic such as 3-D triangulation.

## Summary

- **`BaseTrack.location`** stores a `(camera_id, global_id)` tuple in [`boxmot/trackers/basetrack.py`](https://github.com/mikel-brostrom/boxmot/blob/main/boxmot/trackers/basetrack.py) that enables identity sharing across cameras by copying the location between matched tracks.
- **Camera Motion Compensation** in StrongSort applies warp matrices to track predictions via `camera_update()` in [`boxmot/trackers/strongsort/sort/track.py`](https://github.com/mikel-brostrom/boxmot/blob/main/boxmot/trackers/strongsort/sort/track.py), maintaining spatial consistency when cameras move.
- **`create_tracker`** in [`boxmot/trackers/tracker_zoo.py`](https://github.com/mikel-brostrom/boxmot/blob/main/boxmot/trackers/tracker_zoo.py) generates per-camera instances, while a custom `global_id_map` synchronizes identities by writing to each track's `location` attribute.
- The CLI in [`boxmot/engine/cli.py`](https://github.com/mikel-brostrom/boxmot/blob/main/boxmot/engine/cli.py) (lines 162-168) already supports multiple models with `multiple=True`, providing an alternative entry point for multi-camera pipelines.

## Frequently Asked Questions

### How does BoxMOT merge identities across different cameras?

BoxMOT merges identities by copying the `location` attribute from existing tracks to new tracks. When the same object appears in a second camera, you locate the matching track from the first camera and copy its `(camera_id, global_id)` tuple to the new track's `location` field, effectively synchronizing their global identities.

### What trackers support multi-camera synchronization?

Any tracker inheriting from `BaseTrack` supports multi-camera synchronization through the `location` attribute. StrongSort is the primary implementation used for multi-camera scenarios because it includes built-in Camera Motion Compensation via `get_cmc_method("ecc")()` and the `camera_update()` method in [`boxmot/trackers/strongsort/sort/track.py`](https://github.com/mikel-brostrom/boxmot/blob/main/boxmot/trackers/strongsort/sort/track.py).

### Where is the Camera Motion Compensation implemented?

Camera Motion Compensation is implemented across three files: the abstract interface in [`boxmot/motion/cmc/base_cmc.py`](https://github.com/mikel-brostrom/boxmot/blob/main/boxmot/motion/cmc/base_cmc.py) (lines 15-24), the factory method in [`boxmot/motion/cmc/__init__.py`](https://github.com/mikel-brostrom/boxmot/blob/main/boxmot/motion/cmc/__init__.py), and the concrete application in [`boxmot/trackers/strongsort/strongsort.py`](https://github.com/mikel-brostrom/boxmot/blob/main/boxmot/trackers/strongsort/strongsort.py) where `warp_matrix` is computed and applied to each track via `track.camera_update()`.

### Can I use the BoxMOT CLI for multi-camera tracking?

Yes. The CLI entry point in [`boxmot/engine/cli.py`](https://github.com/mikel-brostrom/boxmot/blob/main/boxmot/engine/cli.py) supports the `--yolo-model` and `--reid-model` arguments with `multiple=True` (lines 162-168), allowing you to specify multiple models for different camera streams. However, for full identity synchronization across cameras, you must implement the `location` attribute mapping logic shown in the code examples above.