目标跟踪中的匈牙利算法

news2024/9/24 13:14:40
  • 从数学角度来看,线性分配问题(也称为匈牙利算法或指派问题)是一个经典的优化问题,其目的是在两个集合之间找到最佳匹配,使得总成本最小。我们可以将其形式化为一个二分图的最小权匹配问题。

数学背景

假设我们有两个集合 ( A ) 和 ( B ),其中 ( A ) 有 ( m ) 个元素,( B ) 有 ( n ) 个元素。我们有一个 ( m \times n ) 的成本矩阵 ( C ),其中 ( C[i, j] ) 表示将 ( A ) 中的第 ( i ) 个元素分配给 ( B ) 中的第 ( j ) 个元素的成本。

目标是找到一个匹配 ( M ⊆ A × B ) (M \subseteq A \times B ) (MA×B),使得总成本

∑ ( i , j ) ∈ M C [ i , j ] \sum_{(i, j) \in M} C[i, j] (i,j)MC[i,j]

最小,并且每个元素最多匹配一次。

算法解释

1. 空成本矩阵的处理

如果成本矩阵为空(即没有元素),则直接返回空匹配和未匹配的索引。

if cost_matrix.size == 0:
    return np.empty((0, 2), dtype=int), tuple(range(cost_matrix.shape[0])), tuple(range(cost_matrix.shape[1]))
2. 使用 LAPJV 算法

如果选择使用 LAPJV 算法(来自 lap 库),则执行以下步骤:

_, x, y = lap.lapjv(cost_matrix, extend_cost=True, cost_limit=thresh)
  • lap.lapjv 函数返回三个数组:
    • 第一个数组(未使用)是总成本。
    • x 数组表示每个 ( A ) 中元素的匹配结果,如果未匹配则为 -1。
    • y 数组表示每个 ( B ) 中元素的匹配结果,如果未匹配则为 -1。
matches = [[ix, mx] for ix, mx in enumerate(x) if mx >= 0]
unmatched_a = np.where(x < 0)[0]
unmatched_b = np.where(y < 0)[0]
  • matches 是一个列表,包含所有有效的匹配对。
  • unmatched_aunmatched_b 分别是未匹配的 ( A ) 和 ( B ) 中的索引。
3. 使用 SciPy 的线性和分配算法

如果选择使用 SciPy 的 linear_sum_assignment 算法,则执行以下步骤:

x, y = scipy.optimize.linear_sum_assignment(cost_matrix)
  • scipy.optimize.linear_sum_assignment 返回两个数组:
    • x 表示 ( A ) 中元素的匹配索引。
    • y 表示 ( B ) 中元素的匹配索引。
matches = np.asarray([[x[i], y[i]] for i in range(len(x)) if cost_matrix[x[i], y[i]] <= thresh])
  • 这行代码筛选出所有匹配成本不超过阈值的匹配对。
if len(matches) == 0:
    unmatched_a = list(np.arange(cost_matrix.shape[0]))
    unmatched_b = list(np.arange(cost_matrix.shape[1]))
else:
    unmatched_a = list(set(np.arange(cost_matrix.shape[0])) - set(matches[:, 0]))
    unmatched_b = list(set(np.arange(cost_matrix.shape[1])) - set(matches[:, 1]))
  • 如果没有有效匹配,所有元素都未匹配。
  • 否则,计算未匹配的 ( A ) 和 ( B ) 中的索引。

线性分配问题通过最小化总成本来找到两个集合之间的最佳匹配。上述函数实现了这个过程,并提供了两种不同的算法选择(LAPJV 和 SciPy 的线性和分配算法)。通过筛选出有效的匹配对和未匹配的元素索引,函数可以有效地处理目标跟踪等应用中的匹配问题。

  • 匹配过程的计算涉及到解决一个优化问题,即找到两个集合之间的最佳匹配,使得总成本最小。这个问题可以用匈牙利算法(Hungarian Algorithm)或其他线性分配算法来解决。下面详细解释这些算法是如何计算匹配的。

1. 匈牙利算法(Hungarian Algorithm)

匈牙利算法是一个经典的解决线性分配问题的算法,具有多项式时间复杂度。它的基本思想是通过逐步修改成本矩阵,找到一个零成本的完美匹配。具体步骤如下:

1.1 构造初始零矩阵
  • 从每一行中减去该行的最小值,使得每一行至少有一个零。
  • 从每一列中减去该列的最小值,使得每一列至少有一个零。
1.2 覆盖零
  • 尽可能少地画横线和竖线覆盖所有的零。
  • 如果所需的线条数量等于行(或列)的数量,则找到最优匹配。
