MOT-SORT

MOT(一)-SORT

    • @[TOC](MOT(一)-SORT)
  • 简介
  • 一、基础知识介绍
      • 卡尔曼滤波
      • 匈牙利算法
  • 二、SORT基本逻辑
      • 1. 物体状态描述
      • 2. 卡尔曼预测
      • 3. 匈牙利分配
      • 4. 卡尔曼更新
  • 三. 代码解读
  • 四. 小结

简介

谈到 MOTSORTDEEP SORT 是两个知名度比较高的算法,当然这也是因为他们的效果比较好才出名的,鉴于是刚刚接触目标跟踪这块,所以就先把 SORT 的论文和源码看了下,毕竟像传统算法还是能看懂的,至于 DL 这种东西,随便看看就好,反正也是看不懂,就没有必要浪费太多时间;

一、基础知识介绍

提到 SORT,几乎所有的博文都会提及匈牙利算法和卡尔曼滤波,而且上来就是一堆公式,各种推导,我有幸看过几篇博文,但是看完还是有点懵,因为看完后还是不知道该怎么用,在这里,不推导公式,不进行计算,只根据自己的理解讲讲计算逻辑和使用方法:

卡尔曼滤波

既然提到这是个 * 滤波算法,那肯定就是进行过滤的,通俗点,就是根据某种特定的计算方式将一堆数据划分成多堆,而每一堆都会有共同的特点;而卡尔曼滤波的作用就是将期望与现实维护一个平衡,使每次的期望都是站在现状的基础上做出的决定,从天,周,直至年度,时间从短到长,逐步实现,逐步修改,从而避免期望越大,失望越大的存在。
卡尔曼滤波主要分成两个过程:预测和更新,预测是指根据现有的数据预判下一步能到达哪里,而更新则是实际到达的位置对上次预测的位置进行纠偏处理。

匈牙利算法

匈牙利算法实现的是最优分配的问题,以 IOU 的值作为权重参数,求取最佳分配。

二、SORT基本逻辑

对于可解释性算法的了解,个人认为逻辑最为重要,其次是代码和论文,可以参考,但是为了更好的了解其中的计算逻辑,还是需要借助论文和代码的,本文会简单通俗的讲解下 SORT 的逻辑,其中也会引用部分网络资源,具体步骤如下:

1. 物体状态描述

SORT 接收的输入数据是图片/视频中的物体状态,而这些状态可以由深度学习网络模型进行检测与识别,再把识别结果作为跟踪算法的输入,在这里,官网提供的物体的姿态描述为:

\alpha = [u, v, s, r, u^, v^, s^]

其中,u,v表示中心点, s,r 表示面积和长宽比, u^ , v^, s^表示下一帧的坐标;

2. 卡尔曼预测

根据 detection 的结果,卡尔曼滤波算法会对这一块进行预测,预判下一帧可能会到达的问题;

3. 匈牙利分配

根据当前帧 detection 的检测结果和卡尔曼滤波的预测测姿态计算 IOUIOU 的计算也有不同的定义喲),然后可以构成二维矩阵,将 IOU 的值作为权重参数,然后根据综合权重最小的原则实现检测框与预测框的分配功能。
经过分配后,整体数据就分为3类:
a. 满足设置的阈值条件,可实现认为正确的配对—成功追踪
b. 检测中有,但预测中没有—新增
c. 预测中有,检测中没有—出了视野
这里面有个bug:其一为对于同一个物体,若中间丢帧,可能会在跟踪计算时出错;其二位若一个物体重复在视野中出现,也会出现多技术的问题

4. 卡尔曼更新

步骤3完成了检测物的分类,根据匹配结果,更新对应索引物体的姿态。

三. 代码解读

核心算法如下:

class Sort(object):
  def __init__(self, max_age=1, min_hits=3, iou_threshold=0.3):
    """
    Sets key parameters for SORT
    """
    self.max_age = max_age
    self.min_hits = min_hits
    self.iou_threshold = iou_threshold
    self.trackers = []  
    self.frame_count = 0

  def update(self, dets=np.empty((0, 5))):
    """
    Params:
      dets - a numpy array of detections in the format [[x1,y1,x2,y2,score],[x1,y1,x2,y2,score],...]
    Requires: this method must be called once for each frame even with empty detections (use np.empty((0, 5)) for frames without detections).
    Returns the a similar array, where the last column is the object ID.

    NOTE: The number of objects returned may differ from the number of detections provided.
    """
    logging.info(dets)
    self.frame_count += 1

    # get predicted locations from existing trackers.
    trks = np.zeros((len(self.trackers), 5))
    to_del = []
    ret = []
    for t, trk in enumerate(trks):
      # logging.info(t)
      # pos the last detection [x1, y1, x2, y2]
      pos = self.trackers[t].predict()[0]
      
      trk[:] = [pos[0], pos[1], pos[2], pos[3], 0]
      if np.any(np.isnan(pos)):
        to_del.append(t)
    # logging.info(len(to_del))
    logging.info(to_del)

    # logging.info(trks)
    # the same is predeal trks generaly
    trks = np.ma.compress_rows(np.ma.masked_invalid(trks))
    # logging.info(trks)

    for t in reversed(to_del):
      self.trackers.pop(t)
    logging.info(len(self.trackers))

    # assign detections&&trackers, get un/matched relationship
    matched, unmatched_dets, unmatched_trks = associate_detections_to_trackers(dets,trks, self.iou_threshold)

    # update matched trackers with assigned detections
    # update real state
    for m in matched:
      self.trackers[m[1]].update(dets[m[0], :])

    # create and initialise new trackers for unmatched detections
    for i in unmatched_dets:
        trk = KalmanBoxTracker(dets[i,:])
        self.trackers.append(trk)
    i = len(self.trackers)
    logging.info("the number of trackers : %d", i)
    for trk in reversed(self.trackers):
        d = trk.get_state()[0]
        if (trk.time_since_update < 1) and (trk.hit_streak >= self.min_hits or self.frame_count <= self.min_hits):
          ret.append(np.concatenate((d,[trk.id+1])).reshape(1,-1)) # +1 as MOT benchmark requires positive
        i -= 1
        # remove dead tracklet
        if(trk.time_since_update > self.max_age):
          self.trackers.pop(i)
    if(len(ret)>0):
      return np.concatenate(ret)

    return np.empty((0,5))

四. 小结

SORT的基本原理是匈牙利算法和卡尔曼滤波算法,所以,他也又卡尔曼滤波算法本身的一些缺陷,比如物体运动位移小时,误差就会很大,以及出现某一帧漏检时,会出现跟踪错误的情况,但是,这个方法不矢为一个很好的模板,在其基础上进行各种优化,更好的适配应用场景。

你可能感兴趣的:(编程工具,DeepLearning,点云,算法,人工智能)