1. 程式人生 > >目標追蹤(Object Tracking)概念的簡要介紹

目標追蹤(Object Tracking)概念的簡要介紹

現在我們有一個視訊流,可以拆解出 N 個幀出來,這時候初始幀/某一幀中出現了一個我們感興趣目標,我們希望在後續幀中對這個目標進行追蹤,這時候就需要 CV 中的目標追蹤;

目標追蹤的效果如下:

 

雖然效果看起來和實時人臉檢測識別效果一樣,但是其實只對初始幀進行了人臉檢測和識別,後續幀只需要進行檢測,不需要再進行識別;

 

Q: 那麼問題來了,為什麼不直接對每一幀進行檢測+識別?

A: 因為識別所佔用的資源要遠遠大於檢測;可以看到下圖中,左邊進行實時的檢測+識別,在無 GPU,CPU=i7-8700K 的情況下,FPS 只有 1.8;

而右圖中如果換成目標追蹤的方法(只對初始幀做識別,後續幀只做跟蹤),FPS 可以達到了 28,獲得了差不多 15 倍的提升;

    

左圖:檢測 + 識別,https://github.com/coneypo/Dlib_face_recognition_from_camera/blob/master/face_descriptor_from_camera.py

右圖:檢測 + OT,https://github.com/coneypo/Dlib_face_recognition_from_camera/blob/master/face_reco_from_camera_ot_single_person.py

 

為了實現目標追蹤,我們按照以下步驟進行:

  1. 對於初始幀(視訊流中的第一幀),輸入/通過檢測演算法,得到一系列目標的位置座標;
  2. 為這些 ROI 建立 ID;
  3. 在視訊流中的後續幀,尋找幀之間目標物件的關係,將幀之間的目標關聯起來;

 

目標跟蹤可以讓我們對於每一個追蹤的目標指定一個唯一的 ID,所以讓我們可以對視訊中的跟蹤物體進行計數,應用於計算人數的場景;

 

一個理想化的目標追蹤演算法能夠實現:

  1. 只需要初始化的時候進行目標檢測;
  2. 處理速度能夠很快;
  3. 可以處理被跟蹤目標,消失或者超過邊界的情況;
  4. 可以處理幀之間目標消失,然後再出現的特殊情況;

 

上圖 gif 中只有一個目標,所以其實後續幀中的檢測出來的目標,如果還是一個,肯定就是我們第一幀中識別出來的 person_X;

但是往往是一幀中出現多目標,我們就需要對於前後幀中的多目標進行比對匹配;

以下圖為例,比如左邊是第 N 幀 ,有兩個目標,我們檢測識別出來是 ID#1 和 ID#2,在 N+1 幀中,也檢查出來兩個目標,我們知道這兩個目標就是 ID#1 和 ID#2,但是不知道到底哪個是 ID#1 哪個是 ID#2;

 

所以就需要 質心追蹤演算法(Centroid Tracking)來進行判定後續幀中的 ID:

 

 

質心追蹤演算法(Centroid Tracking),依賴於在視訊流的連續幀中,比較已知目標和新出現目標之間質心的歐氏距離;

整體的處理邏輯流程如下,希望能夠只在第一幀/初始幀進行檢測識別,並試圖將第 N+1 幀中的目標,與第 N 幀的目標關聯起來,這樣對於後續幀,不再需要進行識別,只需要進行檢測就可以得到目標的 ID 了;

  • 第 N 幀:目標檢測,目標識別
  • 第 N+1 幀:目標檢測,目標追蹤
  • 第 N+2 幀:目標檢測,目標追蹤
  • 第 N+2 幀:目標檢測,目標追蹤
  • ...

 

 

 

步驟一:對於某幀取特徵框並計算質心

 

對於視訊流,通過檢測演算法對於每幀影象進行檢測;

比如上圖中有兩個特徵框 / 或者我們假定兩個特徵框給它,分別為 ID #1 和 ID #2,可以計算出兩個特徵框的質心,分別得到位置座標 (x,y);

以實際視訊流為例:

 

 

步驟二:計算新舊目標特徵框質心的歐氏距離

對於視訊流中的後續幀,我們利用檢測演算法來計算特徵框,但是我們不會再去給對於每一個檢測到的物體新增新的 ID 或者標記什麼的(只做檢測,不做識別),而是希望將新的目標能夠和舊目標聯絡起來;

我們通過計算每對新舊目標的歐式距離來得到這些目標之間的關係;

如下圖所示,比如幀 N 時候有兩個目標(綠色),幀 N+1 時候有三個目標(紅色),所以對於我們希望知道,這兩個舊目標(綠色),在後續幀中變成了哪一個新目標(紅色);

所以我們想知道如下質心之間的關係:

  • 綠1->紅1,綠1->紅2,綠1->紅3;
  • 綠2->紅1,綠2->紅2,綠2->紅3;

 

步驟三:更新已知目標的質心座標

質心追蹤演算法的前提是:對於一個給定目標,將會在後續幀中都出現,而且在第 N 幀和 N+1 幀中的質心歐氏距離,要小於不同目標之間的歐式距離;

因此我們在視訊流的連續幀之間,根據歐氏距離最小原則,將這些幀中特徵框的質心聯絡起來,可以得到一個目標 X 在這些連續幀中的變化聯絡,就達到了我們目標追蹤的目的;

 

步驟四:註冊新目標

有時候會有新目標的加入,比如幀 N 的時候有 x 個目標,而幀 N+1 的時候有 x+1 個目標,增加了一個目標;

所以對於這個新增的目標,我們按照以下順序進行註冊:

  1. 給這個新目標一個目標 ID;
  2. 儲存這個目標特徵框的質心位置;

 

然後從步驟二開始,對於視訊流中的每一幀進行計算歐氏距離,更新座標等步驟;

 

步驟五:登出舊目標

一個目標在後續幀中可能會消失,我們的目標追蹤演算法也要能夠處理這種情況;

但是對於消失目標的處理方法,要根據於你實際部署應用的場景;

  • 第 N 幀丟失目標,登出舊目標
  • 第 N 幀丟失目標,而且第 N 幀中的後續 n 幀中都沒有找回來,那就登出舊目標

因為每次重新註冊的成本(進行檢測/識別)的成本要大於歐氏距離比對進行目標追蹤的成本;

 

這篇介紹 OT 的理論部分,接下來會介紹如何用 Python + OpenCV 去實現 OT;

 

# 請尊重他人勞動成果,轉載或者使用原始碼請註明出處:http://www.cnblogs.com/AdaminXie

# 歡迎關注我的 Github:https://github.com/coneypo/

# 如有問題請留言或者聯絡郵箱: coneypo@foxmail