1.3 调整矩阵
  • 如果线条数量少于行(或列)的数量,找出未被覆盖的最小元素,将其从所有未覆盖元素中减去,并将其加到所有被两条线覆盖的元素上,重复步骤1.2。

2. LAPJV 算法

LAPJV(Jonker-Volgenant Algorithm)是匈牙利算法的一个高效变种,适用于稀疏矩阵。它通过扩展成本矩阵和使用增广路径技术来找到最优匹配。

2.1 初始化
  • 初始化标号(labels)和匹配。
  • 标号表示当前的成本调整,匹配表示当前的部分匹配。
2.2 构造增广路径
  • 从未匹配的行开始,寻找增广路径。
  • 增广路径是从未匹配的行到未匹配的列的一条路径,通过调整标号来找到更低成本的匹配。
2.3 更新匹配
  • 使用增广路径更新匹配。
  • 重复构造增广路径和更新匹配,直到找到最优匹配。

3. SciPy 的线性和分配算法

SciPy 的 linear_sum_assignment 函数实现了匈牙利算法。它通过以下步骤来计算匹配:

3.1 构造初始零矩阵
  • 从每一行中减去该行的最小值。
  • 从每一列中减去该列的最小值。
3.2 覆盖零
  • 使用最少的线条覆盖所有的零。
3.3 调整矩阵
  • 找到未覆盖的最小元素,调整矩阵。
  • 重复覆盖零和调整矩阵,直到找到最优匹配。

示例

假设我们有如下成本矩阵:

C = [ 4 1 3 2 0 5 3 2 2 ] C = \begin{bmatrix} 4 & 1 & 3 \\ 2 & 0 & 5 \\ 3 & 2 & 2 \end{bmatrix} C= 423102352

使用匈牙利算法计算匹配
  1. 构造初始零矩阵

    • 行减去最小值: [ 3 0 2 2 0 5 1 0 0 ] \begin{bmatrix} 3 & 0 & 2 \\ 2 & 0 & 5 \\ 1 & 0 & 0 \end{bmatrix} 321000250
    • 列减去最小值: [ 3 0 2 1 0 5 0 0 0 ] \begin{bmatrix} 3 & 0 & 2 \\ 1 & 0 & 5 \\ 0 & 0 & 0 \end{bmatrix} 310000250
  2. 覆盖零

    • 使用最少的线条覆盖所有的零。
  3. 调整矩阵

    • 找到未覆盖的最小元素,调整矩阵。
  4. 找到匹配

    • 通过增广路径找到最优匹配。

最终匹配结果可能是 ((0, 1), (1, 0), (2, 2)),总成本为 (1 + 2 + 2 = 5)。

  • 匹配过程的核心是通过调整成本矩阵,使得在零成本上找到一个完美匹配。匈牙利算法和 LAPJV 算法都通过不同的路径和技术来实现这一目标。SciPy 的 linear_sum_assignment
    函数实现了匈牙利算法,提供了一个高效的解决方案。

在目标跟踪问题中,目标框之间的匹配通常是通过计算每个目标框之间的相似度或距离来实现的。以下是一个常见的匹配过程,结合了匈牙利算法或其他线性分配算法来找到最佳匹配。

1. 定义成本矩阵

首先,我们需要定义一个成本矩阵 C C C,其中每个元素 C [ i , j ] C[i, j] C[i,j] 表示第 i i i 个目标框和第 j j j 个目标框之间的匹配成本。匹配成本可以基于多种度量方式,例如欧氏距离、IoU(Intersection over Union)、马氏距离等。

1.1 欧氏距离

如果目标框的位置用中心点表示,可以计算中心点之间的欧氏距离:

C [ i , j ] = ( x i − x j ) 2 + ( y i − y j ) 2 C[i, j] = \sqrt{(x_i - x_j)^2 + (y_i - y_j)^2} C[i,j]=(xixj)2+(yiyj)2

1.2 IoU(Intersection over Union)

IoU 是目标跟踪中常用的度量方式,表示两个边界框的交集与并集之比:

C [ i , j ] = 1 − IoU ( B i , B j ) C[i, j] = 1 - \text{IoU}(B_i, B_j) C[i,j]=1IoU(Bi,Bj)

其中, B i B_i Bi B j B_j Bj 分别是第 i i i个和第 j j j 个目标框。

2. 构造成本矩阵

