光流法 Optical Flow
最近調(diào)研目標(biāo)跟蹤,看到一個(gè)光流法,測(cè)試了一下它的效果,挺好玩的,這里對(duì)找到的資料簡單整理總結(jié)一下。
對(duì)于光流法的介紹,可以參看如下博客http://blog.csdn.net/zouxy09/article/details/8683859?:
光流(optic flow)是什么呢?名字很專業(yè),感覺很陌生,但本質(zhì)上,我們是最熟悉不過的了。因?yàn)檫@種視覺現(xiàn)象我們每天都在經(jīng)歷。從本質(zhì)上說,光流就是你在這個(gè)運(yùn)動(dòng)著的世界里感覺到的明顯的視覺運(yùn)動(dòng)(呵呵,相對(duì)論,沒有絕對(duì)的靜止,也沒有絕對(duì)的運(yùn)動(dòng))。例如,當(dāng)你坐在火車上,然后往窗外看。你可以看到樹、地面、建筑等等,他們都在往后退。這個(gè)運(yùn)動(dòng)就是光流。而且,我們都會(huì)發(fā)現(xiàn),他們的運(yùn)動(dòng)速度居然不一樣?這就給我們提供了一個(gè)挺有意思的信息:通過不同目標(biāo)的運(yùn)動(dòng)速度判斷它們與我們的距離。一些比較遠(yuǎn)的目標(biāo),例如云、山,它們移動(dòng)很慢,感覺就像靜止一樣。但一些離得比較近的物體,例如建筑和樹,就比較快的往后退,然后離我們的距離越近,它們往后退的速度越快。一些非常近的物體,例如路面的標(biāo)記啊,草地啊等等,快到好像在我們耳旁發(fā)出嗖嗖的聲音。
光流除了提供遠(yuǎn)近外,還可以提供角度信息。與咱們的眼睛正對(duì)著的方向成90度方向運(yùn)動(dòng)的物體速度要比其他角度的快,當(dāng)小到0度的時(shí)候,也就是物體朝著我們的方向直接撞過來,我們就是感受不到它的運(yùn)動(dòng)(光流)了,看起來好像是靜止的。當(dāng)它離我們?cè)浇?#xff0c;就越來越大(當(dāng)然了,我們平時(shí)看到感覺還是有速度的,因?yàn)槲矬w較大,它的邊緣還是和我們?nèi)搜劬哂写笥?的角度的)。
呵呵,說了那么多,好像還沒進(jìn)入比較官方的,研究性的定義。那就貼上一個(gè)吧。
光流的概念是Gibson在1950年首先提出來的。它是空間運(yùn)動(dòng)物體在觀察成像平面上的像素運(yùn)動(dòng)的瞬時(shí)速度,是利用圖像序列中像素在時(shí)間域上的變化以及相鄰幀之間的相關(guān)性來找到上一幀跟當(dāng)前幀之間存在的對(duì)應(yīng)關(guān)系,從而計(jì)算出相鄰幀之間物體的運(yùn)動(dòng)信息的一種方法。一般而言,光流是由于場(chǎng)景中前景目標(biāo)本身的移動(dòng)、相機(jī)的運(yùn)動(dòng),或者兩者的共同運(yùn)動(dòng)所產(chǎn)生的。
當(dāng)人的眼睛觀察運(yùn)動(dòng)物體時(shí),物體的景象在人眼的視網(wǎng)膜上形成一系列連續(xù)變化的圖像,這一系列連續(xù)變化的信息不斷“流過”視網(wǎng)膜(即圖像平面),好像一種光的“流”,故稱之為光流(optical flow)。光流表達(dá)了圖像的變化,由于它包含了目標(biāo)運(yùn)動(dòng)的信息,因此可被觀察者用來確定目標(biāo)的運(yùn)動(dòng)情況。
研究光流場(chǎng)的目的就是為了從圖片序列中近似得到不能直接得到的運(yùn)動(dòng)場(chǎng)。運(yùn)動(dòng)場(chǎng),其實(shí)就是物體在三維真實(shí)世界中的運(yùn)動(dòng);光流場(chǎng),是運(yùn)動(dòng)場(chǎng)在二維圖像平面上(人的眼睛或者攝像頭)的投影。
那通俗的講就是通過一個(gè)圖片序列,把每張圖像中每個(gè)像素的運(yùn)動(dòng)速度和運(yùn)動(dòng)方向找出來就是光流場(chǎng)。那怎么找呢?咱們直觀理解肯定是:第t幀的時(shí)候A點(diǎn)的位置是(x1, y1),那么我們?cè)诘趖+1幀的時(shí)候再找到A點(diǎn),假如它的位置是(x2,y2),那么我們就可以確定A點(diǎn)的運(yùn)動(dòng)了:(ux, vy) = (x2, y2) - (x1,y1)。
那怎么知道第t+1幀的時(shí)候A點(diǎn)的位置呢? 這就存在很多的光流計(jì)算方法了。
1981年,Horn和Schunck創(chuàng)造性地將二維速度場(chǎng)與灰度相聯(lián)系,引入光流約束方程,得到光流計(jì)算的基本算法。人們基于不同的理論基礎(chǔ)提出各種光流計(jì)算方法,算法性能各有不同。Barron等人對(duì)多種光流計(jì)算技術(shù)進(jìn)行了總結(jié),按照理論基礎(chǔ)與數(shù)學(xué)方法的區(qū)別把它們分成四種:基于梯度的方法、基于匹配的方法、基于能量的方法、基于相位的方法。近年來神經(jīng)動(dòng)力學(xué)方法也頗受學(xué)者重視。
IJCV2011有一篇文章,《A Database and Evaluation Methodology for Optical Flow》里面對(duì)主流的光流算法做了簡要的介紹和對(duì)不同算法進(jìn)行了評(píng)估。網(wǎng)址是:http://vision.middlebury.edu/flow/
感覺這個(gè)文章在光流算法的解說上非常好,條例很清晰。想了解光流的,推薦看這篇文章。另外,需要提到的一個(gè)問題是,光流場(chǎng)是圖片中每個(gè)像素都有一個(gè)x方向和y方向的位移,所以在上面那些光流計(jì)算結(jié)束后得到的光流flow是個(gè)和原來圖像大小相等的雙通道圖像。那怎么可視化呢?這篇文章用的是Munsell顏色系統(tǒng)來顯示。
博文后面還介紹了孟塞爾顏色系統(tǒng),及光流法在OpenCV中的使用示例
這篇博文寫得很好,很清楚,不過就是相關(guān)理論介紹的少了點(diǎn),有關(guān)理論可以參考 http://www.cnblogs.com/gnuhpc/archive/2012/12/04/2802124.html ? :
圖像約束方程可以寫為I(x,y,z,t) = I(x+δx,y+δy,z+δz,t+δt),I(x,y,z,t)為在(x,y,z)位置的體素。我們假設(shè)移動(dòng)足夠的小,那么對(duì)圖像約束方程使用泰勒公式,我們可以得到:
H.O.T. 指更高階,在移動(dòng)足夠小的情況下可以忽略。從這個(gè)方程中我們可以得到:
或者
最終得到
Vx,Vy,Vz分別是I(x,y,z,t)的光流向量中x,y,z的組成。三個(gè)偏微分則是圖像在(x,y,z,t)這一點(diǎn)上相應(yīng)方向的差分。
所以
Ix*Vx + Iy*Vy + Iz*Vz = ?It
即
基于此公式,可以推導(dǎo)出 Lucas–Kanade光流算法 ,詳細(xì)見博文。
?
在Matlab中也有相關(guān)函數(shù)可以實(shí)現(xiàn)光流法,在機(jī)器視覺工具箱中它被封裝成了一個(gè)類,使用方便。這里簡單測(cè)試一下,看代碼:
% 光流法測(cè)試--兩張圖片
clc
clear
close all
% 指定圖片
refimg = 'car0.png'; % 參考圖片
inputimg = 'car1.png'; % 供對(duì)比圖片
refimg = 'frame10.png'; % 參考圖片
inputimg = 'frame11.png'; % 供對(duì)比圖片
% 讀取圖片
Iref = imread(refimg);
Iinput = imread(inputimg);
if size(Iref, 3) == 3
Irefg = rgb2gray(Iref);
Iinputg = rgb2gray(Iinput);
else
Irefg = Iref;
Iinputg = Iinput;
end
% 創(chuàng)建光流對(duì)象及類型轉(zhuǎn)化對(duì)象
opticalFlow = vision.OpticalFlow('ReferenceFrameDelay', 1);
converter = vision.ImageDataTypeConverter;
% 修改光流對(duì)象的配置
opticalFlow.OutputValue = 'Horizontal and vertical components in complex form'; % 返回復(fù)數(shù)形式光流圖
opticalFlow.ReferenceFrameSource = 'Input port'; % 對(duì)比兩張圖片,而不是視頻流
if 1 % 使用的算法
opticalFlow.Method = 'Lucas-Kanade';
opticalFlow.NoiseReductionThreshold = 0.001; % 默認(rèn)是0.0039
else
opticalFlow.Method = 'Horn-Schunck';
opticalFlow.Smoothness = 0.5; % 默認(rèn)是1
end
% 調(diào)用光流對(duì)象計(jì)算兩張圖片的光流
Iinputg_c = step(converter, Iinputg);
Irefg_c = step(converter, Irefg);
of = step(opticalFlow, Iinputg_c, Irefg_c);
ofH = real(of);
ofV = imag(of);
% 將光流轉(zhuǎn)化為彩色圖顯示
ofI = computeColor(ofH, ofV);
% 顯示結(jié)果
figure
subplot(221)
imshow(Iref)
subplot(222)
imshow(Iinput)
subplot(223)
imshow(ofH, [])
subplot(224)
imshow(ofV, [])
figure
imshow(ofI)
程序中的測(cè)試圖片可以從http://vision.middlebury.edu/flow/? ,這個(gè)網(wǎng)站提供了供光流法測(cè)試的很多測(cè)試圖片,方便研究這方面算法的人對(duì)比效果,另外函數(shù)computeColor是將光流法結(jié)果轉(zhuǎn)化為彩色圖顯示,代碼也在這個(gè)網(wǎng)站中。運(yùn)行程序結(jié)果如下
光流法常用在視頻對(duì)象跟蹤中,matlab中提供了例子,這里我稍作整理,換用了不同的顯示方式:
% 光流法測(cè)試--視頻
clc
clear
close all
% 讀取文件對(duì)象
videoReader = vision.VideoFileReader('viptraffic.avi','ImageColorSpace','Intensity','VideoOutputDataType','uint8');
% 類型轉(zhuǎn)化對(duì)象
converter = vision.ImageDataTypeConverter;
% 光流對(duì)象
opticalFlow = vision.OpticalFlow('ReferenceFrameDelay', 1);
opticalFlow.OutputValue = 'Horizontal and vertical components in complex form';
if 0 % 使用的算法
opticalFlow.Method = 'Lucas-Kanade';
opticalFlow.NoiseReductionThreshold = 0.001; % 默認(rèn)是0.0039
else
opticalFlow.Method = 'Horn-Schunck';
opticalFlow.Smoothness = 0.5; % 默認(rèn)是1
end
% 顯示對(duì)象
frame = step(videoReader);
figure
subplot(121)
himg = imshow(frame);
subplot(122)
hof = imshow(frame);
% 開始播放
while ~isDone(videoReader)
% 得到一幀
frame = step(videoReader);
% 格式轉(zhuǎn)化
im = step(converter, frame);
% 計(jì)算光流
of = step(opticalFlow, im);
% 光流圖轉(zhuǎn)化
ofI = computeColor(real(of), imag(of));
% 顯示
set(himg, 'cdata', frame)
set(hof, 'cdata', ofI)
drawnow
end
release(videoReader);
運(yùn)行程序結(jié)果如下
? ? ? Matlab幫助中有對(duì)光流法理論的介紹,簡潔明了,有時(shí)間翻譯一下。 from:?http://chunqiu.blog.ustc.edu.cn/?p=661 《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀
總結(jié)
以上是生活随笔為你收集整理的光流法 Optical Flow的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GitHub上一些有用的Reposito
- 下一篇: Matlab制作个人主页