Skip to content

Hungarian Tracker

app.infrastructure.tracking.hungarian_tracker

View source code

HungarianIoUTracker — pure NumPy/SciPy multi-object tracker.

Architectural contract

  • ZERO Qt dependencies.
  • ZERO UI / views imports.
  • Accepts and returns only plain Python / NumPy data.
  • The TrackingWorker (infrastructure layer) is responsible for unpacking ReviewFrameItemViewModel dicts, feeding this engine, and repacking results.

Algorithm

  1. For each new frame, compute IoU between all active tracks and all detections.
  2. Build a cost matrix (cost = 1.0 - IoU).
  3. Solve the linear assignment problem with scipy.optimize.linear_sum_assignment.
  4. Accept matches whose IoU >= iou_threshold.
  5. Unmatched detections → new tracks.
  6. Unmatched tracks → coast internally (move by last velocity, decay confidence).
  7. Tracks whose confidence drops below min_confidence are pruned; unobserved states are not emitted.

For axis-aligned boxes, the overlap and assignment cost are

\[ \operatorname{IoU}(A,B)=\frac{|A\cap B|}{|A\cup B|}, \qquad C_{ij}=1-\operatorname{IoU}(T_i,D_j). \]

The Hungarian solver minimizes total assignment cost; a candidate match is accepted only when its IoU meets iou_threshold.

See Also

Layer: Infrastructure tracking. Context: A Qt-independent tracker consumes plain detections and returns per-frame track states to the tracking worker.

TrackInput dataclass

One detection handed to the tracker for a single frame.

Layer: Infrastructure. Context: Implements concrete processing or I/O behind application-facing contracts.

bbox_xyxy: BBoxXYXYTuple instance-attribute

confidence: float instance-attribute

label: str instance-attribute

__init__(bbox_xyxy: BBoxXYXYTuple, confidence: float, label: str) -> None

TrackState dataclass

The live view_state of one confirmed track, returned per frame.

Layer: Infrastructure. Context: Implements concrete processing or I/O behind application-facing contracts.

bbox_xyxy: BBoxXYXYTuple instance-attribute

confidence: float instance-attribute

label: str instance-attribute

observed: bool = True class-attribute instance-attribute

time_since_update: int = 0 class-attribute instance-attribute

uid: int instance-attribute

velocity: tuple[float, float] = field(default=(0.0, 0.0)) class-attribute instance-attribute

__init__(uid: int, bbox_xyxy: BBoxXYXYTuple, confidence: float, label: str, velocity: tuple[float, float] = (0.0, 0.0), observed: bool = True, time_since_update: int = 0) -> None

HungarianIoUTracker

Associate frame detections with active tracks by global IoU assignment.

PARAMETER DESCRIPTION
iou_threshold

Minimum IoU required to accept a detection-track match.

TYPE: float DEFAULT: 0.3

confidence_decay

Confidence decrease applied to a track per missed frame.

TYPE: float DEFAULT: 0.05

min_confidence

Minimum confidence at which an unmatched track remains active.

TYPE: float DEFAULT: 0.1

__init__(iou_threshold: float = 0.3, confidence_decay: float = 0.05, min_confidence: float = 0.1) -> None

reset() -> None

Clear all live tracks and reset the UID counter.

update(detections: list[TrackInput]) -> list[TrackState]

Associate one frame of detections and advance unmatched tracks.

PARAMETER DESCRIPTION
detections

Detection boxes for the current frame.

TYPE: list[TrackInput]

RETURNS DESCRIPTION
list[TrackState]

Current active track states, including coast age and observation flags.

RAISES DESCRIPTION
ValueError

If the assignment solver rejects the cost matrix.

Note

Coast states remain active until their confidence falls below the configured floor, allowing later detections to reconnect.

Example

states = tracker.update([TrackInput((0, 0, 10, 10), 0.9, "person")])