Lucas-Kanade 方法
其原論文鏈接:http://cseweb.ucsd.edu/classes/sp02/cse252/lucaskanade81.pdf
光流法
在目標跟蹤的領域引入光流法是一個突破性進展,這還得歸功於Barron,他在1994年發佈了論文“Performance of optical flow techniques”,並提出了光流這一概念。
雖然這一方法能夠對目標更好地進行跟蹤,但同時也存在一些限制性因素,包括運動連續性、運動剛性、光的變化、地表實況等。現在大多數的光流算法都是針對全局能量函數的優化問題而提出的,這裏的能量函數可以看作爲代價函數,它的作用是保持系統狀態的穩定。其中它的表達式爲:
第一項 表示測量光流與輸入圖像的一致性問題,因爲Data中的約束方程小於未知量個數,所以需要一個先驗條件來優化該函數,即使用 來表示,並用 作爲係數進行參數調整。
以上是基本的光流約束方程
Lucas-Kanade方法原理
Lucas-Kanade算法是根據兩幀圖像之間像素點的變化進行處理的,而且具有一定的稀疏性
使用這一方法有幾個假設的前提條件,如下所示:
- 亮度恆定,從 t 到 t+1 時刻不會出現亮度變化
- 運動緩慢,從 t 到 t+1 時刻不會引起位置的劇烈變化
- 空間一致,從 t 到 t+1 時刻像素點的鄰近點不發生變化
1. 以下是圖像匹配時考慮的問題
假設圖片的大小爲NxN,特徵點的大小爲MxM
論文中提到了窮舉搜索(exhaustively search)進行圖像匹配的時間複雜度爲 ,消耗太長的時間;也提到了爬山算法(hill-climbing algorithm)是一個局部搜索技術,在一定的情況下無法找到全局最優值,其時間複雜度爲;還提到了序慣性檢測算法(sequential similarity detection algorithm)中的規則不確定性。
然後提出了自己的方法,先對圖 Figure1 中的 h 進行初始估計,再針對每一個像素點使用空間強度梯度(spatial intensity gradient)方法優化 h 值,並使用類似於NR的迭代方法(Newton-Raphson iteration)對該過程進行迭代,該方法的時間複雜度爲
2.在簡單的一維情況下進行分析
通過分析我們得到了 h 的表達式,然後對 h 的值進行優化
最後我們得到了優化後的 h 表達式,進而求出更加精確的 h 值,以此來獲得相同的特徵點。然後我們可以從一維擴展到多維,利用同樣的方法實現,具體步驟論文中詳細介紹了。
將LK方法應用到光流法中可參考鏈接:https://www.cnblogs.com/gnuhpc/archive/2012/12/04/2802124.html
其中的 和 就相當於是前面圖中所示的 和 ,而 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 表示的是操作標誌
- OPTFLOW_USE_INITIAL_FLOW
使用初始估計將特徵點(流)儲存在 nextPts 上;如果該標誌未設置,即將prePts複製到nextPts作爲初始的估計值- 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) 的方法
- ORDER_CONSTANT: 使用常數填充邊界
- BORDER_REPLICATE: 複製原圖中最臨近的行或者列
該函數返回一個int型數據,表示金字塔圖像的層次大小,不過該值小於 maxLevel