Trackers
End-to-end tracking algorithms.
End-to-end tracker implementations.
This module provides complete tracker implementations that combine filtering, data association, and track management.
- class pytcl.trackers.SingleTargetTracker(state_dim, meas_dim, F, H, Q, R, gate_threshold=None)[source]
Bases:
objectSingle-target tracker using Kalman filtering.
This tracker maintains a single track and provides predict/update functionality with optional gating.
- Parameters:
state_dim (int) – Dimension of state vector.
meas_dim (int) – Dimension of measurement vector.
F (callable or ndarray) – State transition matrix or function F(dt) -> ndarray.
H (ndarray) – Measurement matrix.
Q (callable or ndarray) – Process noise covariance or function Q(dt) -> ndarray.
R (ndarray) – Measurement noise covariance.
gate_threshold (float, optional) – Chi-squared gate threshold (default: None, no gating).
Examples
>>> import numpy as np >>> # Constant velocity model in 2D >>> F = lambda dt: np.array([[1, dt, 0, 0], ... [0, 1, 0, 0], ... [0, 0, 1, dt], ... [0, 0, 0, 1]]) >>> H = np.array([[1, 0, 0, 0], ... [0, 0, 1, 0]]) >>> Q = lambda dt: 0.1 * np.eye(4) >>> R = np.eye(2) * 0.5 >>> tracker = SingleTargetTracker(4, 2, F, H, Q, R) >>> tracker.initialize(np.array([0, 1, 0, 1]), np.eye(4)) >>> tracker.predict(1.0) >>> tracker.update(np.array([1.1, 1.2]))
- initialize(state, covariance, time=0.0)[source]
Initialize the tracker with initial state.
- Parameters:
state (array_like) – Initial state estimate.
covariance (array_like) – Initial state covariance.
time (float, optional) – Initial time (default: 0).
- property state: TrackState | None
Get current track state.
- predict(dt)[source]
Predict state to new time.
- Parameters:
dt (float) – Time step.
- Returns:
Predicted state.
- Return type:
- Raises:
RuntimeError – If tracker is not initialized.
- update(measurement)[source]
Update state with measurement.
- Parameters:
measurement (array_like) – Measurement vector.
- Returns:
state (TrackState) – Updated state.
likelihood (float) – Measurement likelihood (Mahalanobis distance).
- Raises:
RuntimeError – If tracker is not initialized.
- Return type:
- class pytcl.trackers.TrackState(state, covariance, time)[source]
Bases:
NamedTupleState of a single target track.
- state
State estimate vector.
- Type:
ndarray
- covariance
State covariance matrix.
- Type:
ndarray
- class pytcl.trackers.MultiTargetTracker(state_dim, meas_dim, F, H, Q, R, gate_probability=0.99, confirm_hits=3, confirm_window=5, max_misses=5, init_covariance=None)[source]
Bases:
objectMulti-target tracker with GNN data association.
This tracker maintains multiple tracks and handles: - Track initiation from unassociated measurements - Track update via GNN data association - Track confirmation (M-of-N logic) - Track deletion (miss count)
- Parameters:
state_dim (int) – Dimension of state vector.
meas_dim (int) – Dimension of measurement vector.
F (callable or ndarray) – State transition matrix or function F(dt) -> ndarray.
H (ndarray) – Measurement matrix.
Q (callable or ndarray) – Process noise covariance or function Q(dt) -> ndarray.
R (ndarray) – Measurement noise covariance.
gate_probability (float, optional) – Gate probability for association (default: 0.99).
confirm_hits (int, optional) – Hits needed to confirm track (default: 3).
confirm_window (int, optional) – Window for M-of-N confirmation (default: 5).
max_misses (int, optional) – Consecutive misses before deletion (default: 5).
init_covariance (ndarray, optional) – Initial covariance for new tracks. If None, uses 100*R projected to state.
Examples
>>> import numpy as np >>> # Constant velocity model >>> F = lambda dt: np.array([[1, dt, 0, 0], ... [0, 1, 0, 0], ... [0, 0, 1, dt], ... [0, 0, 0, 1]]) >>> H = np.array([[1, 0, 0, 0], ... [0, 0, 1, 0]]) >>> Q = lambda dt: 0.1 * np.eye(4) >>> R = np.eye(2) * 0.5 >>> tracker = MultiTargetTracker(4, 2, F, H, Q, R) >>> # Process measurements >>> measurements = [np.array([1, 2]), np.array([5, 6])] >>> tracks = tracker.process(measurements, dt=1.0)
- class pytcl.trackers.Track(id, state, covariance, status, hits, misses, time)[source]
Bases:
NamedTupleMulti-target track.
- state
State estimate vector.
- Type:
ndarray
- covariance
State covariance matrix.
- Type:
ndarray
- status
Track status.
- Type:
- status: TrackStatus
Alias for field number 3
- class pytcl.trackers.TrackStatus(value)[source]
Bases:
EnumTrack status enumeration.
- TENTATIVE = 'tentative'
- CONFIRMED = 'confirmed'
- DELETED = 'deleted'
- class pytcl.trackers.MHTTrackStatus(value)[source]
Bases:
EnumTrack status in MHT.
- TENTATIVE = 'tentative'
- CONFIRMED = 'confirmed'
- DELETED = 'deleted'
- class pytcl.trackers.MHTTrack(id, state, covariance, score, status, history, parent_id, scan_created, n_hits, n_misses)[source]
Bases:
NamedTupleTrack state within MHT.
- state
State estimate vector.
- Type:
ndarray
- covariance
State covariance matrix.
- Type:
ndarray
- status
Track status.
- Type:
- history
Measurement indices associated with this track branch. -1 indicates a missed detection.
- status: MHTTrackStatus
Alias for field number 4
- class pytcl.trackers.Hypothesis(id, probability, track_ids, scan_created, parent_id)[source]
Bases:
NamedTupleA global hypothesis in MHT.
A hypothesis represents a consistent assignment of measurements to tracks across multiple scans. Each hypothesis maintains a set of track branches that are mutually compatible.
- class pytcl.trackers.HypothesisAssignment(track_id, measurement_idx, likelihood)[source]
Bases:
NamedTupleA track-to-measurement assignment within a hypothesis.
- class pytcl.trackers.HypothesisTree(max_hypotheses=100, n_scan=3, min_probability=1e-06)[source]
Bases:
objectManages hypothesis tree for MHT.
The hypothesis tree represents all possible interpretations of measurement-to-track associations across multiple scans.
- Parameters:
- hypotheses
Current set of hypotheses.
- Type:
list of Hypothesis
- hypotheses: List[Hypothesis]
- pytcl.trackers.generate_joint_associations(gated, n_tracks, n_meas)[source]
Generate all valid joint measurement-to-track associations.
A valid association satisfies: - Each measurement is assigned to at most one track - Each track is assigned to at most one measurement - Only gated track-measurement pairs are considered
- Parameters:
- Returns:
associations – List of valid associations. Each dict maps track_id to meas_idx. meas_idx = -1 indicates missed detection.
- Return type:
Examples
>>> gated = np.array([[True, True], [True, True]]) >>> associations = generate_joint_associations(gated, 2, 2) >>> len(associations) # All valid 2-track, 2-measurement associations 9
- pytcl.trackers.compute_association_likelihood(association, likelihood_matrix, detection_prob, clutter_density, n_meas)[source]
Compute likelihood of a joint association.
- Parameters:
association (dict) – Mapping from track_id to measurement_idx (-1 for miss).
likelihood_matrix (ndarray) – Likelihood values, shape (n_tracks, n_meas).
detection_prob (float) – Probability of detection.
clutter_density (float) – Spatial density of clutter (false alarms).
n_meas (int) – Total number of measurements.
- Returns:
likelihood – Joint likelihood of the association.
- Return type:
Examples
>>> import numpy as np >>> # 2 tracks, 2 measurements >>> likelihood_matrix = np.array([[0.9, 0.1], ... [0.1, 0.8]]) >>> # Association: track 0 -> meas 0, track 1 -> meas 1 >>> association = {0: 0, 1: 1} >>> lik = compute_association_likelihood( ... association, likelihood_matrix, ... detection_prob=0.9, clutter_density=1e-6, n_meas=2 ... ) >>> lik > 0 True >>> # Association with missed detection >>> assoc_miss = {0: 0, 1: -1} # track 1 misses >>> lik_miss = compute_association_likelihood( ... assoc_miss, likelihood_matrix, ... detection_prob=0.9, clutter_density=1e-6, n_meas=2 ... ) >>> lik > lik_miss # Full detection more likely True
- pytcl.trackers.n_scan_prune(hypotheses, tracks, n_scan, current_scan)[source]
N-scan pruning of hypotheses.
Removes hypotheses that diverged from the most likely hypothesis more than n_scan scans ago. This implements “deferred decision” pruning where associations older than N scans are committed to.
- Parameters:
hypotheses (list of Hypothesis) – Current hypotheses.
tracks (dict) – Mapping from track_id to MHTTrack.
n_scan (int) – Number of scans to look back.
current_scan (int) – Current scan number.
- Returns:
pruned_hypotheses (list of Hypothesis) – Hypotheses surviving pruning.
committed_track_ids (set) – Track IDs that are now committed (survived N-scan).
- Return type:
Tuple[List[Hypothesis], Set[int]]
Examples
>>> import numpy as np >>> from pytcl.trackers.hypothesis import ( ... Hypothesis, MHTTrack, MHTTrackStatus, n_scan_prune ... ) >>> # Two hypotheses, tracks with different creation scans >>> track1 = MHTTrack(id=0, state=np.zeros(2), covariance=np.eye(2), ... score=1.0, status=MHTTrackStatus.CONFIRMED, ... history=[0], parent_id=-1, scan_created=0, ... n_hits=3, n_misses=0) >>> track2 = MHTTrack(id=1, state=np.zeros(2), covariance=np.eye(2), ... score=0.5, status=MHTTrackStatus.TENTATIVE, ... history=[1], parent_id=-1, scan_created=2, ... n_hits=1, n_misses=0) >>> tracks = {0: track1, 1: track2} >>> hyp1 = Hypothesis(id=0, probability=0.8, track_ids=[0], ... scan_created=0, parent_id=-1) >>> hyp2 = Hypothesis(id=1, probability=0.2, track_ids=[1], ... scan_created=2, parent_id=-1) >>> pruned, committed = n_scan_prune([hyp1, hyp2], tracks, n_scan=2, ... current_scan=3) >>> len(pruned) >= 1 True
Notes
N-scan pruning works by: 1. Finding tracks that agree across all high-probability hypotheses
at scan (current_scan - n_scan)
Removing hypotheses that disagree with the “committed” decision
- pytcl.trackers.prune_hypotheses_by_probability(hypotheses, max_hypotheses, min_probability=1e-06)[source]
Prune hypotheses by probability threshold and count limit.
- Parameters:
hypotheses (list of Hypothesis) – Current hypotheses.
max_hypotheses (int) – Maximum number of hypotheses to retain.
min_probability (float) – Minimum probability threshold.
- Returns:
pruned – Pruned and renormalized hypotheses.
- Return type:
list of Hypothesis
Examples
>>> from pytcl.trackers.hypothesis import Hypothesis, prune_hypotheses_by_probability >>> # 5 hypotheses with varying probabilities >>> hyps = [ ... Hypothesis(id=0, probability=0.5, track_ids=[0], scan_created=0, parent_id=-1), ... Hypothesis(id=1, probability=0.3, track_ids=[1], scan_created=0, parent_id=-1), ... Hypothesis(id=2, probability=0.1, track_ids=[2], scan_created=0, parent_id=-1), ... Hypothesis(id=3, probability=0.05, track_ids=[3], scan_created=0, parent_id=-1), ... Hypothesis(id=4, probability=1e-8, track_ids=[4], scan_created=0, parent_id=-1), ... ] >>> pruned = prune_hypotheses_by_probability(hyps, max_hypotheses=3) >>> len(pruned) # Only top 3 kept 3 >>> sum(h.probability for h in pruned) # Renormalized to 1 1.0
- class pytcl.trackers.MHTConfig(n_scan=3, max_hypotheses=100, detection_prob=0.9, clutter_density=1e-06, gate_probability=0.99, confirm_threshold=3, delete_threshold=5, min_hypothesis_prob=1e-06, new_track_weight=0.1)[source]
Bases:
NamedTupleConfiguration for MHT tracker.
- class pytcl.trackers.MHTResult(confirmed_tracks, tentative_tracks, all_tracks, n_hypotheses, best_hypothesis_prob)[source]
Bases:
NamedTupleResult of MHT processing step.
- class pytcl.trackers.MHTTracker(state_dim, meas_dim, F, H, Q, R, config=None, init_covariance=None)[source]
Bases:
objectMultiple Hypothesis Tracking (MHT) tracker.
Maintains multiple hypotheses about measurement-to-track associations, with N-scan pruning for complexity control.
- Parameters:
state_dim (int) – Dimension of state vector.
meas_dim (int) – Dimension of measurement vector.
F (callable or ndarray) – State transition matrix or function F(dt) -> ndarray.
H (ndarray) – Measurement matrix.
Q (callable or ndarray) – Process noise covariance or function Q(dt) -> ndarray.
R (ndarray) – Measurement noise covariance.
config (MHTConfig, optional) – Tracker configuration. Uses defaults if not provided.
init_covariance (ndarray, optional) – Initial covariance for new tracks.
Examples
>>> import numpy as np >>> # Constant velocity model >>> F = lambda dt: np.array([[1, dt, 0, 0], ... [0, 1, 0, 0], ... [0, 0, 1, dt], ... [0, 0, 0, 1]]) >>> H = np.array([[1, 0, 0, 0], ... [0, 0, 1, 0]]) >>> Q = lambda dt: 0.1 * np.eye(4) >>> R = np.eye(2) * 0.5 >>> tracker = MHTTracker(4, 2, F, H, Q, R) >>> # Process measurements >>> measurements = [np.array([1, 2]), np.array([5, 6])] >>> result = tracker.process(measurements, dt=1.0)
Single Target Tracking
Single target tracking algorithms.
Single-target tracker implementation.
This module provides a simple single-target tracker using Kalman filtering.
- class pytcl.trackers.single_target.SingleTargetTracker(state_dim, meas_dim, F, H, Q, R, gate_threshold=None)[source]
Bases:
objectSingle-target tracker using Kalman filtering.
This tracker maintains a single track and provides predict/update functionality with optional gating.
- Parameters:
state_dim (int) – Dimension of state vector.
meas_dim (int) – Dimension of measurement vector.
F (callable or ndarray) – State transition matrix or function F(dt) -> ndarray.
H (ndarray) – Measurement matrix.
Q (callable or ndarray) – Process noise covariance or function Q(dt) -> ndarray.
R (ndarray) – Measurement noise covariance.
gate_threshold (float, optional) – Chi-squared gate threshold (default: None, no gating).
Examples
>>> import numpy as np >>> # Constant velocity model in 2D >>> F = lambda dt: np.array([[1, dt, 0, 0], ... [0, 1, 0, 0], ... [0, 0, 1, dt], ... [0, 0, 0, 1]]) >>> H = np.array([[1, 0, 0, 0], ... [0, 0, 1, 0]]) >>> Q = lambda dt: 0.1 * np.eye(4) >>> R = np.eye(2) * 0.5 >>> tracker = SingleTargetTracker(4, 2, F, H, Q, R) >>> tracker.initialize(np.array([0, 1, 0, 1]), np.eye(4)) >>> tracker.predict(1.0) >>> tracker.update(np.array([1.1, 1.2]))
- initialize(state, covariance, time=0.0)[source]
Initialize the tracker with initial state.
- Parameters:
state (array_like) – Initial state estimate.
covariance (array_like) – Initial state covariance.
time (float, optional) – Initial time (default: 0).
- property state: TrackState | None
Get current track state.
- predict(dt)[source]
Predict state to new time.
- Parameters:
dt (float) – Time step.
- Returns:
Predicted state.
- Return type:
- Raises:
RuntimeError – If tracker is not initialized.
- update(measurement)[source]
Update state with measurement.
- Parameters:
measurement (array_like) – Measurement vector.
- Returns:
state (TrackState) – Updated state.
likelihood (float) – Measurement likelihood (Mahalanobis distance).
- Raises:
RuntimeError – If tracker is not initialized.
- Return type:
- class pytcl.trackers.single_target.TrackState(state, covariance, time)[source]
Bases:
NamedTupleState of a single target track.
- state
State estimate vector.
- Type:
ndarray
- covariance
State covariance matrix.
- Type:
ndarray
Multi-Target Tracking
Multi-target tracking algorithms including track management.
Multi-target tracker implementation.
This module provides a multi-target tracker using GNN data association and Kalman filtering with track management (initiation, maintenance, deletion).
- class pytcl.trackers.multi_target.MultiTargetTracker(state_dim, meas_dim, F, H, Q, R, gate_probability=0.99, confirm_hits=3, confirm_window=5, max_misses=5, init_covariance=None)[source]
Bases:
objectMulti-target tracker with GNN data association.
This tracker maintains multiple tracks and handles: - Track initiation from unassociated measurements - Track update via GNN data association - Track confirmation (M-of-N logic) - Track deletion (miss count)
- Parameters:
state_dim (int) – Dimension of state vector.
meas_dim (int) – Dimension of measurement vector.
F (callable or ndarray) – State transition matrix or function F(dt) -> ndarray.
H (ndarray) – Measurement matrix.
Q (callable or ndarray) – Process noise covariance or function Q(dt) -> ndarray.
R (ndarray) – Measurement noise covariance.
gate_probability (float, optional) – Gate probability for association (default: 0.99).
confirm_hits (int, optional) – Hits needed to confirm track (default: 3).
confirm_window (int, optional) – Window for M-of-N confirmation (default: 5).
max_misses (int, optional) – Consecutive misses before deletion (default: 5).
init_covariance (ndarray, optional) – Initial covariance for new tracks. If None, uses 100*R projected to state.
Examples
>>> import numpy as np >>> # Constant velocity model >>> F = lambda dt: np.array([[1, dt, 0, 0], ... [0, 1, 0, 0], ... [0, 0, 1, dt], ... [0, 0, 0, 1]]) >>> H = np.array([[1, 0, 0, 0], ... [0, 0, 1, 0]]) >>> Q = lambda dt: 0.1 * np.eye(4) >>> R = np.eye(2) * 0.5 >>> tracker = MultiTargetTracker(4, 2, F, H, Q, R) >>> # Process measurements >>> measurements = [np.array([1, 2]), np.array([5, 6])] >>> tracks = tracker.process(measurements, dt=1.0)
- class pytcl.trackers.multi_target.Track(id, state, covariance, status, hits, misses, time)[source]
Bases:
NamedTupleMulti-target track.
- state
State estimate vector.
- Type:
ndarray
- covariance
State covariance matrix.
- Type:
ndarray
- status
Track status.
- Type:
- status: TrackStatus
Alias for field number 3
Multiple Hypothesis Tracking (MHT)
Hypothesis-oriented MHT implementation.
Multiple Hypothesis Tracking (MHT) implementation.
MHT maintains multiple hypotheses about measurement-to-track associations, deferring hard decisions until more information is available. This allows the tracker to recover from association errors.
This implementation uses track-oriented MHT with N-scan pruning.
References
- class pytcl.trackers.mht.MHTConfig(n_scan=3, max_hypotheses=100, detection_prob=0.9, clutter_density=1e-06, gate_probability=0.99, confirm_threshold=3, delete_threshold=5, min_hypothesis_prob=1e-06, new_track_weight=0.1)[source]
Bases:
NamedTupleConfiguration for MHT tracker.
- class pytcl.trackers.mht.MHTResult(confirmed_tracks, tentative_tracks, all_tracks, n_hypotheses, best_hypothesis_prob)[source]
Bases:
NamedTupleResult of MHT processing step.
- class pytcl.trackers.mht.MHTTracker(state_dim, meas_dim, F, H, Q, R, config=None, init_covariance=None)[source]
Bases:
objectMultiple Hypothesis Tracking (MHT) tracker.
Maintains multiple hypotheses about measurement-to-track associations, with N-scan pruning for complexity control.
- Parameters:
state_dim (int) – Dimension of state vector.
meas_dim (int) – Dimension of measurement vector.
F (callable or ndarray) – State transition matrix or function F(dt) -> ndarray.
H (ndarray) – Measurement matrix.
Q (callable or ndarray) – Process noise covariance or function Q(dt) -> ndarray.
R (ndarray) – Measurement noise covariance.
config (MHTConfig, optional) – Tracker configuration. Uses defaults if not provided.
init_covariance (ndarray, optional) – Initial covariance for new tracks.
Examples
>>> import numpy as np >>> # Constant velocity model >>> F = lambda dt: np.array([[1, dt, 0, 0], ... [0, 1, 0, 0], ... [0, 0, 1, dt], ... [0, 0, 0, 1]]) >>> H = np.array([[1, 0, 0, 0], ... [0, 0, 1, 0]]) >>> Q = lambda dt: 0.1 * np.eye(4) >>> R = np.eye(2) * 0.5 >>> tracker = MHTTracker(4, 2, F, H, Q, R) >>> # Process measurements >>> measurements = [np.array([1, 2]), np.array([5, 6])] >>> result = tracker.process(measurements, dt=1.0)
Hypothesis Management
Track hypothesis creation, scoring, and pruning.
Hypothesis management for Multiple Hypothesis Tracking (MHT).
This module provides data structures and algorithms for managing hypothesis trees in track-oriented MHT implementations.
References
S. Blackman and R. Popoli, “Design and Analysis of Modern Tracking Systems,” Artech House, 1999.
D. Reid, “An Algorithm for Tracking Multiple Targets,” IEEE Trans. Automatic Control, 1979.
- class pytcl.trackers.hypothesis.MHTTrackStatus(value)[source]
Bases:
EnumTrack status in MHT.
- TENTATIVE = 'tentative'
- CONFIRMED = 'confirmed'
- DELETED = 'deleted'
- class pytcl.trackers.hypothesis.MHTTrack(id, state, covariance, score, status, history, parent_id, scan_created, n_hits, n_misses)[source]
Bases:
NamedTupleTrack state within MHT.
- state
State estimate vector.
- Type:
ndarray
- covariance
State covariance matrix.
- Type:
ndarray
- status
Track status.
- Type:
- history
Measurement indices associated with this track branch. -1 indicates a missed detection.
- status: MHTTrackStatus
Alias for field number 4
- class pytcl.trackers.hypothesis.Hypothesis(id, probability, track_ids, scan_created, parent_id)[source]
Bases:
NamedTupleA global hypothesis in MHT.
A hypothesis represents a consistent assignment of measurements to tracks across multiple scans. Each hypothesis maintains a set of track branches that are mutually compatible.
- class pytcl.trackers.hypothesis.HypothesisAssignment(track_id, measurement_idx, likelihood)[source]
Bases:
NamedTupleA track-to-measurement assignment within a hypothesis.
- pytcl.trackers.hypothesis.generate_joint_associations(gated, n_tracks, n_meas)[source]
Generate all valid joint measurement-to-track associations.
A valid association satisfies: - Each measurement is assigned to at most one track - Each track is assigned to at most one measurement - Only gated track-measurement pairs are considered
- Parameters:
- Returns:
associations – List of valid associations. Each dict maps track_id to meas_idx. meas_idx = -1 indicates missed detection.
- Return type:
Examples
>>> gated = np.array([[True, True], [True, True]]) >>> associations = generate_joint_associations(gated, 2, 2) >>> len(associations) # All valid 2-track, 2-measurement associations 9
- pytcl.trackers.hypothesis.compute_association_likelihood(association, likelihood_matrix, detection_prob, clutter_density, n_meas)[source]
Compute likelihood of a joint association.
- Parameters:
association (dict) – Mapping from track_id to measurement_idx (-1 for miss).
likelihood_matrix (ndarray) – Likelihood values, shape (n_tracks, n_meas).
detection_prob (float) – Probability of detection.
clutter_density (float) – Spatial density of clutter (false alarms).
n_meas (int) – Total number of measurements.
- Returns:
likelihood – Joint likelihood of the association.
- Return type:
Examples
>>> import numpy as np >>> # 2 tracks, 2 measurements >>> likelihood_matrix = np.array([[0.9, 0.1], ... [0.1, 0.8]]) >>> # Association: track 0 -> meas 0, track 1 -> meas 1 >>> association = {0: 0, 1: 1} >>> lik = compute_association_likelihood( ... association, likelihood_matrix, ... detection_prob=0.9, clutter_density=1e-6, n_meas=2 ... ) >>> lik > 0 True >>> # Association with missed detection >>> assoc_miss = {0: 0, 1: -1} # track 1 misses >>> lik_miss = compute_association_likelihood( ... assoc_miss, likelihood_matrix, ... detection_prob=0.9, clutter_density=1e-6, n_meas=2 ... ) >>> lik > lik_miss # Full detection more likely True
- pytcl.trackers.hypothesis.n_scan_prune(hypotheses, tracks, n_scan, current_scan)[source]
N-scan pruning of hypotheses.
Removes hypotheses that diverged from the most likely hypothesis more than n_scan scans ago. This implements “deferred decision” pruning where associations older than N scans are committed to.
- Parameters:
hypotheses (list of Hypothesis) – Current hypotheses.
tracks (dict) – Mapping from track_id to MHTTrack.
n_scan (int) – Number of scans to look back.
current_scan (int) – Current scan number.
- Returns:
pruned_hypotheses (list of Hypothesis) – Hypotheses surviving pruning.
committed_track_ids (set) – Track IDs that are now committed (survived N-scan).
- Return type:
Tuple[List[Hypothesis], Set[int]]
Examples
>>> import numpy as np >>> from pytcl.trackers.hypothesis import ( ... Hypothesis, MHTTrack, MHTTrackStatus, n_scan_prune ... ) >>> # Two hypotheses, tracks with different creation scans >>> track1 = MHTTrack(id=0, state=np.zeros(2), covariance=np.eye(2), ... score=1.0, status=MHTTrackStatus.CONFIRMED, ... history=[0], parent_id=-1, scan_created=0, ... n_hits=3, n_misses=0) >>> track2 = MHTTrack(id=1, state=np.zeros(2), covariance=np.eye(2), ... score=0.5, status=MHTTrackStatus.TENTATIVE, ... history=[1], parent_id=-1, scan_created=2, ... n_hits=1, n_misses=0) >>> tracks = {0: track1, 1: track2} >>> hyp1 = Hypothesis(id=0, probability=0.8, track_ids=[0], ... scan_created=0, parent_id=-1) >>> hyp2 = Hypothesis(id=1, probability=0.2, track_ids=[1], ... scan_created=2, parent_id=-1) >>> pruned, committed = n_scan_prune([hyp1, hyp2], tracks, n_scan=2, ... current_scan=3) >>> len(pruned) >= 1 True
Notes
N-scan pruning works by: 1. Finding tracks that agree across all high-probability hypotheses
at scan (current_scan - n_scan)
Removing hypotheses that disagree with the “committed” decision
- pytcl.trackers.hypothesis.prune_hypotheses_by_probability(hypotheses, max_hypotheses, min_probability=1e-06)[source]
Prune hypotheses by probability threshold and count limit.
- Parameters:
hypotheses (list of Hypothesis) – Current hypotheses.
max_hypotheses (int) – Maximum number of hypotheses to retain.
min_probability (float) – Minimum probability threshold.
- Returns:
pruned – Pruned and renormalized hypotheses.
- Return type:
list of Hypothesis
Examples
>>> from pytcl.trackers.hypothesis import Hypothesis, prune_hypotheses_by_probability >>> # 5 hypotheses with varying probabilities >>> hyps = [ ... Hypothesis(id=0, probability=0.5, track_ids=[0], scan_created=0, parent_id=-1), ... Hypothesis(id=1, probability=0.3, track_ids=[1], scan_created=0, parent_id=-1), ... Hypothesis(id=2, probability=0.1, track_ids=[2], scan_created=0, parent_id=-1), ... Hypothesis(id=3, probability=0.05, track_ids=[3], scan_created=0, parent_id=-1), ... Hypothesis(id=4, probability=1e-8, track_ids=[4], scan_created=0, parent_id=-1), ... ] >>> pruned = prune_hypotheses_by_probability(hyps, max_hypotheses=3) >>> len(pruned) # Only top 3 kept 3 >>> sum(h.probability for h in pruned) # Renormalized to 1 1.0
- class pytcl.trackers.hypothesis.HypothesisTree(max_hypotheses=100, n_scan=3, min_probability=1e-06)[source]
Bases:
objectManages hypothesis tree for MHT.
The hypothesis tree represents all possible interpretations of measurement-to-track associations across multiple scans.
- Parameters:
- hypotheses
Current set of hypotheses.
- Type:
list of Hypothesis
- hypotheses: List[Hypothesis]