據我目前瞭解掌握,多目標跟蹤大概有兩種方式:算法
Option1函數
基於初始化幀的跟蹤,在視頻第一幀中選擇你的目標,以後交給跟蹤算法去實現目標的跟蹤。這種方式基本上只能跟蹤你第一幀選中的目標,若是後續幀中出現了新的物體目標,算法是跟蹤不到的。這種方式的優勢是速度相對較快。缺點很明顯,不能跟蹤新出現的目標。spa
Option2視頻
基於目標檢測的跟蹤,在視頻每幀中先檢測出來全部感興趣的目標物體,而後將其與前一幀中檢測出來的目標進行關聯來實現跟蹤的效果。這種方式的優勢是能夠在整個視頻中跟蹤隨時出現的新目標,固然這種方式要求你前提得有一個好的「目標檢測」算法。blog
本文主要講述Option2的實現原理,也就是Tracking By Detecting的跟蹤方式。這篇文章沒有源碼連接,關於「目標檢測」算法的源碼能夠參見我上一篇文章,至於「軌跡跟蹤」算法的源碼實現很簡單,看完本文相信你們都能寫出來,Python實現大概200行不到。源碼
Tracking By Detecting的跟蹤過程io
Step1:使用目標檢測算法將每幀中感興趣的目標檢測出來,獲得對應的(位置座標, 分類, 可信度),假設檢測到的目標數量爲M;原理
Step2:經過某種方式將Step1中的檢測結果與上一幀中的檢測目標(假設上一幀檢測目標數量爲N)一一關聯起來。換句話說,就是在M*N個Pair中找出最像似的Pair。numpy
對於Step2中的「某種方式」,其實有多種方式能夠實現目標的關聯,好比常見的計算兩幀中兩個目標之間的歐幾里得距離(平面兩點之間的直線距離),距離最短就認爲是同一個目標,而後經過匈牙利算法找出最匹配的Pair。當讓,你還能夠加上其餘的判斷條件,好比我用到的IOU,計算兩個目標Box(位置大小方框)的交併比,該值越接近1就表明是同一個目標。還有其餘的好比判斷兩個目標的外觀是否類似,這就須要用到一種外觀模型去作比較了,可能耗時更長。方法
在關聯的過程當中,會出現三種狀況:
1)在上一幀中的N個目標中找到了本次檢測到的目標,說明正常跟蹤到了;
2)在上一幀中的N個目標中沒有找到本次檢測到的目標,說明這個目標是這一幀中新出現的,因此咱們須要把它記錄下來,用於下下一次的跟蹤關聯;
3)在上一幀中存在某個目標,這一幀中並無與之關聯的目標,那麼說明該目標可能從視野中消失了,咱們須要將其移除。(注意這裏的可能,由於有可能因爲檢測偏差,在這一幀中該目標並無被檢測到)
存在的問題
上面提到的跟蹤方法在正常狀況下都可以很好的工做,可是若是視頻中目標運動得很快,先後兩幀中同一個目標運動的距離很遠,那麼這種跟蹤方式就會出現問題。
如上圖,實線框表示目標在第一幀的位置,虛線框表示目標在第二幀的位置。當目標運行速度比較慢的時候,經過以前的跟蹤方式能夠很準確的關聯(A, A’)和(B, B’)。可是當目標運行速度很快(或者隔幀檢測)時,在第二幀中,A就會運動到第一幀中B的位置,而B則運動到其餘位置。這個時候使用上面的關聯方法就會獲得錯誤的結果。
那麼怎樣才能更加準確地進行跟蹤呢?
基於軌跡預測的跟蹤方式
既然經過第二幀的位置與第一幀的位置進行對比關聯會出現偏差,那麼咱們能夠想辦法在對比以前,先預測目標的下一幀會出現的位置,而後與該預測的位置來進行對比關聯。這樣的話,只要預測足夠精確,那麼幾乎不會出現前面提到的因爲速度太快而存在的偏差。
如上圖,咱們在對比關聯以前,先預測出A和B在下一幀中的位置,而後再使用實際的檢測位置與預測的位置進行對比關聯,能夠完美地解決上面提到的問題。理論上,無論目標速度多麼快,都能關聯上。那麼問題來了,怎麼預測目標在下一幀的位置?
方法有不少,可使用卡爾曼濾波來根據目標前面幾幀的軌跡來預測它下一幀的位置,還可使用本身擬合出來的函數來預測下一幀的位置。實際過程當中,我是使用擬合函數來預測目標在下一幀中的位置。
如上圖,經過前面6幀的位置,我能夠擬合出來一條(T->XY)的曲線(注意不是圖中的直線),而後預測目標在T+1幀的位置。具體實現很簡單,Python中的numpy庫中有相似功能的方法。
仍然存在的不足
即便如此完美了,仍是存在不足。
軌跡預測的前提是須要知道目標前面若干幀的軌跡信息,所以在剛開始,目標的軌跡是預測不到的,或者說預測得不許。因此在剛開始的幾幀,咱們仍是須要使用原來的方式進行對比關聯。