Lucas-Kanade算法


Lucas-Kanade 方法

其原論文鏈接:http://cseweb.ucsd.edu/classes/sp02/cse252/lucaskanade81.pdf


光流法

在目標跟蹤的領域引入光流法是一個突破性進展,這還得歸功於Barron,他在1994年發佈了論文“Performance of optical flow techniques”,並提出了光流這一概念。


雖然這一方法能夠對目標更好地進行跟蹤,但同時也存在一些限制性因素,包括運動連續性、運動剛性、光的變化、地表實況等。現在大多數的光流算法都是針對全局能量函數的優化問題而提出的,這裏的能量函數可以看作爲代價函數,它的作用是保持系統狀態的穩定。其中它的表達式爲:
EGlobal=EData+λEPrior1E_{Global} = E_{Data} + \lambda E_{Prior} (1)
第一項 EDataE_{Data} 表示測量光流與輸入圖像的一致性問題,因爲Data中的約束方程小於未知量個數,所以需要一個先驗條件來優化該函數,即使用 EPriorE_{Prior} 來表示,並用 λ\lambda 作爲係數進行參數調整。

在這裏插入圖片描述
以上是基本的光流約束方程




Lucas-Kanade方法原理

Lucas-Kanade算法是根據兩幀圖像之間像素點的變化進行處理的,而且具有一定的稀疏性

使用這一方法有幾個假設的前提條件,如下所示:

  1. 亮度恆定,從 t 到 t+1 時刻不會出現亮度變化
  2. 運動緩慢,從 t 到 t+1 時刻不會引起位置的劇烈變化
  3. 空間一致,從 t 到 t+1 時刻像素點的鄰近點不發生變化


1. 以下是圖像匹配時考慮的問題

在這裏插入圖片描述
假設圖片的大小爲NxN,特徵點的大小爲MxM

論文中提到了窮舉搜索(exhaustively search)進行圖像匹配的時間複雜度爲 O(M2N2)O(M^2N^2),消耗太長的時間;也提到了爬山算法(hill-climbing algorithm)是一個局部搜索技術,在一定的情況下無法找到全局最優值,其時間複雜度爲O(M2N)O(M^2N);還提到了序慣性檢測算法(sequential similarity detection algorithm)中的規則不確定性。

然後提出了自己的方法,先對圖 Figure1 中的 h 進行初始估計,再針對每一個像素點使用空間強度梯度(spatial intensity gradient)方法優化 h 值,並使用類似於NR的迭代方法(Newton-Raphson iteration)對該過程進行迭代,該方法的時間複雜度爲 O(M2logN)O(M^2 log N)


2.在簡單的一維情況下進行分析

在這裏插入圖片描述

通過分析我們得到了 h 的表達式,然後對 h 的值進行優化

在這裏插入圖片描述
最後我們得到了優化後的 h 表達式,進而求出更加精確的 h 值,以此來獲得相同的特徵點。然後我們可以從一維擴展到多維,利用同樣的方法實現,具體步驟論文中詳細介紹了。


將LK方法應用到光流法中可參考鏈接:https://www.cnblogs.com/gnuhpc/archive/2012/12/04/2802124.html

其中的 I(x,y,t)I(x,y,t)I(x+Δx,y+Δy)I(x+ \Delta x,y+ \Delta y) 就相當於是前面圖中所示的 F(x)F(x)G(x)G(x) ,而 h 則相當於轉變的方位跟大小,用一階泰勒展開後的一階項




在OpenCV中使用LK方法


C++: void calcOpticalFlowPyrLK(
		InputArray prevImg, 
		InputArray nextImg,
		InputArray prevPts, 
		InputOutputArray nextPts, 
		OutputArray status, 
		OutputArray err, 
		Size winSize=Size(21,21), 
		int maxLevel=3, 
		TermCriteria criteria=TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 0.01), 
		int flags=0, 
		double minEigThreshold=1e-4 
		)


