TLD(Tracking-Learning-Detection)學習與源碼理解之(五)

來源:互聯網
上載者:User

       下面是自己在看論文和這些大牛的分析過程中,對代碼進行了一些理解,但是由於自己接觸影像處理和機器視覺沒多久,另外由於自己編程能力比較弱,所以分析過程可能會有不少的錯誤,希望各位不吝指正。而且,因為編程很多地方不懂,所以注釋得非常亂,還海涵。

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, 否則設定為 0  std::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 Medians  simmed = 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;  else    return false;}/* * old OpenCV stylevoid 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 );}*/

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.