假设我们有两个集合:上一帧的目标框集合 A A A 和当前帧的目标框集合 B B B。我们构造一个成本矩阵 C C C,其中 C [ i , j ] C[i, j] C[i,j] 表示 A A A中的第 i i i 个目标框和 B B B 中的第 j j j 个目标框之间的匹配成本。

3. 计算匹配

使用匈牙利算法或其他线性分配算法来计算最佳匹配。下面是一个使用 scipy.optimize.linear_sum_assignment 函数的示例:

import numpy as np
from scipy.optimize import linear_sum_assignment

# 假设 cost_matrix 是预先计算好的成本矩阵
cost_matrix = np.array([
    [4, 1, 3],
    [2, 0, 5],
    [3, 2, 2]
])

# 使用匈牙利算法计算最佳匹配
row_ind, col_ind = linear_sum_assignment(cost_matrix)

# row_ind 和 col_ind 分别表示最佳匹配的行索引和列索引
matches = list(zip(row_ind, col_ind))
print("匹配结果:", matches)

4. 处理未匹配的目标框

在实际应用中,可能会有一些目标框没有找到匹配。我们需要处理这些未匹配的目标框:

# 找到未匹配的目标框
unmatched_a = list(set(range(cost_matrix.shape[0])) - set(row_ind))
unmatched_b = list(set(range(cost_matrix.shape[1])) - set(col_ind))

print("未匹配的A中的目标框索引:", unmatched_a)
print("未匹配的B中的目标框索引:", unmatched_b)

5. 更新目标状态

根据匹配结果更新目标状态。例如,可以更新目标的轨迹、位置等信息。

示例总结

假设我们有以下成本矩阵:

C = [ 4 1 3 2 0 5 3 2 2 ] C = \begin{bmatrix} 4 & 1 & 3 \\ 2 & 0 & 5 \\ 3 & 2 & 2 \end{bmatrix} C= 423102352

通过 linear_sum_assignment 函数,我们可以计算出最佳匹配:

row_ind, col_ind = linear_sum_assignment(cost_matrix)
matches = list(zip(row_ind, col_ind))

匹配结果可能是 ((0, 1), (1, 0), (2, 2))。

通过定义成本矩阵并使用匈牙利算法或其他线性分配算法,我们可以在目标跟踪中找到最佳的目标框匹配。匹配过程包括计算成本矩阵、使用优化算法计算最佳匹配、处理未匹配的目标框以及更新目标状态。这些步骤可以帮助我们在视频帧之间有效地跟踪目标。

  • 目标检测中的非极大值抑制(Non-Maximum Suppression, NMS)和匈牙利算法解决的匹配问题是两个不同的概念,尽管它们都涉及到目标框的处理,但它们的应用场景和目的不同。

非极大值抑制(NMS)

NMS 是一种后处理技术,用于在目标检测中消除多余的检测框。目标检测算法通常会在同一目标上产生多个重叠的检测框,NMS 通过以下步骤来保留最好的检测框并去除冗余的框:

  1. 排序:根据检测框的置信度得分对所有检测框进行排序,从高到低。
  2. 选择最高得分框:选择得分最高的检测框,并将其加入最终的检测结果中。
  3. 移除重叠框:计算其他检测框与当前选择框的 IoU(Intersection over Union),如果 IoU 超过预设的阈值,则将这些重叠的检测框移除。
  4. 重复:重复步骤 2 和 3,直到没有剩余的检测框。

NMS 的目的是减少冗余检测框,保留最有可能的目标框。

匈牙利算法

匈牙利算法用于解决线性分配问题,目的是在两个集合之间找到最佳匹配,使得总的匹配成本最小。它通常用于目标跟踪中的目标框匹配,具体步骤如前面所述,包括构造成本矩阵、使用匈牙利算法计算最佳匹配以及处理未匹配的目标框。

NMS 和匈牙利算法的区别

  • 目的

    • NMS:用于消除冗余检测框,保留最有可能的目标框。
    • 匈牙利算法:用于在两个集合之间找到最佳匹配,使得总的匹配成本最小。
  • 应用场景

    • NMS:主要用于目标检测的后处理阶段。
    • 匈牙利算法:主要用于目标跟踪中的目标框匹配。
  • 处理方式

    • NMS:基于检测框的置信度得分和 IoU 进行排序和移除。
    • 匈牙利算法:基于成本矩阵和优化算法找到最佳匹配。

示例

假设我们在目标检测中得到了以下检测框和对应的置信度得分:

  • 框 1:得分 0.9
  • 框 2:得分 0.8
  • 框 3:得分 0.7

