目标跟踪中的匈牙利匹配,,,hungarian_match

目标跟踪中的匈牙利匹配( associate_detections_to_trackers()):
先计算相似度矩阵:sort中之计算检测框和轨迹的iou。
代价矩阵:cost_matrix就是-iou_matrix。
以下代码中,两种方式计算对应索引的匹配:
1、一一对应的话直接出结果;
2、不是一一对应的话,就用scipy的linear_sum_assignment。
理论参考:
https://zhuanlan.zhihu.com/p/459758723
https://blog.csdn.net/lzzzzzzm/article/details/122634983

以下代码中,用到的测试数据可以通过数据链接下载。

# -*- coding: utf-8 -*-
"""
Time    : 2022/5/12 19:20
Author  : cong
"""
from scipy.optimize import linear_sum_assignment
import numpy as np


def iou_batch(bb_test, bb_gt):
    """
  From SORT: Computes IOU between two bboxes in the form [x1,y1,x2,y2]
  """
    bb_gt = np.expand_dims(bb_gt, 0)
    bb_test = np.expand_dims(bb_test, 1)

    xx1 = np.maximum(bb_test[..., 0], bb_gt[..., 0])
    yy1 = np.maximum(bb_test[..., 1], bb_gt[..., 1])
    xx2 = np.minimum(bb_test[..., 2], bb_gt[..., 2])
    yy2 = np.minimum(bb_test[..., 3], bb_gt[..., 3])
    w = np.maximum(0., xx2 - xx1)
    h = np.maximum(0., yy2 - yy1)
    wh = w * h
    o = wh / ((bb_test[..., 2] - bb_test[..., 0]) * (bb_test[..., 3] - bb_test[..., 1])
              + (bb_gt[..., 2] - bb_gt[..., 0]) * (bb_gt[..., 3] - bb_gt[..., 1]) - wh)
    return o


iou_threshold = 0.3
dets = np.load('dets.npy')
tracks = np.load('trks.npy')
# 计算iou相似度矩阵
iou_matrix = iou_batch(dets, tracks)

if min(iou_matrix.shape) > 0:
    a = (iou_matrix > iou_threshold).astype(np.int32)
    # axis=1以后就是将一个矩阵的每一行向量相加,0:列相加
    # 每行的元素相加, 求出所有行的max为1,所有列max为1,
    # 如果大于0.3的位置恰好一一对应,可直接得到匹配结果,否则利用匈牙利算法进行匹配
    if a.sum(1).max() == 1 and a.sum(0).max() == 1:
        # np.where(a) 找出符合条件的元素索引
        print('*'*20)
        matched_indices = np.stack(np.where(a), axis=1) # ndarray
    else:
        x,y = linear_sum_assignment(-iou_matrix) # tuple
        matched_indices = np.array(list(zip(x, y)))

unmatched_detections = []
for d, det in enumerate(dets):
    if d not in matched_indices[:, 0]:
        unmatched_detections.append(d)
unmatched_trackers = []
for t, trk in enumerate(tracks):
    if t not in matched_indices[:, 1]:
        unmatched_trackers.append(t)

# filter out matched with low IOU
matches = []
for m in matched_indices:
    if iou_matrix[m[0], m[1]] < iou_threshold:
        unmatched_detections.append(m[0])
        unmatched_trackers.append(m[1])
    else:
        matches.append(m.reshape(1, 2))
if len(matches) == 0:
    matches = np.empty((0, 2), dtype=int)
else:
    matches = np.concatenate(matches, axis=0)




匈牙利算法(匈牙利匹配算法)是一种解决二分图最大匹配问题的算法。它的基本思想是从左侧的未匹配顶点开始,依次尝试与其右侧的顶点匹配,如果匹配成功,则继续处理下一个未匹配顶点,否则尝试为当前顶点寻找另一个可行的匹配。 以下是一份基于 MATLAB 的匈牙利算法实现代码,用于求解给定二分图的最大匹配: ```matlab function [match, maxMatch] = hungarianAlgorithm(BipartiteGraph) % BipartiteGraph: 二分图的邻接矩阵表示 % match: 匹配结果(左侧顶点对应的右侧顶点编号,未匹配则为 0) % maxMatch: 最大匹配数 n = size(BipartiteGraph, 1); % 左侧顶点数 m = size(BipartiteGraph, 2); % 右侧顶点数 match = zeros(1, n); % 匹配结果 maxMatch = 0; % 最大匹配数 for i = 1:n % 初始化标记数组 S = false(1, n); T = false(1, m); P = zeros(1, m); % 右侧顶点的前驱顶点编号 AugPath = zeros(1, n); % 增广路径 % 寻找未匹配的左侧顶点 if match(i) == 0 % 在未匹配的左侧顶点查找增广路径 if dfs(i) % 更新匹配结果 maxMatch = maxMatch + 1; j = i; while j ~= 0 match(j) = AugPath(j); j = P(AugPath(j)); end end end end % 深度优先搜索查找增广路径 function isPathFound = dfs(u) S(u) = true; for v = 1:m if BipartiteGraph(u, v) && ~T(v) T(v) = true; if P(v) == 0 || dfs(P(v)) P(v) = u; AugPath(u) = v; isPathFound = true; return end end end isPathFound = false; end end ``` 该算法的时间复杂度为 O(n^3),其 n 为图顶点的数量。在实际应用,可以通过一些优化技巧(如启发式算法、Kuhn-Munkres 算法)来提高算法的效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值