系列文章目錄
本系列開篇文章,暫時沒有目錄啦~
文章目錄
- 系列文章目錄
- 前言
- 一、問題假設
- 二、方程推導
- 三、計算Ix,Iy,ItI_x,I_y,I_tIx?,Iy?,It?
- 四、計算光流u,vu,vu,v
- 4.1 傳統算法Lucas-Kanade算法
- 五、孔徑問題
- 5.1 直觀理解
- 5.2 數學角度
- 5.3 解決方法
- 總結
前言
光流(Optical Flow)是指圖像中的物體在連續幀之間的相對運動。具體來說,光流法試圖通過圖像中的像素變化(通常是亮度變化)來推測場景中物體的運動方向和速度。
假設你有一個視頻或連續的圖像幀,光流法就是計算在連續的兩幀圖像之間,每個像素點的位移(即物體的運動)。如果你可以估計每個像素點的位移,那么你就可以獲得整個圖像的光流場。
主要參考了下述兩篇文章,如有侵權,聯系我我會刪除此內容
經典光流算法Lucas-Kanade(有圖助理解)
光流法(optical flow methods)
一、問題假設
假設一——亮度一致性假設:圖像中某個像素點的亮度在連續的兩幀圖像之間不會發生太大變化,只有由于相對運動而產生的位移。即假設物體的亮度在兩幀圖像之間是恒定的。這個假設是基于圖像的亮度變化主要由物體的運動引起的。
假設二——平滑性假設:圖像中的運動變化是平滑的,即在局部區域內,相鄰像素的運動是相似的。
二、方程推導
設t時刻(x,y)位置的像素亮度為I(x,y,t)I(x,y,t)I(x,y,t)
根據假設一,對于一個像素點(x,y)(x,y)(x,y),在時間ttt和t+Δtt+\Delta tt+Δt之間的亮度變化應滿足:
I(x,y,t)=I(x+Δx,y+Δy,t+Δt)I(x,y,t)=I(x+\Delta x,y+\Delta y,t+\Delta t)I(x,y,t)=I(x+Δx,y+Δy,t+Δt)
其中:
- I(x,y,t)I(x,y,t)I(x,y,t)表示時刻ttt時,坐標(x,y)(x,y)(x,y)位置的亮度。
- Δx,Δy\Delta x,\Delta yΔx,Δy分別是該像素在水平和垂直方向上的位移。
- Δt\Delta tΔt是兩個圖像幀之間的時間差。
利用泰勒級數展開對右邊進行近似,可以得到一個簡化的表達式。泰勒展開的思想是,通過將一個函數在某一點附近的變化表示為該點函數值與其各階導數的線性組合,來逼近這個函數在該點附近的值。
將I(x+Δx,y+Δy,t+Δt)I(x+\Delta x,y+\Delta y,t+\Delta t)I(x+Δx,y+Δy,t+Δt)近似為I(x+Δx,y+Δy,t+Δt)≈I(x,y,t)+?I?xΔx+?I?yΔy+?I?tΔtI(x+\Delta x,y+\Delta y,t+\Delta t) \approx I(x,y,t)+\frac{\partial I}{\partial x}\Delta x+\frac{\partial I}{\partial y}\Delta y+\frac{\partial I}{\partial t}\Delta tI(x+Δx,y+Δy,t+Δt)≈I(x,y,t)+?x?I?Δx+?y?I?Δy+?t?I?Δt
這個公式使用了泰勒展開的前幾項,其中:
- ?I?x\frac{\partial I}{\partial x}?x?I?是圖像I(x,y,t)I(x,y,t)I(x,y,t)在xxx方向的偏導數,表示圖像亮度在水平(x)方向上的變化速率(即圖像在xxx方向上的梯度);
- ?I?y\frac{\partial I}{\partial y}?y?I?是圖像I(x,y,t))I(x,y,t))I(x,y,t))在yyy方向的偏導數,表示圖像亮度在垂直(y)方向上的變化速率(即圖像在yyy方向上的梯度);
- ?I?t\frac{\partial I}{\partial t}?t?I?是圖像I(x,y,t)I(x,y,t)I(x,y,t)隨時間ttt變化的偏導數,表示圖像亮度在時間方向上的變化速率(即圖像隨時間變化的亮度變化)。
現在,我們將泰勒展開的結果代入亮度恒定假設中:
I(x,y,t)=I(x+Δx,y+Δy,t+Δt)=I(x,y,t)+IxΔx+IyΔy+ItΔtI(x,y,t)=I(x+\Delta x,y+\Delta y,t+\Delta t)=I(x,y,t)+I_x\Delta x+I_y\Delta y+I_t\Delta tI(x,y,t)=I(x+Δx,y+Δy,t+Δt)=I(x,y,t)+Ix?Δx+Iy?Δy+It?Δt
其中:
- Ix=?I?xI_x=\frac{\partial I}{\partial x}Ix?=?x?I?是圖像在xxx方向的梯度;
- Iy=?I?yI_y=\frac{\partial I}{\partial y}Iy?=?y?I?是圖像在yyy方向的梯度;
- It=?I?tI_t=\frac{\partial I}{\partial t}It?=?t?I?是圖像在ttt方向的梯度。
由于左側的兩個I(x,y,t)I(x,y,t)I(x,y,t)相等,可以將它們抵消掉:
0=IxΔx+IyΔy+ItΔt0=I_x\Delta x+I_y\Delta y+I_t\Delta t0=Ix?Δx+Iy?Δy+It?Δt
接下來,假設Δx\Delta xΔx和Δy\Delta yΔy是該像素的位移(即物體運動導致該像素位置的變化),我們可以將Δx\Delta xΔx和Δy\Delta yΔy表示為光流的分量uuu和vvv,即:
Δx=uΔt\Delta x=u\Delta tΔx=uΔt
Δy=vΔt\Delta y=v\Delta tΔy=vΔt
其中:
- uuu是圖像中像素在方向的運動速度(光流的水平分量);
- vvv是圖像中像素在方向的運動速度(光流的垂直分量);
- Δt\Delta tΔt是兩個時間幀之間的時間差。
將這些表達式代入之前的方程,我們得到:
0=IxuΔt+IyvΔt+ItΔt0=I_xu\Delta t+I_yv\Delta t+I_t\Delta t0=Ix?uΔt+Iy?vΔt+It?Δt
由于Δt\Delta tΔt是一個常數,且不等于零,我們可以把Δt\Delta tΔt消去,得到光流的核心方程:
Ixu+Iyv+It=0I_xu+I_yv+I_t=0Ix?u+Iy?v+It?=0
這個方程描述了在每個像素點上,圖像亮度變化與該點的運動(光流)之間的關系。它給出了光流uuu和vvv的關系:像素的運動(光流)與圖像的梯度信息(在空間和時間上的變化)有關。
三、計算Ix,Iy,ItI_x,I_y,I_tIx?,Iy?,It?
四、計算光流u,vu,vu,v
4.1 傳統算法Lucas-Kanade算法
增加一個假設:假設在小窗口內,光流是恒定的。
算法的核心思想是通過在該窗口內對每個像素的光流方程進行加權最小二乘法擬合,從而估算出該窗口內所有像素的水平和垂直方向的光流(即uuu和vvv)。
Ixu+Iyv+It=0I_xu+I_yv+I_t=0Ix?u+Iy?v+It?=0
我們將上述公式轉為矩陣形式:
(Ix,Iy)(uv)=?It(I_x,I_y)\begin{pmatrix} u\\ v \end{pmatrix}=-I_t(Ix?,Iy?)(uv?)=?It?
所以,如果我們選擇一個n×nn \times nn×n的窗口(包含n2n^2n2個像素),那么每個像素的光流滿足相同的方程。對于這個窗口內的所有像素,我們可以構建以下方程組:
{Ix1u+Iy1v=?It1Ix2u+Iy2v=?It2?Ixnu+Iynv=?Itn\left\{\begin{matrix} I_{x1}u+I_{y1}v=-I_{t1}\\ I_{x2}u+I_{y2}v=-I_{t2}\\ \vdots \\ I_{xn}u+I_{yn}v=-I_{tn} \end{matrix}\right.????Ix1?u+Iy1?v=?It1?Ix2?u+Iy2?v=?It2??Ixn?u+Iyn?v=?Itn??
將上述方程組轉為矩陣形式:
[Ix1Iy1Ix2Iy2??IxnIyn][uv]=?[It1It2?Itn]\begin{bmatrix} I_{x1} & I_{y1}\\ I_{x2} & I_{y2}\\ \vdots &\vdots \\ I_{xn} &I_{yn} \end{bmatrix}\begin{bmatrix} u\\ v \end{bmatrix}=-\begin{bmatrix} I_{t1}\\ I_{t2}\\ \vdots\\ I_{tn} \end{bmatrix}?Ix1?Ix2??Ixn??Iy1?Iy2??Iyn???[uv?]=??It1?It2??Itn???
令左邊矩陣為AAA,中間矩陣為xxx,右邊矩陣為bbb,上述公式轉為:
Ax=bAx=bAx=b
利用最小二乘法的解法,我們可以得到uuu和vvv的解:
x=(ATA)?1ATbx=(A^TA)^{-1}A^{T}bx=(ATA)?1ATb
觀察上述公式可以發現一個問題:ATAA^TAATA一定有逆嗎?參看第五節。
五、孔徑問題
5.1 直觀理解
想象你透過一個小孔(比如一根吸管)去觀察一條運動的直線。如果這條直線向右上方移動,你在小孔里看到的只是直線的一小段。由于你只能看到局部信息,你會發現:
- 直線沿著垂直于自身的方向移動時,亮度會明顯變化;
- 但如果直線沿著平行于自身的方向移動時,局部的亮度看起來幾乎不變。
結果就是:
你無法僅憑小孔里的這一小段直線判斷運動的真實方向,只能感知到垂直于邊緣的運動,而沿邊緣方向的運動信息丟失。
這就是“孔徑問題”的由來。
5.2 數學角度
光流基本方程是:
Ixu+Iyv+It=0I_xu+I_yv+I_t=0Ix?u+Iy?v+It?=0
這是一個一元約束(一條方程),但我們有兩個未知數(u,v)(u,v)(u,v)。
結果是:我們只能確定光流在圖像梯度方向上的分量,而沿著等梯度方向的分量無法確定。
舉個例子:
- 如果圖像中某個區域是純水平邊緣(亮度只隨 y 變化),則Ix=0,Iy≠0I_x=0,I_y \neq 0Ix?=0,Iy?=0
- 則方程變成Iyv+It=0I_yv+I_t=0Iy?v+It?=0。這時候我們只能解出vvv(垂直方向的運動),而uuu(水平方向的運動)完全不受約束。
- 這就是孔徑問題:缺少運動方向的完整信息。
那么與ATAA^TAATA是否可逆有什么關系呢?
我們先考慮一下有哪些情況ATAA^TAATA不可逆:
- 像素的梯度信息缺失或重復:如果圖像中的某個區域(或多個區域)的梯度信息是重復的或無效的,那么矩陣的列會變得線性相關。例如,如果在某個區域內圖像亮度完全不變化(如純白色區域),那么,這意味著我們無法從該像素中提取任何有用的運動信息,導致梯度矩陣的列是線性相關的。
- 沒有足夠的運動信息:在一些特定情況下,比如圖像中存在單一的邊緣(比如水平或垂直邊緣),我們只能檢測到沿邊緣方向的運動,而無法感知到垂直于邊緣方向的運動。這會導致方向的梯度相同或相互平行,進而使得矩陣變得奇異(不可逆)。
- 局部區域的梯度信息不足:如果選擇的局部窗口區域太小,導致該區域內的圖像梯度幾乎沒有變化,也可能導致的列線性相關。例如,如果選擇一個只有一條直線的區域,那么該區域內的梯度信息就沒有足夠的多樣性來推測所有方向的運動。
是不是有點眼熟,好像我們剛剛在直觀理解里面提到過一些東西?沒錯,孔徑問題是在一定程度上可以用ATAA^TAATA不可逆來解釋的。那么ATAA^TAATA不可逆會出現什么情況呢?可能會出現多解,也就是不能準確估計運動方向。
5.3 解決方法
既然ATAA^TAATA不可逆會出現孔徑問題,那么我們不用ATAA^TAATA不可逆的地方不就行了?
因此我們可以選擇一些角點,這樣保證ATAA^TAATA可逆,就可以保證光流估計運動方向的精度了。