-
Notifications
You must be signed in to change notification settings - Fork 7
Description
Bug
hungarian_matching() in sleap_nn/tracking/utils.py crashes with ValueError: cost matrix is infeasible when the cost matrix passed to scipy.optimize.linear_sum_assignment() contains only inf values.
How to reproduce
Run tracking with --track_matching_method hungarian on data where some frames produce all-NaN scores (e.g., when no candidates pass the min_match_points filter or when keypoints contain NaN values):
sleap-nn track \
-i predictions.slp \
-o tracked.slp \
--tracking \
--track_matching_method hungarian \
--scoring_method euclidean_dist \
--features keypoints \
--candidates_method local_queues \
--max_tracks 2Root cause
In tracker.py, scores_to_cost_matrix() converts NaN scores to inf costs:
def scores_to_cost_matrix(self, scores: np.ndarray):
cost_matrix = -scores
cost_matrix[np.isnan(cost_matrix)] = np.inf # NaN → inf
return cost_matrixWhen all scores for a frame are NaN (e.g., empty scores_trackid list → np.nanmean([]) returns NaN), the entire cost matrix becomes inf, which linear_sum_assignment() considers infeasible.
greedy_matching() does not have this problem because np.argsort() silently handles inf values by sorting them to the end.
The current hungarian_matching() has no such handling:
def hungarian_matching(cost_matrix: np.ndarray):
row_ids, col_ids = linear_sum_assignment(cost_matrix) # fails on all-inf matrix
return row_ids, col_idsSuggested fix
Replace inf/nan values with a large finite number before calling linear_sum_assignment:
def hungarian_matching(cost_matrix: np.ndarray):
cost_matrix = np.copy(cost_matrix)
bad = ~np.isfinite(cost_matrix)
if bad.any():
finite_vals = cost_matrix[~bad]
fill = (np.abs(finite_vals).max() * 10 + 1) if finite_vals.size > 0 else 1e6
cost_matrix[bad] = fill
row_ids, col_ids = linear_sum_assignment(cost_matrix)
return row_ids, col_idsThis makes the assignment feasible while still strongly penalizing unmatched pairs, preserving the intended behavior.
Environment
- sleap-nn 0.1.0 (installed from source,
mainbranch) - scipy 1.17.1
- Python 3.12