目標跟蹤之klt---光流跟蹤法


近來在研究跟蹤,跟蹤的方法其實有很多,如粒子濾波(pf)、meanshift跟蹤,以及KLT跟蹤或叫Lucas光流法,這些方法各自有各自的有點,對於粒子濾波而言,它能夠比較好的在全局搜索到最優解,但其求解速度相對較慢,由於其是基於顏色直方圖的計算,所以對相同顏色東西不太能夠區別,meanshift方法很容易陷入局部最優,但速度還是挺快,所以現在很有一些人是將meanshift跟pf結合做跟蹤,恰好在很多方面能夠互補。

  Kanade-Lucas-Tomasi方法,在跟蹤方面表現的也不錯,尤其在實時計算速度上,用它來得到的,是很多點的軌跡“trajectory”,並且還有一些發生了漂移的點,所以,得到跟蹤點之后要進行一些后期的處理,說到Kanade-Lucas-Tomasi方法,首先要追溯到Kanade-Lucas兩人在上世紀80年代發表的paper:An Iterative Image Registration Technique with an Application to Stereo Vision,這里講的是一種圖像點定位的方法,即圖像的局部匹配,將圖像匹配問題,從傳統的滑動窗口搜索方法變為一個求解偏移量d的過程,后來Jianbo Shi和Carlo Tomasi兩人發表了一篇CVPR(94')的文章Good Features To Track,這篇文章,主要就是講,在求解d的過程中,哪些情況下可以保證一定能夠得到d的解,這些情況的點有什么特點(后來會發現,很多時候都是尋找的角點)。

  PS: 其實我很奇怪這個算法為什么叫做KLT算法,而不加上Jianbo Shi的名字~

  好吧,前戲就這么多,接下來進入正題,KLT是如何實現跟蹤的?

  先說KLT算法的幾個前提假設:
   1)亮度恆定
   2)時間連續或者是運動是“小運動”
     3)空間一致,臨近點有相似運動,保持相鄰

  這幾個為什么要這么假設,我在后面來解釋,很直觀的講,如果判斷一個視頻的相鄰兩幀I、J在某局部窗口w上是一樣的,則在窗口w內有:I(x, y, t) = J(x', y', t+τ),亮度恆定的假設(假設1)即為了保證其等號成立不受亮度的影響,假設2是為了保證KLT能夠找到點,假設3則為以下原因假設(即對於同一個窗口中,所有點的偏移量都相等):

  在窗口w上,所有(x, y)都往一個方向移動了(dx,  dy),從而得到(x', y'),即t時刻的(x, y)點在t+τ時刻為(x+dx, y+dy),所以尋求匹配的問題可化為對以下的式子尋求最小值,或叫做最小化以下式子:

  用積分來表示上述式子,以上式子可等效為:

  這個式子的含義,即找到兩副圖像中,在W窗口中,I、J的差異,其中I以x-d/2為中心,J以x+d/2為中心,w/2為半徑的一個矩形窗口間的差異,好吧,結合我們微積分的知識,函數ε(d)要取得最小值,這個極值點的導數一定為0,即
  

的值為0,由泰勒展開的性質:

可以得到:

於是,問題轉化為:

其中:

從而,問題即為:

=>

即其等式可看作為:

其中,Z為一個2*2的矩陣,e為一個2*1的向量,

為了要使d能夠得到解,則Z需要滿足條件,即Z*Z'矩陣可逆,其中Z'為Z矩陣的轉置(ZT),在一般情況下,角點具有這樣的特點。

在OpenCV里面,找角點的函數可用

void cvGoodFeaturesToTrack(
   const CvArr* image
   CvArr* eigImage, CvArr* tempImage
   CvPoint2D32f* corners
   int* cornerCount
   double qualityLevel
   double minDistance
   const CvArr* mask=NULL
   int blockSize=3
   int useHarris=0 //一般采用Harris角點
   double k=0.04 );

然后可以通過函數cvCalcOpticalFlowPyrLK進行跟蹤(好像OpenCV里面調用LK的函數不止這一個,這個是金字塔計算):

void cvCalcOpticalFlowPyrLK(
    const CvArr* prev,
    const CvArr* curr,
    CvArr* prevPyr,
    CvArr* currPyr,
    const CvPoint2D32f* prevFeatures,
    CvPoint2D32f* currFeatures,
    int count,
    CvSize winSize,
    int level,
    char* status,
    float* track error,
    CvTermCriteria criteria,
    int flags );

  OK,KLT算法的原理基本就這樣,其實其跟蹤效果並非太准,后來有很多提出的校正的方法,其中我目前看到比較實用的就是TLD算法的作者Zdenek Kalal在他2010年ICPR上的文章Forward-Backward Error: Automatic Detection of Tracking Failures提出的方法看起來非常不錯,我正動手實現之。

網友做過的實驗用光流+角點檢測效果圖:

用角點統計光流1

 

opencv 中d1-2:

opencv 中的cif-3:

fast 角點-4:

用gmm:

http://www.cnblogs.com/moondark/archive/2012/05/12/2497391.html

http://blog.sina.com.cn/s/blog_50363a7901011215.html

http://www.cnblogs.com/jtianwen2014/p/4249003.html knn分類


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM