TLD(Tracking-Learning-Detection)学习与源码理解之(五)
生活随笔
收集整理的這篇文章主要介紹了
TLD(Tracking-Learning-Detection)学习与源码理解之(五)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
TLD(Tracking-Learning-Detection)學習與源碼理解之(五)??
zouxy09@qq.com
http://blog.csdn.net/zouxy09
????
?????? 下面是自己在看論文和這些大牛的分析過程中,對代碼進行了一些理解,但是由于自己接觸圖像處理和機器視覺沒多久,另外由于自己編程能力比較弱,所以分析過程可能會有不少的錯誤,希望各位不吝指正。而且,因為編程很多地方不懂,所以注釋得非常亂,還海涵。
LKTracker.h
#include<tld_utils.h> #include <opencv2/opencv.hpp>//使用金字塔LK光流法跟蹤,所以類的成員變量很多都是OpenCV中calcOpticalFlowPyrLK()函數的參數 class LKTracker{ private:std::vector<cv::Point2f> pointsFB;cv::Size window_size; //每個金字塔層的搜索窗口尺寸int level; //最大的金字塔層數std::vector<uchar> status; //數組。如果對應特征的光流被發現,數組中的每一個元素都被設置為 1, 否則設置為 0std::vector<uchar> FB_status; std::vector<float> similarity; //相似度std::vector<float> FB_error; //Forward-Backward error方法,求FB_error的結果與原始位置的歐式距離//做比較,把距離過大的跟蹤結果舍棄float simmed;float fbmed;//TermCriteria模板類,取代了之前的CvTermCriteria,這個類是作為迭代算法的終止條件的//該類變量需要3個參數,一個是類型,第二個參數為迭代的最大次數,最后一個是特定的閾值。//指定在每個金字塔層,為某點尋找光流的迭代過程的終止條件。cv::TermCriteria term_criteria;float lambda; //某閾值??Lagrangian 乘子// NCC 歸一化交叉相關,FB error與NCC結合,使跟蹤更穩定 交叉相關的圖像匹配算法??//交叉相關法的作用是進行云團移動的短時預測。選取連續兩個時次的GMS-5衛星云圖,將云圖區域劃分為32×32像素//的圖像子集,采用交叉相關法計算獲取兩幅云圖的最佳匹配區域,根據前后云圖匹配區域的位置和時間間隔,確//定出每個圖像子集的移動矢量(速度和方向),并對圖像子集的移動矢量進行客觀分析,其后,基于檢驗后的云//圖移動矢量集,利用后向軌跡方法對云圖作短時外推預測。void normCrossCorrelation(const cv::Mat& img1, const cv::Mat& img2, std::vector<cv::Point2f>& points1, std::vector<cv::Point2f>& points2);bool filterPts(std::vector<cv::Point2f>& points1,std::vector<cv::Point2f>& points2); public:LKTracker();//特征點的跟蹤??bool trackf2f(const cv::Mat& img1, const cv::Mat& img2,std::vector<cv::Point2f> &points1, std::vector<cv::Point2f> &points2);float getFB(){return fbmed;} };
?
LKTracker.cpp
#include <LKTracker.h> using namespace cv;//金字塔LK光流法跟蹤 //Media Flow 中值光流跟蹤 加 跟蹤錯誤檢測 //構造函數,初始化成員變量 LKTracker::LKTracker(){該類變量需要3個參數,一個是類型,第二個參數為迭代的最大次數,最后一個是特定的閾值。term_criteria = TermCriteria( TermCriteria::COUNT + TermCriteria::EPS, 20, 0.03);window_size = Size(4,4);level = 5;lambda = 0.5; }bool LKTracker::trackf2f(const Mat& img1, const Mat& img2, vector<Point2f> &points1, vector<cv::Point2f> &points2){//TODO!:implement c function cvCalcOpticalFlowPyrLK() or Faster tracking function//Forward-Backward tracking//基于Forward-Backward Error的中值流跟蹤方法//金字塔LK光流法跟蹤//forward trajectory 前向軌跡跟蹤calcOpticalFlowPyrLK( img1,img2, points1, points2, status, similarity, window_size, level, term_criteria, lambda, 0);//backward trajectory 后向軌跡跟蹤calcOpticalFlowPyrLK( img2,img1, points2, pointsFB, FB_status,FB_error, window_size, level, term_criteria, lambda, 0);//Compute the real FB-error//原理很簡單:從t時刻的圖像的A點,跟蹤到t+1時刻的圖像B點;然后倒回來,從t+1時刻的圖像的B點往回跟蹤,//假如跟蹤到t時刻的圖像的C點,這樣就產生了前向和后向兩個軌跡,比較t時刻中 A點 和 C點 的距離,如果距離//小于一個閾值,那么就認為前向跟蹤是正確的;這個距離就是FB_error//計算 前向 與 后向 軌跡的誤差for( int i= 0; i<points1.size(); ++i ){FB_error[i] = norm(pointsFB[i]-points1[i]); //norm()求矩陣或向量的范數??絕對值?}//Filter out points with FB_error[i] <= median(FB_error) && points with sim_error[i] > median(sim_error)normCrossCorrelation(img1, img2, points1, points2);return filterPts(points1, points2); }//利用NCC把跟蹤預測的結果周圍取10*10的小圖片與原始位置周圍10*10的小圖片(使用函數getRectSubPix得到)進 //行模板匹配(調用matchTemplate) void LKTracker::normCrossCorrelation(const Mat& img1,const Mat& img2, vector<Point2f>& points1, vector<Point2f>& points2) {Mat rec0(10,10,CV_8U);Mat rec1(10,10,CV_8U);Mat res(1,1,CV_32F);for (int i = 0; i < points1.size(); i++) {if (status[i] == 1) { //為1表示該特征點跟蹤成功//從前一幀和當前幀圖像中(以每個特征點為中心?)提取10x10象素矩形,使用亞象素精度getRectSubPix( img1, Size(10,10), points1[i],rec0 ); getRectSubPix( img2, Size(10,10), points2[i],rec1);//匹配前一幀和當前幀中提取的10x10象素矩形,得到匹配后的映射圖像//CV_TM_CCOEFF_NORMED 歸一化相關系數匹配法//參數分別為:欲搜索的圖像。搜索模板。比較結果的映射圖像。指定匹配方法matchTemplate( rec0,rec1, res, CV_TM_CCOEFF_NORMED); similarity[i] = ((float *)(res.data))[0]; //得到各個特征點的相似度大小} else {similarity[i] = 0.0;}}rec0.release();rec1.release();res.release(); }//篩選出 FB_error[i] <= median(FB_error) 和 sim_error[i] > median(sim_error) 的特征點 //得到NCC和FB error結果的中值,分別去掉中值一半的跟蹤結果不好的點 bool LKTracker::filterPts(vector<Point2f>& points1,vector<Point2f>& points2){//Get Error Medianssimmed = median(similarity); //找到相似度的中值size_t i, k;for( i=k = 0; i<points2.size(); ++i ){if( !status[i])continue;if(similarity[i]> simmed){ //剩下 similarity[i]> simmed 的特征點points1[k] = points1[i]; points2[k] = points2[i];FB_error[k] = FB_error[i];k++;}}if (k==0)return false;points1.resize(k);points2.resize(k);FB_error.resize(k);fbmed = median(FB_error); //找到FB_error的中值for( i=k = 0; i<points2.size(); ++i ){if( !status[i])continue;if(FB_error[i] <= fbmed){ /points1[k] = points1[i]; //再對上一步剩下的特征點進一步篩選,剩下 FB_error[i] <= fbmed 的特征點points2[k] = points2[i];k++;}}points1.resize(k);points2.resize(k);if (k>0)return true;elsereturn false; }/** old OpenCV style void LKTracker::init(Mat img0, vector<Point2f> &points){//Preallocate//pyr1 = cvCreateImage(Size(img1.width+8,img1.height/3),IPL_DEPTH_32F,1);//pyr2 = cvCreateImage(Size(img1.width+8,img1.height/3),IPL_DEPTH_32F,1);//const int NUM_PTS = points.size();//status = new char[NUM_PTS];//track_error = new float[NUM_PTS];//FB_error = new float[NUM_PTS]; }void LKTracker::trackf2f(..){cvCalcOpticalFlowPyrLK( &img1, &img2, pyr1, pyr1, points1, points2, points1.size(), window_size, level, status, track_error, term_criteria, CV_LKFLOW_INITIAL_GUESSES);cvCalcOpticalFlowPyrLK( &img2, &img1, pyr2, pyr1, points2, pointsFB, points2.size(),window_size, level, 0, 0, term_criteria, CV_LKFLOW_INITIAL_GUESSES | CV_LKFLOW_PYR_A_READY | CV_LKFLOW_PYR_B_READY ); } */總結
以上是生活随笔為你收集整理的TLD(Tracking-Learning-Detection)学习与源码理解之(五)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: TLD(Tracking-Learnin
- 下一篇: TLD(Tracking-Learnin