效果:
ByteTrack在遮挡情况下ID不丢失演示
最近几天在看Bytetrack,感觉自己的学习方法有点问题,
应该先断点跑通,总体把握
然后完全理解算法代码的每一行,可以自己复现(这个就很难,看github的大佬把python转C++ 好羡慕)
所以如果学习Bytetrack,需要:
目录
Pre
匈牙利算法
卡尔曼追踪器
bytetrack思路
轨迹:不断保存某一个目标在画面中出现的位置(bbox)于一容器中
Bytetrack 无需训练,只要在数据集上训练好检测模型即可
Bytetrack只是对追踪结果作逻辑处理
现在有4个目标检测框,4个轨迹,如何将其一一配对?
匈牙利算法干的就是这件事,可以依据检测框与轨迹的IoU距离,也可以利用目标的外观信息,让检测框与轨迹配对。
源码:
BYTETracker.cpp
// 让预测后的 track 和当前帧的 detection 框做 cost_matrix,用的方式是 IOU关联
// 这里的 iou_distance 函数中 调用了track.tlbr,返回的是预测之后track坐标信息
std::vector< std::vector > dists;
int dist_size = 0, dist_size_size = 0;
dists = iou_distance(strack_pool, detections, dist_size, dist_size_size);
// 用匈牙利算法算出相匹配的 track 和 detection 的索引,以及没有被匹配到的 track 和没有匹配到的 detection 框的索引
std::vector< std::vector > matches;
std::vector u_track, u_detection;
linear_assignment(dists, dist_size, dist_size_size, match_thresh, matches, u_track, u_detection);
说明:
卡尔曼滤波有涉及公式,我不大看的懂
但是需要晓得卡尔曼的操作对象是轨迹(track),卡尔曼追踪其有两个要点:
均值(Mean):表示目标的位置信息,由bbox的中心坐标(cx,cy),宽高比r,高h,以及各自的速度变化值组成,由8维向量表示为 x = [cx, cy, r, h, vx, vy, vr, vh],各个速度值初始化为0。
协方差(Covariance):表示目标位置信息的不确定性,由8x8的对角矩阵表示,矩阵中数字越大则表明不确定性越大,可以以任意值初始化。
源码:
#pragma once
#include "dataType.h"
namespace byte_kalman
{
class ByteKalmanFilter
{
public:
static const double chi2inv95[10];
ByteKalmanFilter();
// 初始化均值状态(mean)与状态协方差(covariant)
KAL_DATA initiate(const DETECTBOX& measurement);
// 预测
void predict(KAL_MEAN& mean, KAL_COVA& covariance);
// 分布转换
KAL_HDATA project(const KAL_MEAN& mean, const KAL_COVA& covariance);
// 更新
KAL_DATA update(const KAL_MEAN& mean,
const KAL_COVA& covariance,
const DETECTBOX& measurement);
// 计算状态分布和测量 (检测框)之间的距离
Eigen::Matrix gating_distance(
const KAL_MEAN& mean,
const KAL_COVA& covariance,
const std::vector& measurements,
bool only_position = false);
private:
Eigen::Matrix _motion_mat;
Eigen::Matrix _update_mat;
float _std_weight_position;
float _std_weight_velocity;
};
}
track-by-detection目标追踪算法一般由检测器模块和数据关联模块两个模块组成。先由检测器进行检测获得目标检测框,然后数据关联模块会赋予这些检测框ID进行轨迹跟踪。
大多数关联方法只对检测分数高于阈值的检测框进行ID标识。那些检测分数低于阈值的检测框,会被简单地丢掉,这不是很合理。
如a组图1的第二个人,没有被遮挡时候,检测分数为0.8,但是其被遮挡时候,检测分数为0.1。
Bytetrack会关联每个检测框,而不是简单的丢掉低检测分数检测框。具体见下
1)每一帧率,检测器获得该帧检测框和分数,依据分数分为高分数检测框、低分数检测框,并添加进轨迹中。用卡尔曼滤波对每个轨迹的当前帧中的新位置进行预测
2)对高分数检测框和所有轨迹执行第一次关联:先计算检测框与预测轨迹框之间的 IoU 或 Re-ID 特征距离,获得相似度(代价矩阵)。然后采用匈牙利算法完成检测框与轨迹间的匹配,并保留未匹配到轨迹的检测框、未匹配到检测框的轨迹。
3)对低分数检测框和第一次关联未匹配到检测框的轨迹执行第二次关联:与第一次关联大体类似,但只使用IoU计算检测框与轨迹的相似度。因为低分数检测框通常包含严重的遮挡或运动模糊,外观特征不可靠。保留在迹第二次关联仍旧未匹配到检测框的轨,放入TLost中,存在超过30帧被删除。删除未匹配到轨迹的低分数检测框
4)将第一次关联未匹配到轨迹的高分检测框初始化为新的轨迹。每个单独帧的输出是当前帧中轨迹的边界框和ID标识
参考:
多目标跟踪MOT——对ByteTrack算法的一些理解_johnhamtom的博客-CSDN博客
ByteTrack注释详解 - 腾讯云开发者社区-腾讯云