KCF論文理解與源碼解析


KCF(Kernelized Correlation Filter)基於核化的 嶺迴歸分類器 使用循環移位得到的 循環矩陣 來採集正負樣本,利用循環矩陣在 傅里葉空間 可對角化的性質,將矩陣的運算轉化爲元素的點乘,從而降低了運算量,使得算法滿足實時性要求。同時, KCF使用 多通道HOG特徵 代替單通道灰度特徵,將特徵擴展到多通道的非線性特徵空間,達到了更高的魯棒性和準確性。

源碼及參考

數據集

論文中提及所用的數據集是 OTB2013 Y. Wu, J. Lim, and M. H. Yang, “Online object tracking: A benchmark,” in CVPR, 2013 共包含50個視頻序列。官方下載:Visual Tracker Benchmark

視頻列表:

videos = {'basketball', 'bolt', 'boy', 'car4', 'carDark', 'carScale', ...
	'coke', 'couple', 'crossing', 'david2', 'david3', 'david', 'deer', ...
	'dog1', 'doll', 'dudek', 'faceocc1', 'faceocc2', 'fish', 'fleetface', ...
	'football', 'football1', 'freeman1', 'freeman3', 'freeman4', 'girl', ...
	'ironman', 'jogging', 'jumping', 'lemming', 'liquor', 'matrix', ...
	'mhyang', 'motorRolling', 'mountainBike', 'shaking', 'singer1', ...
	'singer2', 'skating1', 'skiing', 'soccer', 'subway', 'suv', 'sylvester', ...
	'tiger1', 'tiger2', 'trellis', 'walking', 'walking2', 'woman'};

MATLAB 代碼測試

Quickstart:

  1. Extract code somewhere.
  2. The tracker is prepared to run on any of the 50 videos of the Visual Tracking Benchmark [3]. For that, it must know where they are/will be located. You can change the default location ‘base_path’ in ‘download_videos.m’ and run_tracker.m.
  3. If you don’t have the videos already, run download_videos.m (may take some time).
  4. Execute ‘run_tracker’ without parameters to choose a video and test the KCF on it.

注意:

  • 在國內用腳本下載數據集容易失敗,建議前往官網手動下載;
  • 代碼不兼容部分需要按提示更改,如show_video.m中第24行的Number應改爲NumberTitle等,MATLAB2018環境可直接下載調整好的代碼:MATLAB 2018 KCF源碼

測試環境:
在這裏插入圖片描述

測試結果:

>> run_tracker all gaussian hog  %Kernelized Correlation Filter (KCF)

從最後結果來看,KCF(0.742,293)要優於論文結果(0.732,172), DCF(0.730, 604)也優於論文結果(0.728, 292). 代碼相同的前提下,可能是硬件不同以及MATLAB版本升級帶來了巨大的性能提升。
在這裏插入圖片描述

MATLAB 代碼分析

只對 KCF-HOG 部分的代碼進行分析

性能評估接口:
run_tracker.m
在這裏插入圖片描述
這是並行測試50個視頻序列,最後對結果取平均。從下面的跟蹤接口代碼來看,img_files中存放圖片名稱,在tracker函數中進行讀取並跟蹤。從tic() toc()包括的代碼來看,只測量跟蹤算法消耗的時間,imread()時間不計入。

跟蹤接口代碼:

run_tracker.m
在這裏插入圖片描述
跟蹤參數:

padding = 1.5;    				// extra area surrounding the target
feature_type = 'hog';			// feature type
kernel.type = 'gaussian';   	// kernel
kernel.sigma = 0.5;				// gaussian kernel bandwidth
lambda = 1e-4;    				// regularization
output_sigma_factor = 0.1;  	// spatial bandwidth (proportional to target)
interp_factor = 0.02;			// linear interpolation factor for adaptation of model parameters
cell_size = 4;					// HOG cell size 
features.hog = true;			// enable HOG feature
features.hog_orientations = 9;	// the number of HOG bins

跟蹤代碼:
在這裏插入圖片描述
與論文中的僞代碼相差不大:
在這裏插入圖片描述
這是由以下的核心公式得出的。

KCF核心公式

  • 核相關矩陣的初始向量:
    在這裏插入圖片描述

  • 核化後的嶺迴歸分類器權值:
    在這裏插入圖片描述

  • 快速檢測:
    在這裏插入圖片描述

KCF公式推導

Step 1:KCF的基本模型是嶺迴歸分類器
在這裏插入圖片描述


Step 2:爲了 簡化閉式解的計算,消除矩陣乘法與求逆運算,以及爲了 增廣樣本,需要引入循環矩陣。
在這裏插入圖片描述
在這裏插入圖片描述
循環矩陣有着良好性質:
在這裏插入圖片描述
離散傅里葉變換簡介:
在這裏插入圖片描述


