研究對象:MOT中的數據關聯算法,包括基於IOU的貪婪匹配、基於匈牙利和KM算法的線性偶圖匹配、基於圖論的離線數據關聯。
1 Background
目前主流的MOT框架是DBT框架,這種框架的特點就是離不開數據關聯算法,不論是對不同幀之間跟蹤軌跡的關聯還是跟蹤軌跡和觀測量的關聯, 有數據關聯才能更好的保證目標ID的連續性。
不得不說IOU Tracker和他的改進版V-IOU Tracker算是多目標跟蹤算法中的一股清流,方法特別簡單粗暴,對於檢測質量很好的場景效果比較好。首先我們交代一下IOU的度量方式:

IOU Tracker的跟蹤方式沒有跟蹤,只有數據關聯,關聯指標就是IOU,關聯算法就是一種基於IOU的貪婪匹配算法:
這里留到下一節講,作者會利用不同的貪婪方式進行IOU匹配。那么V-IOU的改進就是:由於IOU Tracker僅僅是對觀測量進行了關聯,當目標丟失或者檢測不到的時候,便無法重建軌跡,因此V-IOU加入了KCF單目標跟蹤器來彌補這一漏洞,也很粗暴。
2.2 IOU Matching基於貪婪算法的數據關聯的核心思想就是,不考慮整體最優,只考慮個體最優。這里作者設計了兩種貪婪方式,第一種Local IOU Matching,即依次為每條跟蹤軌跡分配觀測量,只要IOU滿足條件即可,流程如下:

IOU Tracker就是采用的這種局部貪心方式,這種貪心策略的特點是每次為當前跟蹤軌跡選擇與之IOU最大的觀測量。那么我們再提出一種全局的貪婪策略,即每次選擇所有關聯信息中IOU最大的匹配對,流程如下:

兩種貪婪方式的代碼如下:
def GreedyAssignment(cost, threshold = None, method = 'global'): """Using iou matching to make linear assignment Parameters ---------- cost : ndarray A NxM matrix for costs between each track_ids with dection_ids threshold: float if cost > threshold, then will not be considered method: str eg: global, local Returns ------- row_idx: List of matched tracks (<=N,) assigned tracklets' id col_idx: List of matched dets (<=M,) assigned dets' id unmatched_rows: List of unmatched tracks unassigned tracklets' id unmatched_cols: List of unmatched dets unassigned dets' id """ cost_c = np.atleast_2d(cost) sz = cost_c.shape if threshold is None: threshold = 1.0 row_idx = [] col_idx = [] if method == 'global': vector_in = list(range(sz[0])) vector_out = list(range(sz[1])) while min(len(vector_in), len(vector_out)) > 0: v = cost_c[np.ix_(vector_in, vector_out)] min_cost = np.min(v) if min_cost <= threshold: place = np.where(v == min_cost) row_idx.append(vector_in[place[0][0]]) col_idx.append(vector_out[place[1][0]]) del vector_in[place[0][0]] del vector_out[place[1][0]] else: break else: vector_in = [] vector_out = list(range(sz[1])) index = 0 while min(sz[0] - len(vector_in), len(vector_out)) > 0: if index >= sz[0]: break place = np.argmin(cost_c[np.ix_([index], vector_out)]) if cost_c[index, vector_out[place]] <= threshold: row_idx.append(index) col_idx.append(vector_out[place]) del vector_out[place] else: vector_in.append(index) index += 1 vector_in += list(range(index, sz[0])) return np.array(row_idx), np.array(col_idx), np.array(vector_in), np.array(vector_out)
可以看到跟蹤效果並不是很差,那么我們觀察二者定量的結果則為:
Local: MOTA=0.77, IDF1=0.83
Global: MOTA=0.79, IDF1=0.88
相比之下全局的貪心策略比局部的要好。
3 線性匹配
3.1 匈牙利算法和KM算法
線性分配問題也叫指派問題,通常的線性分配任務是給定N個workers和N個tasks,結合相應的N×N的代價矩陣,就能得到匹配組合。其模型如下:

上述模型有個問題,即要求workers和tasks的數量對等,然而在MOT問題中待匹配的跟蹤軌跡和檢測數量大概率不相同,而且我們經常還會設定閾值來限制匹配。
匈牙利算法是專門用來求解指派問題的算法,並且通常用於求解二分圖最大匹配的。也就是說我們需要先利用規則判斷邊是否連接,然后匹配,因此不會出現非邊節點存在匹配,只有可能出現剩余未匹配:

匈牙利算法的問題在於一旦確定邊之后就沒有相對優劣了,所以我們這里介紹帶權二分圖匹配KM,顧名思義,就是求最小代價,只不過是不對等匹配:
這里我們可以看到有一個維度的和要求是1,原因就是必須要保證有一個維度滿分配,不然就會直接不建立連接了。
3.2 實驗對比
借用scipy
工具箱實現:
inf_cost = 1e+5 def LinearAssignment(cost, threshold = None, method = 'KM'): """Using Hungarian or KM algorithm to make linear assignment Parameters ---------- cost : ndarray A NxM matrix for costs between each track_ids with dection_ids threshold: float if cost > threshold, then will not be considered method : str 'KM': weighted assignment 'Hungarian': 01 assignment Returns ------- row_idx: List of matched tracks (<=N,) assigned tracklets' id col_idx: List of matched dets (<=M,) assigned dets' id unmatched_rows: List of unmatched tracks unassigned tracklets' id unmatched_cols: List of unmatched dets unassigned dets' id min_cost: float cost of assignments """ cost_c = deepcopy(np.atleast_2d(cost)) sz = cost_c.shape if threshold is not None: cost_c = np.where(cost_c > threshold, inf_cost, cost_c) if method == 'Hungarian': t = threshold if threshold is not None else inf_cost cost_c = np.where(cost_c < t, 0, cost_c) # linear assignment row_ind, col_ind = linear_sum_assignment(cost_c) if threshold is not None: t = inf_cost - 1 if threshold == inf_cost else threshold mask = cost_c[row_ind, col_ind] <= t row_idx = row_ind[mask] col_idx = col_ind[mask] else: row_idx, col_idx = row_ind, col_ind unmatched_rows = np.array(list(set(range(sz[0])) - set(row_idx))) unmatched_cols = np.array(list(set(range(sz[1])) - set(col_idx))) min_cost = cost[row_idx, col_idx].sum() return row_idx, col_idx, np.sort(unmatched_rows), np.sort(unmatched_cols), min_cost
同樣地,為了更好地對比,我們以IOU為代價指標,分別以匈牙利算法和KM算法為數據關聯算法進行實驗,有意思的是對於MOT-04-SDP視頻而言,二者並沒有太大區別,整體效果跟Global IOU Assignment一致。
完整代碼參見:https://github.com/nightmaredimple/libmot作者:黃飄
鏈接:https://zhuanlan.zhihu.com/p/111114497
來源:知乎