日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Optical_Flow(4)

發布時間:2023/12/15 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Optical_Flow(4) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

申明:本文非筆者原創,原文轉載自:http://blog.csdn.NET/crzy_sparrow/article/details/7407604


本文目錄:

????? 一.基于特征點的目標跟蹤的一般方法

????? 二.光流法

????? 三.OpenCV中的光流法函數

??? ? 四.用類封裝基于光流法的目標跟蹤方法

????? 五.完整代碼

????? 六.參考文獻


一.基于特征點的目標跟蹤的一般方法

????? 基于特征點的跟蹤算法大致可以分為兩個步驟:

????? 1)探測當前幀的特征點;

????? 2)通過當前幀和下一幀灰度比較,估計當前幀特征點在下一幀的位置;

????? 3)過濾位置不變的特征點,余下的點就是目標了。

????? 很顯然,基于特征點的目標跟蹤算法和1),2)兩個步驟有關。特征點可以是Harris角點(見我的另外一篇博文),也可以是邊緣點等等,而估計下一幀位置的方法也有不少,比如這里要講的光流法,也可以是卡爾曼濾波法(咱是控制系的,上課經常遇到這個,所以看光流法看著看著就想到這個了)。

????? 本文中,用改進的Harris角點提取特征點(見我另一篇博文:http://blog.csdn.Net/crzy_sparrow/article/details/7391511),用Lucas-Kanade光流法實現目標跟蹤。


二.光流法

????? 這一部分《learing opencv》一書的第10章Lucas-Kanade光流部分寫得非常詳細,推薦大家看書。我這里也粘帖一些選自書中的內容。

????? 另外我對這一部分附上一些個人的看法(謬誤之處還望不吝指正):

????? 1.首先是假設條件:

?? ??? (1)亮度恒定,就是同一點隨著時間的變化,其亮度不會發生改變。這是基本光流法的假定(所有光流法變種都必須滿足),用于得到光流法基本方程;

?????? (2)小運動,這個也必須滿足,就是時間的變化不會引起位置的劇烈變化,這樣灰度才能對位置求偏導(換句話說,小運動情況下我們才能用前后幀之間單位位置變化引起的灰度變化去近似灰度對位置的偏導數),這也是光流法不可或缺的假定;

?????? (3)空間一致,一個場景上鄰近的點投影到圖像上也是鄰近點,且鄰近點速度一致。這是Lucas-Kanade光流法特有的假定,因為光流法基本方程約束只有一個,而要求x,y方向的速度,有兩個未知變量。我們假定特征點鄰域內做相似運動,就可以連立n多個方程求取x,y方向的速度(n為特征點鄰域總點數,包括該特征點)。

????? 2.方程求解

????? 多個方程求兩個未知變量,又是線性方程,很容易就想到用最小二乘法,事實上opencv也是這么做的。其中,最小誤差平方和為最優化指標。

????? 3.好吧,前面說到了小運動這個假定,聰明的你肯定很不爽了,目標速度很快那這貨不是二掉了。幸運的是多尺度能解決這個問題。首先,對每一幀建立一個高斯金字塔,最大尺度圖片在最頂層,原始圖片在底層。然后,從頂層開始估計下一幀所在位置,作為下一層的初始位置,沿著金字塔向下搜索,重復估計動作,直到到達金字塔的底層。聰明的你肯定發現了:這樣搜索不僅可以解決大運動目標跟蹤,也可以一定程度上解決孔徑問題(相同大小的窗口能覆蓋大尺度圖片上盡量多的角點,而這些角點無法在原始圖片上被覆蓋)。




三.opencv中的光流法函數

????? opencv2.3.1中已經實現了基于光流法的特征點位置估計函數(當前幀位置已知,前后幀灰度已知),介紹如下(摘自opencv2.3.1參考手冊):

[cpp]?view plaincopy
  • calcOpticalFlowPyrLK??
  • Calculates?an?optical?flow?for?a?sparse?feature?set?using?the?iterative?Lucas-Kanade?method?with?pyramids.??
  • ??
  • void?calcOpticalFlowPyrLK(InputArray?prevImg,?InputArray?nextImg,?InputArray?prevPts,??
  • InputOutputArray?nextPts,?OutputArray?status,?OutputArray?err,??
  • Size?winSize=Size(15,15),?int?maxLevel=3,?TermCriteria?crite-??
  • ria=TermCriteria(TermCriteria::COUNT+TermCriteria::EPS,?30,?0.01),??
  • double?derivLambda=0.5,?int?flags=0?)??
  • ??
  • Parameters??
  • prevImg?–?First?8-bit?single-channel?or?3-channel?input?image.??
  • nextImg?–?Second?input?image?of?the?same?size?and?the?same?type?as?prevImg?.??
  • prevPts?–?Vector?of?2D?points?for?which?the?flow?needs?to?be?found.?The?point?coordinates??
  • must?be?single-precision?floating-point?numbers.??
  • nextPts?–?Output?vector?of?2D?points?(with?single-precision?floating-point?coordinates)??
  • containing?the?calculated?new?positions?of?input?features?in?the?second?image.?When??
  • OPTFLOW_USE_INITIAL_FLOW?flag?is?passed,?the?vector?must?have?the?same?size?as?in?the??
  • input.??
  • status?–?Output?status?vector.?Each?element?of?the?vector?is?set?to?1?if?the?flow?for?the??
  • corresponding?features?has?been?found.?Otherwise,?it?is?set?to?0.??
  • err?–?Output?vector?that?contains?the?difference?between?patches?around?the?original?and??
  • moved?points.??
  • winSize?–?Size?of?the?search?window?at?each?pyramid?level.??
  • ??
  • maxLevel?–?0-based?maximal?pyramid?level?number.?If?set?to?0,?pyramids?are?not?used??
  • (single?level).?If?set?to?1,?two?levels?are?used,?and?so?on.??
  • criteria?–?Parameter?specifying?the?termination?criteria?of?the?iterative?search?algorithm??
  • (after?the?specified?maximum?number?of?iterations?criteria.maxCount?or?when?the?search??
  • window?moves?by?less?than?criteria.epsilon?.??
  • derivLambda?–?Not?used.??
  • ??
  • flags?–?Operation?flags:??
  • –?OPTFLOW_USE_INITIAL_FLOW?Use?initial?estimations?stored?in?nextPts?.?If?the??
  • flag?is?not?set,?then?prevPts?is?copied?to?nextPts?and?is?considered?as?the?initial?estimate.??

  • 四.用類封裝基于光流法的目標跟蹤方法

    ????? 廢話少說,附上代碼,包括特征點提取,跟蹤特征點,標記特征點等。

    [cpp]?view plaincopy
  • <span?style="font-size:18px;">//幀處理基類??
  • class?FrameProcessor{??
  • ????public:??
  • ????????virtual?void?process(Mat?&input,Mat?&ouput)=0;??
  • };??
  • ??
  • //特征跟蹤類,繼承自幀處理基類??
  • class?FeatureTracker?:??public?FrameProcessor{??
  • ????Mat?gray;??//當前灰度圖??
  • ????Mat?gray_prev;??//之前的灰度圖??
  • ????vector<Point2f>?points[2];//前后兩幀的特征點??
  • ????vector<Point2f>?initial;//初始特征點??
  • ????vector<Point2f>?features;//檢測到的特征??
  • ????int?max_count;?//要跟蹤特征的最大數目??
  • ????double?qlevel;?//特征檢測的指標??
  • ????double?minDist;//特征點之間最小容忍距離??
  • ????vector<uchar>?status;?//特征點被成功跟蹤的標志??
  • ????vector<float>?err;?//跟蹤時的特征點小區域誤差和??
  • public:??
  • ????FeatureTracker():max_count(500),qlevel(0.01),minDist(10.){}??
  • ????void?process(Mat?&frame,Mat?&output){??
  • ????????//得到灰度圖??
  • ????????cvtColor?(frame,gray,CV_BGR2GRAY);??
  • ????????frame.copyTo?(output);??
  • ????????//特征點太少了,重新檢測特征點??
  • ????????if(addNewPoint()){??
  • ????????????detectFeaturePoint?();??
  • ????????????//插入檢測到的特征點??
  • ????????????points[0].insert?(points[0].end?(),features.begin?(),features.end?());??
  • ????????????initial.insert?(initial.end?(),features.begin?(),features.end?());??
  • ????????}??
  • ????????//第一幀??
  • ????????if(gray_prev.empty?()){??
  • ????????????????gray.copyTo?(gray_prev);??
  • ????????}??
  • ????????//根據前后兩幀灰度圖估計前一幀特征點在當前幀的位置??
  • ????????//默認窗口是15*15??
  • ????????calcOpticalFlowPyrLK?(??
  • ????????????????gray_prev,//前一幀灰度圖??
  • ????????????????gray,//當前幀灰度圖??
  • ????????????????points[0],//前一幀特征點位置??
  • ????????????????points[1],//當前幀特征點位置??
  • ????????????????status,//特征點被成功跟蹤的標志??
  • ????????????????err);//前一幀特征點點小區域和當前特征點小區域間的差,根據差的大小可刪除那些運動變化劇烈的點??
  • ????????int?k?=?0;??
  • ????????//去除那些未移動的特征點??
  • ????????for(int?i=0;i<points[1].size?();i++){??
  • ????????????if(acceptTrackedPoint?(i)){??
  • ????????????????initial[k]=initial[i];??
  • ????????????????points[1][k++]?=?points[1][i];??
  • ????????????}??
  • ????????}??
  • ????????points[1].resize?(k);??
  • ????????initial.resize?(k);??
  • ????????//標記被跟蹤的特征點??
  • ????????handleTrackedPoint?(frame,output);??
  • ????????//為下一幀跟蹤初始化特征點集和灰度圖像??
  • ????????std::swap(points[1],points[0]);??
  • ????????cv::swap(gray_prev,gray);??
  • ????}??
  • ??
  • ????void?detectFeaturePoint(){??
  • ????????goodFeaturesToTrack?(gray,//輸入圖片??
  • ?????????????????????????????????features,//輸出特征點??
  • ?????????????????????????????????max_count,//特征點最大數目??
  • ?????????????????????????????????qlevel,//質量指標??
  • ?????????????????????????????????minDist);//最小容忍距離??
  • ????}??
  • ????bool?addNewPoint(){??
  • ????????//若特征點數目少于10,則決定添加特征點??
  • ????????return?points[0].size?()<=10;??
  • ????}??
  • ??
  • ????//若特征點在前后兩幀移動了,則認為該點是目標點,且可被跟蹤??
  • ????bool?acceptTrackedPoint(int?i){??
  • ????????return?status[i]&&??
  • ????????????????(abs(points[0][i].x-points[1][i].x)+??
  • ??????????????????abs(points[0][i].y-points[1][i].y)?>2);??
  • ????}??
  • ??
  • ????//畫特征點??
  • ????void??handleTrackedPoint(Mat?&frame,Mat?&output){??
  • ????????????for(int?i=0;i<points[i].size?();i++){??
  • ????????????????//當前特征點到初始位置用直線表示??
  • ????????????????line(output,initial[i],points[1][i],Scalar::all?(0));??
  • ????????????????//當前位置用圈標出??
  • ????????????????circle(output,points[1][i],3,Scalar::all(0),(-1));??
  • ????????????}??
  • ????????}??
  • };</span>??

  • 五.完整代碼
    ? 完整的運行代碼有300+行,粘上來太多了,大家去我傳的資源里下載吧。

    ? 下載地址:http://download.csdn.net/detail/crzy_sparrow/4183674

    ? 運行結果:



    六.參考文獻

    【1】The classic article by B. Lucas and T. Kanade, An iterative image registration technique with an application to stereo vision in Int. Joint Conference in Artificial Intelligence, pp. 674-679,1981, that describes the original feature point tracking algorithm.
    【2】The article by J. Shi and C. Tomasi, Good Features to Track in IEEE Conference on Computer Vision and Pattern Recognition, pp. 593-600, 1994, that describes an improved version of the original feature point tracking algorithm.

    總結

    以上是生活随笔為你收集整理的Optical_Flow(4)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。