这些检测框有一定的重叠度。NMS 的工作流程如下:

  1. 排序:框 1、框 2、框 3。
  2. 选择最高得分框:选择框 1。
  3. 移除重叠框:计算框 1 与框 2、框 3 的 IoU,如果 IoU 超过阈值,将这些框移除。
  4. 重复:选择下一个最高得分框(框 2),重复步骤 3,直到没有剩余的检测框。

最终,NMS 将保留最有可能的目标框,减少冗余。

非极大值抑制(NMS)和匈牙利算法解决的匹配问题是不同的技术,尽管它们都涉及到目标框的处理。NMS 主要用于目标检测的后处理阶段,以消除冗余检测框,而匈牙利算法主要用于目标跟踪中的目标框匹配,以找到最佳匹配。两者在目的、应用场景和处理方式上都有显著区别。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2160433.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

R语言机器学习遥感数据处理与模型空间预测技术及实际项目案例分析

随机森林作为一种集成学习方法&#xff0c;在处理复杂数据分析任务中特别是遥感数据分析中表现出色。通过构建大量的决策树并引入随机性&#xff0c;随机森林在降低模型方差和过拟合风险方面具有显著优势。在训练过程中&#xff0c;使用Bootstrap抽样生成不同的训练集&#xff…

LeetCode 每日一题 ---- 【2207. 字符串中最多数目的子序列】

LeetCode 每日一题 ---- 【2207. 字符串中最多数目的子序列】 2207.字符串中最多数目的子序列方法&#xff1a;贪心 一次遍历 2207.字符串中最多数目的子序列 方法&#xff1a;贪心 一次遍历 从题意中可以看出来&#xff0c;对于 pattern.charAt(0) 一定是插入到最左侧是最优…

什么是SSL证书?它能保护你的网络安全!

相信大家在浏览网页时经常会看到一些网址前面有个“小锁”图标&#xff0c;它代表的网站是安全的&#xff0c;而这背后的秘密就是SSL证书。那SSL证书到底是什么&#xff1f;它有什么用呢&#xff1f; 什么是SSL证书&#xff1f; SSL证书的全称是Secure Sockets Layer证书&…

php发送邮箱教程:如何实现邮件发送功能?

php发送邮箱性能优化策略&#xff1f;怎么使用PHPMail发送邮箱&#xff1f; 无论是用户注册验证、密码重置&#xff0c;还是系统通知&#xff0c;邮件发送都是不可或缺的一部分。AokSend将详细介绍如何使用PHP实现邮件发送功能&#xff0c;帮助开发者快速掌握这一技能。 php发…

高效驱动,掌控动力:TB67H400AFNG 马达驱动器

在如今智能设备和自动化应用领域中&#xff0c;驱动器的性能直接决定了系统的可靠性与效率。东芝的TB67H400AFNG有刷直流马达驱动器凭借其卓越的性能&#xff0c;成为众多行业解决方案中的关键部件。无论是工业控制、自动化设备还是消费类电子产品&#xff0c;TB67H400AFNG都能…

一小时拿下鸿蒙应用开发者高级证书!(二)

鸿蒙应用开发者高级认证&#xff0c;是华为自家研发的硬核操作系统&#xff0c;现在它在市场上的名声也越来越响亮。你手上要是有了鸿蒙的认证小本本&#xff0c;那就等于是掌握了这行里的独门秘籍&#xff0c;找工作的时候&#xff0c;妥妥的加分项。 一个小时刷刷题&#xf…

玩机进阶教程----MTK芯片杂牌机 小品牌机型以及其他mtk设备导出分区的另外一种方法解析

在前面多期博文中都是通过工具来导出分区 制作线刷包的。今天我们以另外一种方法备份系统分区。mtk芯片较多。具体机型适合哪种方法需要自测。多种方法多条思路。遇到机型善用工具。目前一些wifi网卡 点读笔以及有些其他mtk芯片设备。通常分区都较小。可以参考教程 通过教程了…

amr文件怎么转换成mp3?这几种方法超多人在用!

amr文件怎么转换成mp3&#xff1f;AMR音频格式&#xff0c;作为音频领域的一个相对边缘角色&#xff0c;其应用范围相对狭窄&#xff0c;这背后深藏着多重内在限制&#xff0c;首要挑战在于AMR的音质瓶颈&#xff0c;它难以逃脱声音失真与杂音干扰的阴影&#xff0c;这对于追求…

通过企业微信群机器人 发送群消息

1、添加群机器人&#xff0c;复制的webhook地址 2、 public static void main(String[] args) { String reqUrl "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key6xdexxxxxxxxxxxxxxxxxxxxxxxxxxx"; String title "填…

