匈牙利算法是多目标追踪算法中最基础的数据关联方法。
基本思路
在追踪问题当中,我们的目标是将“当前时刻的检测目标”和“过去(上一时刻)已经存在的目标轨迹”进行一一对应。经过过去学者的研究,将这个问题转换为一个分配问题,从而可以用匈牙利算法进行求解。
数学表达
分配问题
对于 \( n \times n \) 的代价矩阵 \( C \),需要求得最小的总代价:
mini=1∑nj=1∑ncijxij
并且满足以下约束条件:
i=1∑nxij=1∀j=1,2,…,n
j=1∑nxij=1∀i=1,2,…,n
xij∈{0,1}∀i,j=1,2,…,n
cij 表示第 i 个任务由第 j 个人完成的代价
xij表示第 i 个任务是否由第 j 个人完成
匈牙利算法伪代码
输入: 检测框列表 D, 轨迹列表 T, IoU 阈值 θ
输出: 匹配列表 M
1. 构建代价矩阵:
costmatrix ← 计算检测框与轨迹之间的代价矩阵
2. 矩阵预处理:
对于每一行 i:
cost_matrix[i,:]←cost_matrix[i,:]−min(cost_matrix[i,:])
对于每一列 j:
cost_matrix[:,j]←cost_matrix[:,j]−min(cost_matrix[:,j])
3. 寻找零元素并标记:
marked_zeros← 使用最少数量的线覆盖所有零元素
4. 调整矩阵:
当覆盖线的数量不等于矩阵的行数或列数时:
调整矩阵,重新寻找零元素并标记
找到步骤 3 中未被一行覆盖的最小元素(称为 k)。从所有未覆盖的元素中减去 k,然后将 k 添加到覆盖两次的元素中。
5. 提取匹配:
M← 从标记的零元素中提取匹配对
返回结果:
返回 M
代码实现
调用库函数的实现
1 2 3
| from scipy.optimize import linear_sum_assignment cost =np.array([[4,1,3],[2,0,5],[3,2,2]]) row_ind,col_ind=linear_sum_assignment(cost)
|
SORT的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import lap import numpy as np
def linear_assignment(cost_matrix, extend_cost=True): if extend_cost:
pass row_ind, col_ind, cost = lap.lapjv(cost_matrix) return cost, row_ind, col_ind
cost_matrix = np.array([[4, 1, 3], [2, 0, 5], [3, 2, 2]])
cost, row_ind, col_ind = linear_assignment(cost_matrix)
print("最小代价:", cost) print("行分配:", row_ind) print("列分配:", col_ind)
|