【目标跟踪】相机运动补偿

文章目录

  • 一、前言
  • 二、简介
  • 三、改进思路
    • 3.1、状态定义
    • 3.2、相机运动补偿
    • 3.3、iou和ReID融合
    • 3.4、改进总结
  • 四、相机运动补偿

一、前言

  1. 前 MOT (Multiple Object Tracking) 最有效的方法仍然是 Tracking-by-detection。
  2. 今天给大家分享一篇论文 BoT-SORT。论文地址 ,论文声称很牛*,各种屠榜,今天我们就来一探究竟。
  3. 主要是分享论文提出的改进点以及分享在自己的算法中如何去运用。

二、简介

Tracking-by-detection 成为 MOT 任务中最有效的范式。Tracking-by-detection 包含一个步骤检测步骤,然后是一个跟踪步骤。跟踪步骤通常由2个主要部分组成:

(1)运动模型和状态估计,用于预测后续帧中轨迹的边界框。卡尔曼滤波器 (KF) 是此任务的主流选择。

(2)将新帧检测与当前轨迹集相关联。对于步骤2:有2种主要的方法用于处理关联任务:

  • 目标的定位,主要是预测轨迹边界框和检测边界框之间的 IoU。(SORT)
  • 目标的外观模型和解决 Re-ID 任务。(DeepSORT)

在许多复杂的场景中,预测边界框的正确位置可能会由于相机运动而失败,这导致2个相关边界框之间的重叠率低,最终导致跟踪器性能低下。

作者通过采用传统的图像配准来估计相机运动,通过适当地校正卡尔曼滤波器来克服这个问题。这里将此称为相机运动补偿(CMC)。

三、改进思路

3.1、状态定义

x, y, w, h = box.centerX, box.centerY, box.width, box.height

(1) SORT,状态向量被选择为7元组:

在这里插入图片描述

s = w * h, r = h / w

(2) DeepSORT,状态向量被选择为8元组:

在这里插入图片描述

随着镜头移动或者物体与相机的相对运动,物体的长宽比也是会发生变化的。

(3) BoT-SORt 状态向量:

在这里插入图片描述

作者通过实验发现,直接估计边界框的宽度和高度会可以得到更好的性能。

在这里插入图片描述

蓝色框 DeepSORT 绿色框 BoT-SORT

且Q、R设置为与当前状态有关。具体设置如下图:

在这里插入图片描述

3.2、相机运动补偿

这个是我们的重点,针对这一点如何实现,包括如何在我们自己代码运用,我下一节单独拿来分析。

Tracking-by-detection严重依赖 预测框predictBox与检测框detectBox的重叠程度(如 IOU)。在自动驾驶领域中,相机是动态的,图像平面的边界框位置可能会发生显著变化。就算在相机固定的情况下,跟踪器也可能因振动或漂移引起的运动而受到影响。
在这里插入图片描述

这部分使用opencv中的全局运动估计(GMC)技术来表示背景运动。 首先提取图像关键点,再利用稀疏光流进行基于平移的局部异常点抑制的特征跟踪。然后使用 RANSAC 计算放射变换矩阵,再将预测的边界框从 k-1 帧坐标变换到其下一阵第k帧的坐标。上图表现出的效果看起来也很不错。

变换矩阵的平移部分仅影响边界框的中心位置,而另一部分影响所有状态向量和噪声矩阵。M ∈ R2×2 是包含仿射矩阵 a 的尺度和旋转部分的矩阵,并且 T 包含平移部分。 简单理解 M∈R2×2 为二维旋转矩阵,T为平移矩阵。由于我们前面状态定义为:

在这里插入图片描述

所以所有的状态都需要旋转操作,平移只需要对中心点(x,y)平移即可。如何在预测后的状态量中再旋转平移拿到最终状态量,用最终状态量进行匹配操作。
在这里插入图片描述

如果看不懂,把公式写出这样大家应该就明白了

在这里插入图片描述

关于 M 怎么求? 我下面一节会提供一个简单的思路和代码,大家可以参考下。

在经过上述式子更新过后,我们可以得到计算相机运动补偿后的目标状态与增益,此时把相应的 X,P 进行卡尔曼滤波的更新步骤。
在这里插入图片描述

3.3、iou和ReID融合

这部分是论文新提出的方法,也是可圈可点的地方。不过由于实时性太差,并不是适用实际场景,所以不是我们今天分析的重点。

为了提取 Re-ID 特征,采用了 FastReID 库中 BoT 之上的更强的 baseline——SBS(2020年提出)+ ResNeSt50 作为骨干网络。

更新外观状态:
在这里插入图片描述

由于外观特征很容易受到拥挤、遮挡和模糊目标的扰动破坏,作者仅使用高置信度的框。对于轨迹外观状态e与新检测嵌入特征 f 的关联,采用余弦相似性度量。α=0.9 是动量项。外观成本 Aa 和运动成本 Am 计算成本矩阵 C。其中权重因子 λ 通常设置为 0.98 。
在这里插入图片描述