数据结构 - 查找算法

一.查找的概念 二.顺序表查找 特点&#xff1a; 1.记录的数据可以是无序的 2.当数据量较大时&#xff0c;查找效率低&#xff0c;需要依次遍历 /*** description: 顺序表查找算法&#xff0c;从后往前查找* param - a : 要操作的数组的指针* param - k…

OpenCV_自定义线性滤波(filter2D)应用详解

OpenCV filter2D将图像与内核进行卷积&#xff0c;将任意线性滤波器应用于图像。支持就地操作。当孔径部分位于图像之外时&#xff0c;该函数根据指定的边界模式插值异常像素值。 卷积核本质上是一个固定大小的系数数组&#xff0c;数组中的某个元素被作为锚点&#xff08;一般…

安霸cv22平台移植采坑记录

主要分为3部分&#xff1a; 1.数据输入部分&#xff1a; 1.因原始测试代码只是单张测试图片&#xff08;测试格式&#xff1a;安霸平台离线转的bin文件&#xff09;&#xff0c;现在的问题是&#xff1a;如何输入数据流&#xff1f;会不会涉及到字节对齐问题&#xff0c;如何…

ROS第六梯:ROS+VSCode+C++消息发布和订阅

第一步&#xff1a;创建ROS工作空间&#xff0c;并在工作空间下创建名为srr_pkg的功能包&#xff0c;具体步骤参考第二章。 第二步&#xff1a;在src下创建publisher.cpp作为发布节点代码文件&#xff0c;创建subscriber.cpp作为订阅节点代码文件&#xff1a; 主要步骤是&#…

这几个方法轻松压缩ppt文件大小,操作起来很简单的压缩PPT方法

这几个方法轻松压缩ppt文件大小。在当今信息化迅速发展的时代&#xff0c;PPT已成为工作和学习中必不可少的工具。然而&#xff0c;随着内容的增加&#xff0c;文件体积常常变得庞大&#xff0c;影响了分享和传输的便利性。过大的文件不仅占用存储空间&#xff0c;还可能导致演…

Nat Med|机器学习+高通量筛选,发现用于治疗胶质母细胞瘤的神经活性药物|顶刊精析·24-09-23

小罗碎碎念 今日顶刊&#xff1a;Nat Med 这篇文章是2024-09-20发表在《Nature Medicine》上的一篇研究型论文&#xff0c;标题为“High-throughput identification of repurposable neuroactive drugs with potent anti-glioblastoma activity”。 先打个提前量&#xff0c;发…

Java刷题知识总结(一)

1.局部变量参与运算前是必须要初始化的&#xff0c;比如下面的代码就会编译出错&#xff0c;提示y必须要初始化。 public static void main(String[] args) {int x 1;int y;int z x y; } 2.ArrayList和Vector主要区别是什么&#xff1f; A Vector与ArrayList一样&#xf…

Win11+cuda11.7+spconv11.7搭建OpenPCdet

这里写自定义目录标题 前面詳細的教程參考&#xff1a;https://blog.csdn.net/xuegreat1/article/details/141892867 懶得寫了&#xff0c;先寫遇到的一些教程外的bug&#xff1a; 上文教程走完后運行demo.py&#xff0c;但是發現沒有裝mayavi庫&#xff0c;直接安裝報錯&#…

【STM32】PWM

一、 PWM 概述 定义 PWM&#xff08;Pulse Width Modulation&#xff09;&#xff0c; 脉冲宽度调制。 脉冲&#xff1a; 方波&#xff0c; 频率(freq) 宽度&#xff1a; 高电平的宽度&#xff0c; 占空比(duty) ​ 详细波形如下图。 用途 控制灯光的亮度&#xff08;手机/平…

ASP.NET Core8.0学习笔记(十九)——EF Core DbSet

一、DbSet概述 1.DbSet提供了通过DbContext对表进行查询操作的路径。DbSet对应的属性名称将默认映射为实体T的表名。 2.使用DbSet<T>进行查询的方法&#xff1a; (1)直接在DbContext中创建对应的DbSet<T>属性 (2)使用DbSet DbContext.Set<T>方法操作数据表。…

红外图像绝缘子识别数据集

红外图像绝缘子识别数据集&#xff0c;数据集一共919张图片&#xff0c;标注为voc格式&#xff0c;可以转yolo格式 数据集名称 红外图像绝缘子识别数据集 (Infrared Insulator Recognition Dataset, IIRD) 数据集描述 IIRD是一个专为电气工程领域设计的小规模红外图像数据集…