Step 3:簡化計算
在這裏插入圖片描述
在這裏插入圖片描述
注:最後結果的 diagdiag運算可以省略。


Step 4:爲了提高分類器的準確度,解決“線性不可分”問題,對嶺迴歸分類器進行 “核化”。
在這裏插入圖片描述
在這裏插入圖片描述

核空間的嶺迴歸:


Step 5:核化分類器的簡化計算
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
對閉式解進行同等化簡(對角化、傅里葉變換):
在這裏插入圖片描述
在這裏插入圖片描述


Step 6:核相關矩陣的加速計算
在這裏插入圖片描述


Step 7:快速檢測
在這裏插入圖片描述


Step 8:選用多通道HOG特徵提升準確率。對於多通道的特徵描述符,只需在傅立葉域中對對每個通道的各個點積求和即可。
在這裏插入圖片描述

HOG特徵與FHOG特徵:

C++ 代碼測試

在這裏插入圖片描述
需要修改數據集,這裏只對Coke序列進行了測試。OpenCV版本 4.x,修改後的可運行代碼和數據集已經上傳: Streamlined KCF.zip

video info:

  • img size (640, 480)
  • roi size (48, 80)
  • win size (120, 200) = roi * 2.5
  • frame count 291

在這裏插入圖片描述
相比MATLAB的測試結果(143 fps),慢了太多。根據作者GitHub所描述的,這並不是單一尺度的跟蹤,使用的特徵是FHOG+CN,因此測試基本性能需要將這些參數清零:
在這裏插入圖片描述
再次測試,速度明顯提升:
在這裏插入圖片描述
此時,C++ 版本的算法實現參數爲:單一尺度、僅使用灰度圖像的FHOG特徵、使用Gaussian核,達到平均幀率 110 fps;跟蹤效果方面僅可以抵抗小部分遮擋,完全遮擋則會出現目標丟失。

OpenCV 代碼測試

版本 4.1.2

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/tracking.hpp>

using namespace std;

int main(int argc, char* argv[])
{
    // 讀取視頻序列
    string frame_files = "../datasets/OTB2013/Coke/img/%04d.jpg";
    cv::VideoCapture cap(frame_files);
    int frame_height = int(cap.get(cv::CAP_PROP_FRAME_HEIGHT));
    int frame_width = int(cap.get(cv::CAP_PROP_FRAME_WIDTH));
    int frame_count = (int)cap.get(cv::CAP_PROP_FRAME_COUNT);
    printf("video info: (%d, %d), %d frames\n", frame_width, frame_height, frame_count);
    cv::Mat frame;
    cap >> frame;
    cv::Rect2d bbox(298, 160, 48, 80);

    // 跟蹤測試
    cv::Ptr<cv::Tracker> tracker;
    cv::TrackerKCF::Params tracker_params;
    tracker_params.detect_thresh = 0.3f;
    tracker = cv::TrackerKCF::create(tracker_params);
    tracker->init(frame, bbox);
    double total_time_s = 0.;
    for (int i = 0; i < frame_count - 1; ++i)
    {
        cap >> frame;
        double time_profile_counter = cv::getTickCount();
        tracker->update(frame, bbox);
        time_profile_counter = cv::getTickCount() - time_profile_counter;
        auto time = time_profile_counter / cv::getTickFrequency();
        total_time_s += time;
        std::cout << "  -> speed : " << 1. / time << " fps" << std::endl;
    }

    cap.release();
    std::cout << "\nAverage speed " << (frame_count - 1) / total_time_s << " fps" << std::endl;
    std::cout << "\nProcessing time: " << total_time_s << " s." << std::endl;

    return 0;
}

同樣的數據集,比着上一節的Streamlined KCF要快的多,並且高於MATLAB(143 fps) 的測試結果。此時採用的是 cv::TrackerKCF 默認參數,選擇的是壓縮後的ColorName特徵,並不是論文中設計的FHOG特徵。從跟蹤效果上看,無法應對小部分遮擋,在 OTB2013/Coke 數據集中 第10幀往後即丟失目標
在這裏插入圖片描述
關於幀率統計需要說明的是:

  • 評價tracker的性能,應該只統計跟蹤時間,圖像讀取時間是被排除的,在作者的MATLAB源碼中也是這麼計時的(上文中有提及)。
  • 如果在for/while循環外進行計時,則連帶統計了imread的耗時,結果有所不同:總耗時 2.498 s,由此可見,KCF的跟蹤性能與OpenCV的圖像讀取差不多,的確性能出衆。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章