作者开发了一种将运动和外观信息相结合的新方法,即IoU距离矩阵和余弦距离矩阵。首先,根据 IoU 的得分,低余弦相似性或遥远的候选者被拒绝。然后,使用矩阵的每个元素中的最小值作为我们的成本矩阵 C 的最终值。IoU-ReID 融合管道可以公式化如下:
在这里插入图片描述

3.4、改进总结

我们结合流程图,回顾以上三点改进:

在这里插入图片描述

  • 步骤 1 的提升并不明显。可以说步骤 1 的状态也是为了步骤 2 服务的。
  • 步骤 2 对跟踪器分数的提升较大。实际测试发现步骤 2 的提升是很大的,尤其是对突然发生抖动场景(如车子过减速带,急刹车等)。
  • 步骤 3 加入RE-ID之后速度非常慢,达不到实时检测跟踪。

四、相机运动补偿

整体思路如下:

  1. 计算图片背景特征点角点检测
  2. 上一帧与当前帧光流匹配
  3. 根据特征点计算旋转平移

之前博主有分享过一篇光流跟踪博客 【目标跟踪】光流跟踪(python、c++代码)。

那篇博客思路与这里有点像素, 不过那篇博客是对每个检测的目标框进行光流估计,而且没有考虑旋转。

我们这里是对背景进行光流估计,补偿所有的检测框。

根据论文思路,博主自己写了一个 demo。

import numpy as np
import cv2
import osimg_dir = "F:\\image_raw\\"
n_frames = len(os.listdir(img_dir))
w, h = 1920, 1080
num = 1
prev = cv2.imread(img_dir + "{}.jpg".format(num))
prev_gray = cv2.cvtColor(prev, cv2.COLOR_BGR2GRAY)
color = np.random.randint(0, 255, (20000, 3))for i in range(n_frames - 2):curr_path = img_dir + "{}.jpg".format(i + 2)curr = cv2.imread(curr_path)drawImg = curr.copy()mask = np.zeros_like(drawImg)prev_pts = cv2.goodFeaturesToTrack(prev_gray, maxCorners=200, qualityLevel=0.01, minDistance=30, blockSize=3)curr_gray = cv2.cvtColor(curr, cv2.COLOR_BGR2GRAY)curr_pts, status, err = cv2.calcOpticalFlowPyrLK(prev_gray, curr_gray, prev_pts, None)idx = np.where(status == 1)[0]prev_pts = prev_pts[idx]curr_pts = curr_pts[idx]m, _ = cv2.estimateAffinePartial2D(prev_pts, curr_pts)prev_gray = cv2.cvtColor(curr, cv2.COLOR_BGR2GRAY)for i, (new, old) in enumerate(zip(prev_pts, curr_pts)):a, b = new.ravel()c, d = old.ravel()mask = cv2.line(mask, (int(a), int(b)), (int(c), int(d)), color[i].tolist(), 2)drawImg = cv2.circle(drawImg, (int(a), int(b)), 4, color[i].tolist(), -1)showImg = cv2.add(drawImg, mask)cv2.imshow("show", showImg)cv2.waitKey(100)

代码中的 m 就是我们的旋转平移矩阵。选取特征点时尽量选择背景,不要选择动态目标,可以通过检测简单过滤。

在这里插入图片描述

有了 m 我们可以对 kalman 中的预测状态进行再修正后,进行匹配。

整体的效果非常不错,尤其是在颠簸的道路行驶时,基本碾压其他算法。
在这里插入图片描述

论文公布的效果对比图:
在这里插入图片描述


如有疑问,欢迎大家交流!

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

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

相关文章

C#学习(十二)——Linq

一、Linq Language-Integrated Query 语言集成查询 对内存中数据、关系数据和XML数据执行的查询进行检查 例如,在不使用Linq语法时,想要实现查看C盘windows文件夹下最大的前五个文件 class Program {static void Main(string[] args){//实现文件排序功能…

【力扣 51】N 皇后(回溯+剪枝+深度优先搜索)

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上,并且使皇后彼此之间不能相互攻击。 给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。 每一种…

【数据结构与算法】(3)基础数据结构 之 链表 单向链表、双向链表、循环链表详细示例讲解

目录 2.2 链表1) 概述2) 单向链表3) 单向链表(带哨兵)4) 双向链表(带哨兵)5) 环形链表(带哨兵) 2.2 链表 1) 概述 定义 在计算机科学中,链表是数据元素的线性集合,其每个元素都指…

Rust 本地文档的使用:rustup doc

Rust 是一种系统级编程语言,以其安全性、速度和内存控制能力而闻名。为了方便开发者更好地了解并利用 Rust 标准库和工具链中的功能,Rust 提供了一种内置的文档浏览方式——通过 rustup doc 命令。 安装 rustup 在查阅 Rust 文档之前,确保你…

蓝桥杯刷题--python-1

0门牌制作 - 蓝桥云课 (lanqiao.cn) import os import sys # 请在此输入您的代码 res0 for i in range (1,2021): xstr(i) resx.count(2) print(res) 0卡片 - 蓝桥云课 (lanqiao.cn) import os import sys # 请在此输入您的代码 res_10 for i in range(1,99999999999999999): r…