第一個參數 prevImg 表示的是8位輸入圖像 或者是 使用 buildOpticalFlowPyramid() 方法構建的金字塔圖像(pyramid)

第二個參數 nextImg 表示的是與 prevImg 同樣格式的輸入圖像,且是對應於 preImg 的下一幀圖像

第三個參數 prevPts 表示的是檢測到的光流(特徵)的二維點向量,其中點座標必須是單精度浮點數(single-precison floating-point)

第四個參數 nextPts 表示的是一個 包含了在下一幀圖像中計算得出的新特徵位置 的二維點向量

第五個參數 status 表示的是輸出的狀態向量,如果能夠找到對應特徵的流 即將向量元素置爲1,若不能則置爲0

第六個參數 err 表示的是輸出的誤差向量,每一個向量相關聯的特徵點均設置一個誤差值,並且誤差測量的方式由 參數flags來設定

第七個參數 winSize 表示的是定義的金字塔圖像每一層的搜索窗口大小

第八個參數 maxLevel 表示的是定義的金字塔圖像的層次,如果 maxLevel=0 即只有一層圖像, maxLevel=n 即有n+1層圖像。如果金字塔圖像被傳遞給了輸入圖像,該算法會使用不超過maxLevel的層次數

第九個參數 criteria 表示的是迭代搜索算法 (iterative search algorithm) 的最終收斂條件

第十個參數 flags 表示的是操作標誌

  1. OPTFLOW_USE_INITIAL_FLOW
    使用初始估計將特徵點(流)儲存在 nextPts 上;如果該標誌未設置,即將prePts複製到nextPts作爲初始的估計值
  2. OPTFLOW_LK_GET_MIN_EIGENVALS
    使用最小特徵值 (minimum eigen values) 作爲誤差度量;如果該標誌未設置,即取起始點到運動點之間的L1範數 (L1 norm),然後除以窗口的像素大小作爲誤差度量

第十一個參數 minEigThreshold 表示的是一個算法,計算2x2標準光流矩陣最小特徵值再除以窗口的像素大小;如果求出的值小於minEigThreshold 則過濾掉相應的特徵,所以這個方法可以除去不好的特徵點並提高性能。



構建金字塔圖像的方法


C++: int buildOpticalFlowPyramid(
		InputArray img, 
		OutputArrayOfArrays pyramid, 
		Size winSize, 
		int maxLevel, 
		bool withDerivatives=true, 
		int pyrBorder=BORDER_REFLECT_101, 
		int derivBorder=BORDER_CONSTANT, 
		bool tryReuseInputImage=true
		)


第一個參數 img 爲8位的輸入圖像

第二個參數 pyramid 爲輸出的金字塔圖像

第三個參數 winSize 表示的是實現光流算法的窗口大小,不能小於calcOpticalFlowPyrLK() 中的winSize參數。並且它需要計算金字塔層次所需的填充。

第四個參數 maxLevel 表示的是金字塔層次的最大層次數

第五個參數 withDerivatives 表示設置一個預計算梯度處理金字塔圖像的每一層圖像

第六個參數 pyrBorder 表示的是金字塔圖像的邊界模式

第七個參數 derivBorder 表示的是梯度的邊界模式

第八個參數 tryReuseInputImage 表示的是是否將輸入圖像的興趣區域 (ROI : Region of Intretest) 設置到金字塔圖像中,默認爲 true


進行邊界填充是爲了避免圖像膨脹後導致的邊界模糊的狀態,填充後才能保證對邊界像素的安全操作,以下有兩種填充邊界(borderType) 的方法

  1. ORDER_CONSTANT: 使用常數填充邊界
  2. BORDER_REPLICATE: 複製原圖中最臨近的行或者列

該函數返回一個int型數據,表示金字塔圖像的層次大小,不過該值小於 maxLevel



發佈了49 篇原創文章 · 獲贊 11 · 訪問量 3059
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章