多目標跟蹤-DeepSort分析(二)HungarianOper模塊代碼分析

HungarianOper

https://blog.csdn.net/qq_25945437/article/details/70835157
https://blog.csdn.net/Kerrwy/article/details/81018202

在得到了上一幀的多個Bbox與這一幀的多個Bbox的IOU矩陣,需要找到最大IOU組合的索引對,論文使用匈牙利算法來進行匹配。在class HungarianOper—匈牙利指派模塊中,核心功能

static Eigen::Matrix<float, -1, 2> Solve(const DYNAMICM &cost_matrix) 

是通過調用class Munkres 這個類來實現的(Ubuntu下輸入法有問題了,有時候是繁體字。。。)。Munkres算法是帶權重的一種指派算法。

Munkres算法流程如下:
1
前提:要求傳進來的矩陣m是方陣,即行和列相等。if 行數!=列數,就resize 。

void solve(Matrix<Data> &m)
this->matrix = m;
if (rows != columns)
    {
      matrix.resize(size, size, matrix.mmax());
    }

而且,如果存在無窮大的值,替換成矩陣的最大值。

replace_infinites(matrix);

以上是準備工作,下面進入munkres指派流程(請結合流程圖和我的筆記看,同樣沒有學會在csdn畫矩陣劃線,所以就直接貼圖了):
王大寶
王大寶
首先,對行進行規約,具體做法爲,在每行中找出最小值,然後每行都減掉這個最小值。
第二,進行列規約,前提是經過行規約後,該列的最小值不等於0,具體做法同行規約。
尋找最小值及規約代碼如下:

 for (size_t j = 1; j < inner_size && min > 0; j++)
  {
        min = XYZMIN(min,over_columns ? matrix(j, i) : matrix(i, j));
  }

if (min > 0)
{
 for (size_t j = 0; j < inner_size; j++)
  {
     if (over_columns)
     {
       matrix(j, i) -= min;
     }
    else
     {
        matrix(i, j) -= min;
     }
  }

第三,進行試指派。

首先,畫蓋零線,通俗的理解爲:用最少的橫線來覆蓋矩陣中所有被標記爲0的元素.

在矩陣中,找到沒有被蓋零線覆蓋的值.

 inline bool find_uncovered_in_matrix();
    if (find_uncovered_in_matrix(0, saverow, savecol))
    {
      mask_matrix(saverow, savecol) = PRIME; // prime it.
    }

判定蓋零線的數量covercount是否==矩陣的rows ||==矩陣的cols。如果等於,則指派成功.(這裏,可以理解爲:判定i行i列是否只有一個0元素,如果是,則說明指派成功.)
否則進行下一步:調整

主0搜索

 if (find_uncovered_in_matrix(0, saverow, savecol))
    {
    // 把它標記爲prime
      mask_matrix(saverow, savecol) = PRIME; 
    }

Increment Set of Starred Zeros

  1. Construct the ``alternating sequence’’ of primed and starred zeros:
    僞代碼:

        Z0 : Unpaired Z' from Step 4.2
        Z1 : The Z* in the column of Z0
        Z[2N] : The Z' in the row of Z[2N-1], if such a zero exists
        Z[2N+1] : The Z* in the column of Z[2N]
        The sequence eventually terminates with an unpaired Z' = Z[2N] for some N.
    
  2. Unstar each starred zero of the sequence.
    if (mask_matrix(i->first, i->second) == STAR) mask_matrix(i->first, i->second) = NORMAL;

3.Star each primed zero of the sequence

if (mask_matrix(i->first, i->second) == PRIME)
        mask_matrix(i->first, i->second) = STAR;
  1. Erase all primes, uncover all columns and rows,
for (size_t row = 0; row < mask_matrix.rows(); row++)
    {
      for (size_t col = 0; col < mask_matrix.columns(); col++)
      {
        if (mask_matrix(row, col) == PRIME)
        {
          mask_matrix(row, col) = NORMAL;
        }
      }
    }

最後返回結果,類型爲matrix矩陣.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章