platfrom tree架构下实现3-Wire驱动(DS1302)

目录 概述 1 认识DS1302 1.1 DS1302 硬件电路 1.2 操作DS1302 1.3 注意要点 2 IO引脚位置 3 添加驱动节点 3.1 更新内核.dts 3.2 更新板卡.dtb 4 驱动程序实现 4.1 编写驱动程序 4.2 编写驱动程序的Makefile 4.3 安装驱动程序 5 验证驱动程序 5.1 编写测试程序…

何时以及如何选择制动电阻

制动电阻的选择是优化变频器应用的关键因素 制动电阻器在变频器中是如何工作的? 制动电阻器在 VFD 应用中的工作原理是将电机减速到驱动器设定的精确速度。它们对于电机的快速减速特别有用。制动电阻还可以将任何多余的能量馈入 VFD,以提升直流母线上的…

Electron实战(二):将Node.js和UI能力(app/BrowserWindow/dialog)等注入html

文章目录 设置webPreferences参数安装electron/remotemain进程中初始化html中使用dialog踩坑参考文档 上一篇:Electron实战(一):环境搭建/Hello World/打包exe 设置webPreferences参数 为了能够在html/js中访问Node.js提供fs等模块,需要在n…

新概念英语第二册(54)

【New words and expressions】生词和短语(14) sticky adj. 粘的 finger n. 手指 pie n. 馅饼 mix v. 混合,拌和 pastr…

踩坑实录(First Day)

2023 年一整年感觉我的进步都很小,所以自 2024 年起,我将专门开设专栏记录自己在工作期间踩过的所有坑,一来是为了有个记录,自己不会再踩,而来也是为了跟大家做一个分享,与大家进行讨论,提升自己…

力扣宝石补给

欢迎各位勇者来到力扣新手村,在开始试炼之前,请各位勇者先进行「宝石补给」。 每位勇者初始都拥有一些能量宝石, gem[i] 表示第 i 位勇者的宝石数量。现在这些勇者们进行了一系列的赠送,operations[j] [x, y] 表示在第 j 次的赠送…

QT 范例阅读:系统托盘 The System Tray Icon example

main.cpp QApplication app(argc, argv);//判断系统是否支持 系统托盘功能if (!QSystemTrayIcon::isSystemTrayAvailable()) {QMessageBox::critical(0, QObject::tr("Systray"),QObject::tr("I couldnt detect any system tray ""on this system.&qu…

利用jmeter完成简单的压力测试

Jmeter是一个非常好用的压力测试工具。Jmeter用来做轻量级的压力测试,非常合适,只需要十几分钟,就能把压力测试需要的脚本写好。 1、什么是压力测试 顾名思义:压力测试,就是 被测试的系统,在一定的访问压…

下载、安装Jenkins

进入官网 下载Jenkins https://www.jenkins.io 直接点击Download 一般是下长期支持版 因为它是java写的,你要运行它(Jenkins.war)肯定要有java环境 有两种方式去运行它,一种是下载Tomcat(是很经典的java容器或者jav…

代码随想录day16 Java版 二叉树部分

404.左叶子之和 感觉就是遍历,遇到叶子结点就累加,试了下居然过了 class Solution {int sum 0;public int sumOfLeftLeaves(TreeNode root) {add(root);return sum;}void add(TreeNode root){if (root null) return;if (root.left ! null &&…

linux编译ffmpeg动态库

1,获取源码:git clone https://git.ffmpeg.org/ffmpeg.git 2,创建编译目录,并编译、安装, cd ffmpeg mkdir build cd build ../configure --prefix~/ffmpeg --enable-shared --enable-debug1 //configure后需要使…

深入探索C++ Move语义:现代编程中的性能革命

1. 引言 介绍C中的Move语义 Move语义是C11中引入的一个重要特性,它为C编程语言带来了显著的性能改进。在这之前,C只支持拷贝语义,即通过拷贝构造函数和拷贝赋值操作符来复制对象。Move语义通过允许"移动"而非"拷贝"资源…

Git版本管理工具(基础):这一篇基本能满足Git基本的使用需求了!

文章目录 Git01-什么是Git作用 02-使用Git03-Git仓库创建 04-Git的三个区域三个区域 05-Git文件状态06-Git暂存区使用07-Git回退版本08-删除文件 Git 01-什么是Git 答:他是一个免费开源的,分布式代码版本控制系统,帮助开发团队维护代码 作用…

三、消除分心的事物(Eliminating Distractions)

External Improvements 外部改进 1.Eliminating Distractions 一、消除分心的事物 Distractions are the most obvious problem when it comes to focus, and they are often the easiest to fix. In particular, you want to find an environment for focus that minimizes b…

爬虫工作量由小到大的思维转变---<第四十五章 Scrapyd 关于gerapy遇到问题>

前言: 本章主要是解决一些gerapy遇到的问题,会持续更新这篇! 正文: 问题1: 1400 - build.py - gerapy.server.core.build - 78 - build - error occurred (1, [E:\\项目文件名\\venv\\Scripts\\python.exe, setup.py, clean, -a, bdist_uberegg, -d, C:\\Users\\Administrat…