deepsort算法的原理及代碼解析


概述

前邊我們講了sort算法的原理,並且指出了它的不足--IDsw過大,為了解決該問題,17年時候sort算法的團隊又提出了DeepSort算法。Deepsort在原來Sort算法的基礎上,改進了以下內容:

  1. 使用級聯匹配算法:針對每一個檢測器都會分配一個跟蹤器,每個跟蹤器會設定一個time_since_update參數。
  2. 添加馬氏距離與余弦距離:實際上是針對運動信息與外觀信息的計算。
  3. 添加深度學習特征:這一部分也就是ReID的模塊,也是deepsort的亮點之一。

代碼流程

由於deepsort的流程和算法原理幾乎和sort一樣,只是說增加了上邊三個特色,因此我們直接從代碼開始講起:

整體流程圖

算法的整體流程圖如下所示:

2020-07-13_161051

源碼流程

image-20200715113558645

首先我們從主函數部分開始說起,主函數部分整體邏輯是比較簡單的,首先是將命令行參數進行解析,解析的內容包括,MOTChanlleng序列文件所在路徑、需要檢測文件所在的目錄等一系列參數。解析之后傳遞給run方法,開始運行。

image-20200715113707665

進入run函數之后,首先會收集流信息,包括圖片名稱,檢測結果以及置信度等,后續會將這些流信息傳入到檢測框生成函數中,生成檢測框列表。然后會初始化metric對象,metric對象簡單來說就是度量方式,在這個地方我們可以選擇兩種相似度的度量方式,第一種叫做余弦相似度度量,另一種叫做歐拉相似度度量。通過metric對象我們來初始化追蹤器。

image-20200715113756738

接着根據display參數開始生成對應的visuializer,如果選擇將檢測結果進行可視化展示,那么便會生成Visualization對象,我從這個類中可以看到,它主要是調用opencv image viewer來講追蹤的結果進行展示。如果display是false則會生成一個NoVisualization對象,它一個虛擬可視化對象,它以給定的順序循環遍歷所有幀以更新跟蹤器,而無需執行任何可視化。兩者主要區別其實就是是否調用opencv將圖片展示出來。其實前邊我們所做的一系列工作可以說都是准備的工作,實際上核心部分就是在執行這個run方法之后。此處我們可以看到,在run方法中傳入了一個frame_callback函數,這個frame_callback函數可以說是整個算法的核心部分,每一幀的圖片都會執行該函數。

為什么這樣說那?

首先進入run函數之后我們會發現,無論當時選擇是可視化操作還是非可視化操作,它的run函數最終都要調用frame_callback函數的,比如說Visualization中的run方法,它首先判斷幀序號是否大於最大幀,如果大於最大幀,直接返回。否則回調執行frame_callback函數;同樣的如果是NoVisualization對象,它的run方法也是類似的,也是調用frame_callback函數,然后幀序號加1。最后上邊追蹤結果處理完之后,然后將追蹤的結果保存到對應的目錄下邊。

image-20200715114107385

上邊我們說了frame_callback函數實際上是整個函數的核心內容。進入frame_callback函數,我們可以看到,它第一步是根據之前的參數,生成檢測框列表,然后將置信度小於最小置信度閾值的檢測框剔除掉。

image-20200715114146972

然后執行非極大值抑制。

什么叫做非極大值抑制那?

簡單來說就是就是一個尋找局部最大值的過程,我們以下邊檢測框為例,我們可以看到在檢測人臉的過程中可能會產生多個檢測框,通過非極大值抑制,可以在局部范圍內選擇出那個得分最高的檢測框,剔除掉其他得分低的檢測框。

image-20200715114206754

接着調用predict函數執行預測操作,進入predict函數,我們可以看到,它其實主要就是對軌跡列表中所有的軌跡使用卡爾曼濾波算法進行狀態的預測。接着調用update函數執行更新操作。在update函數中,主要如下幾件事:

  1. 根據之前預測的結果,進行匹配操作。在該開始匹配的時候都處於不確定態,然后若干次匹配之后,如果匹配成功的次數大於n_init的話,軌跡便會從初始態轉換成確定態。如果一直沒有匹配到檢測框則會直接進入刪除態。由於追蹤的目標體可能會消失,因此就算進入到了確定態,如果在后續的匹配中多次沒有匹配到,大於max_age的時候軌跡便會從確定態轉換成刪除態。一旦軌跡進入到刪除態,則證明這個軌跡失效,后續便會被刪除。

  2. 針對不同狀態進行不同的操作

    a) 對未匹配的tracker,調用mark_missed標記,后續會刪除對應的軌跡

    b) 針對未匹配的detection(檢測框)。沒有匹配到目標,因此檢測框失配,進行初始化操作

    c) 更新軌跡列表,得到最新的tracks

    d) 更新處於確定態的trac_id

    e) 最后對特征集更新。

執行到此處當前幀的處理就完成了,直接幀序號加1,繼續進行下一幀的操作。

結論

最后我們將代碼整體原理整理成樹圖如下:

了便於大家閱讀源碼,我將源碼的具體邏輯也整理成了一個樹圖:

deep_sort_app


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM