SORT算法
SORT(Simple Online and Realtime Tracking)算法是一种目标追踪算法,其简单有效,基于IOU来匹配,并且融入了卡尔曼滤波和匈牙利算法来降低ID Switch(可以说,追踪算法的目标只有两个:1.提高速度 2.降低ID Switch)
Intersection over Union(IoU)分数是对象类别分割问题的标准性能度量
SORT算法的组成主要包括三大部分:目标检测,卡尔曼滤波,匈牙利算法。
目标检测
SORT的作者使用了 Faster RCNN(还是Fast来着,忘了),来完成目标检测,目标检测的这一部分是可以替换的,可以理解为目标检测网络可以替换为其他的任何模型,如YOLO,Transformer系列。
卡尔曼滤波
下图展示了三个正态分布
图中我们能非常清晰的看到,我们有预测和测量两个方法得到的状态,而上图的高斯分布,我们可以视为使用这两种方法时判定物体出现在某一区域的概率。
预测修正,也就是我们图中的黄线,通俗来讲就是代表了预测和测量的高斯分布的交集的高斯分布。
这样子做的意义在于:我们对于连续帧中运动较快的物体出现区域,能够有较为准确的预测。
预测时我们对当前帧检测框需要7个数据:检测框中心的横坐标,检测框中心的纵坐标,检测框的面积,长宽比,横坐标速度,纵坐标速度,面积速度。
匈牙利算法
在ICPC经历里,图论的二分图问题会用到匈牙利算法。
这里的匈牙利算法解决的是一个匹配问题。
我们在卡尔曼滤波中得到了基于上一帧物体数据的预测框,然后用预测框和当前帧的检测框做IOU匹配(对轨迹的均值进行处理,得到轨迹目标的框坐标,计算轨迹框和检测目标框的坐标的IOU值,1减去其值,得到损失,进行配对),通过IOU计算结果来得到代价矩阵(1-IoU)计算相似度,显然如果计算结果认为不像似ID就会switch。
DeepSORT算法
无论是什么场景的跟踪,重叠问题是无法避免的,而SORT却忽略的这个问题,常常造成IDSW值过大。
DeepSORT算法是基于SORT算法做出的改进,其引入了ReID可以利用学习外观特征来进一步降低ID Switch(实际使用时,在镜头不稳定的情况下SORT和DeepSORT的差别最为明显)。
DeepSort算法则在Sort算法的基础上添加了鉴别网络,并在流程上增加了级联匹配和轨迹预测两个步骤,其流程如图所示。
将Detection和Track进行匹配,所以出现几种情况:
1.Detection和Track匹配,也就是Matched Tracks。普通连续跟踪的目标都属于这种情况,前后两帧都有目标,能够匹配上。
2. Detection没有找到匹配的Track,也就是Unmatched Detections。图像中突然出现新的目标的时候,Detection无法在之前的Track找到匹配的目标。
3.Track没有找到匹配的Detection,也就是Unmatched Tracks。连续追踪的目标超出图像区域,Track无法与当前任意一个Detection匹配。
遮挡情况,也属于第三种情况,我们希望遮挡的目标再出现后ID尽可能不变,这时需要用到阈值和级联匹配
级联匹配
确定态的跟踪框集合我们记为T,当前目标检测出来的结果集合我们记为D
通俗描述
通俗来讲,级联分为三步
第一步:检测和预测两个结果对应的图像,放入ReID中,通过外观特征信息计算余弦距离
第二步:根据马氏距离去除不匹配项(不是删掉)
第三步:根据预测框的更新状态。
建议去下面这个文章看具体的通俗理解。
多目标跟踪(二)DeepSort——级联匹配Matching Cascade
原理
马氏距离
DeepSort将采用8维变量x来描述某时刻目标的外观信息和位置信息,如式所示。
式中()代表小麦的中心坐标,代表检测框的长宽比,代表检测框的高,而则代表了相应的速度信息。
对于运动信息,采用马氏距离来描述卡尔曼滤波预测的结果和检测结果的关联度,具体如式
式中,dj 为第j个检测框,Yi代表第i个检测框的状态向量,Si代表i条运动路径间的标准差矩阵。然后用对目标进行筛选要用到马氏距离,当某次关联时马氏距离小于阙值t(1) 则表明运动状态匹配成功,否则代表运动状态匹配失败,其函数表达如式
式中t(1) 代表相关阙值=1,代表阙值指示器.
余弦距离
当相机剧烈运动时马氏距离不能很好的对关联程度进行度量,此时会出现ID跳变导致错误计数。为了避免这类问题,将采用外观特征信息作为关联信息。对每一个检测目标dj求得一个128维的特征向量rj,并且规定限制条件‖rj‖=1为限制条件,同时对每一个小麦构建一个能预测其100帧后路径的特征向量,然后通过式(1)计算出检测的特征描述与追踪的特征描述之间的最小余弦距离,下一步将余弦距离与训练得到的相关阈值t(2)比较如式(2),如果小于阈值则代表关联成功。
公式1
公式2
式中d(i,j)代表最小余弦距离,rj代表检测框的特征向量,rk代表之后100帧里成功关联的特征向量,Ri代表目标外观特征集合,b(i,j)为外观指示器阙值。
上述最小余弦距离可以使得丢失目标重新出现后恢复其ID值
ReID特征提取网络
上面光说了,用REID,那么ReID是具体怎么搞得呢,ReID模块,用于提取表观特征,原论文中是生成了128维的embedding。
ReID在DeepSORT原文中是适用于人的,具体使用时可以替换其他泛化性更好的网络去预训练特征提取网络。
class Extractor(object):def __init__(self, model_name, model_path, use_cuda=True):self.net = build_model(name=model_name,num_classes=96)self.device = "cuda" if torch.cuda.is_available() and use_cuda else "cpu"state_dict = torch.load(model_path)['net_dict']self.net.load_state_dict(state_dict)print("Loading weights from {}... Done!".format(model_path))self.net.to(self.device)self.size = (128,128)self.norm = transforms.Compose([transforms.ToTensor(),transforms.Normalize([0.3568, 0.3141, 0.2781],[0.1752, 0.1857, 0.1879])])def _preprocess(self, im_crops):"""TODO:1. to float with scale from 0 to 12. resize to (64, 128) as Market1501 dataset did3. concatenate to a numpy array3. to torch Tensor4. normalize"""def _resize(im, size):return cv2.resize(im.astype(np.float32) / 255., size)im_batch = torch.cat([self.norm(_resize(im, self.size)).unsqueeze(0) for im in im_crops],dim=0).float()return im_batchdef __call__(self, im_crops):im_batch = self._preprocess(im_crops)with torch.no_grad():im_batch = im_batch.to(self.device)features = self.net(im_batch)return features.cpu().numpy()
下图是整个DeepSort算法的类图,来自Deep SORT多目标跟踪算法代码解析
本文主要参考了三篇论文
自己的一篇SCI
Deep SORT多目标跟踪算法代码解析 建议去这里看代码具体怎么用
多目标跟踪(二)DeepSort——级联匹配Matching Cascade这里看DeepSORT的级联匹配的通俗步骤。