近來在研究跟蹤,跟蹤的方法其實有很多,如粒子濾波(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分類