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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > windows >内容正文

windows

OpenCV学习笔记(三十六)——Kalman滤波做运动目标跟踪 OpenCV学习笔记(三十七)——实用函数、系统函数、宏core OpenCV学习笔记(三十八)——显示当前FPS OpenC

發(fā)布時(shí)間:2025/3/21 windows 43 豆豆

OpenCV學(xué)習(xí)筆記(三十六)——Kalman濾波做運(yùn)動(dòng)目標(biāo)跟蹤??

kalman濾波大家都很熟悉,其基本思想就是先不考慮輸入信號(hào)和觀測(cè)噪聲的影響,得到狀態(tài)變量和輸出信號(hào)的估計(jì)值,再用輸出信號(hào)的估計(jì)誤差加權(quán)后校正狀態(tài)變量的估計(jì)值,使?fàn)顟B(tài)變量估計(jì)誤差的均方差最小。具體它的原理和實(shí)現(xiàn),我想也不用我在這里費(fèi)口舌,但這個(gè)理論基礎(chǔ)必須的有,必須得知道想用kalman濾波做跟蹤,必須得先建立運(yùn)動(dòng)模型和觀察模型,不是想用就能用的。如果不能建立運(yùn)動(dòng)模型,也就意味著你所要面對(duì)的問(wèn)題不能用kalman濾波解決。

我結(jié)合一下OpenCV自帶的kalman.cpp這個(gè)例程來(lái)介紹一下如何在OpenCV中使用kalman濾波吧,OpenCV已經(jīng)把Kalman濾波封裝到一個(gè)類KalmanFilter中了。使用起來(lái)非常方便,但那繁多的各種矩陣還是容易讓人摸不著頭腦。這里要知道的一點(diǎn)是,想要用kalman濾波,要知道前一時(shí)刻的狀態(tài)估計(jì)值x,當(dāng)前的觀測(cè)值y,還得建立狀態(tài)方程和量測(cè)方程。有了這些就可以運(yùn)用kalman濾波了。

OpenCV自帶了例程里面是對(duì)一個(gè)1維點(diǎn)的運(yùn)動(dòng)跟蹤,雖然這個(gè)點(diǎn)是在2維平面中運(yùn)動(dòng),但由于它是在一個(gè)圓弧上運(yùn)動(dòng),只有一個(gè)自由度,角度,所以還是1維的。還是一個(gè)勻速運(yùn)動(dòng),建立勻速運(yùn)動(dòng)模型,設(shè)定狀態(tài)變量x = [ x1, x2 ] = [ 角度,角速度 ],則運(yùn)動(dòng)模型為

x1(k+1) = x1(k)+x2(k)*T

x2(k+1)= x2(k)

則狀態(tài)轉(zhuǎn)移方程為

x* = Ax + w

這里設(shè)計(jì)的噪聲是高斯隨機(jī)噪聲,則量測(cè)方程為:

z = Cx + v

看了代碼,對(duì)應(yīng)上以上各項(xiàng):

狀態(tài)估計(jì)值x --> state

當(dāng)前觀測(cè)值z(mì) -->?measurement

KalmanFilter類內(nèi)成員變量transitionMatrix就是狀態(tài)轉(zhuǎn)移方程中的矩陣A

KalmanFilter類內(nèi)成員變量measurementMatrix就是量測(cè)方程中矩陣C

[cpp] view plain copy
  • Mat?statePre;???????????//!<?predicted?state?(x'(k)):?x(k)=A*x(k-1)+B*u(k)??
  • Mat?statePost;??????????//!<?corrected?state?(x(k)):?x(k)=x'(k)+K(k)*(z(k)-H*x'(k))??
  • Mat?transitionMatrix;???//!<?state?transition?matrix?(A)??
  • Mat?controlMatrix;??????//!<?control?matrix?(B)?(not?used?if?there?is?no?control)??
  • Mat?measurementMatrix;??//!<?measurement?matrix?(H)??
  • Mat?processNoiseCov;????//!<?process?noise?covariance?matrix?(Q)??
  • Mat?measurementNoiseCov;//!<?measurement?noise?covariance?matrix?(R)??
  • Mat?errorCovPre;????????//!<?priori?error?estimate?covariance?matrix?(P'(k)):?P'(k)=A*P(k-1)*At?+?Q)*/??
  • Mat?gain;???????????????//!<?Kalman?gain?matrix?(K(k)):?K(k)=P'(k)*Ht*inv(H*P'(k)*Ht+R)??
  • Mat?errorCovPost;???????//!<?posteriori?error?estimate?covariance?matrix?(P(k)):?P(k)=(I-K(k)*H)*P'(k)??

  • 我想就不用我再翻譯了吧。相信有了以上的注釋,大家都能找到它們的對(duì)應(yīng)項(xiàng)。

    使用的時(shí)候,除了初始化我剛剛初始化過(guò)的transitionMatrix和measurementMatrix外,還需要初始化processNoiseCov,measurementNoiseCov和errorCovPost

    把它們初始化好之后,接下來(lái)的動(dòng)作就很簡(jiǎn)單了,分兩步走,第一步調(diào)用成員函數(shù)predict得到當(dāng)前狀態(tài)變量的估計(jì)值,第二步調(diào)用成員函數(shù)correct用觀測(cè)值校正狀態(tài)變量。再更新?tīng)顟B(tài)變量做下一次估計(jì)。聽(tīng)著好簡(jiǎn)單啊,代碼就不上傳坑爹了,在opencv2.3.1\samples\cpp\kalman.cpp中其義自見(jiàn)。



    OpenCV學(xué)習(xí)筆記(三十七)——實(shí)用函數(shù)、系統(tǒng)函數(shù)、宏core

    如果你想在OpenCV的基礎(chǔ)上自己開(kāi)發(fā)一些算法,我覺(jué)得core這部分內(nèi)容不得不精啊,能熟練使用OpenCV的數(shù)據(jù)結(jié)構(gòu)是開(kāi)發(fā)的基礎(chǔ),又是重中之重。最近就又拌在這上頭了,所以再重溫一下。這次分析一下Utility and System Functions and Macros這部分,就是實(shí)用函數(shù)、系統(tǒng)函數(shù)和宏。

    OpenCV在這部分里包含一些類似標(biāo)準(zhǔn)c++、c里面的一些東西。

    系統(tǒng)函數(shù)有很多。有些是內(nèi)存方面的操作,類似new delete之類的操作,很多都是為了防止內(nèi)存溢出的函數(shù)有alignPtr、alignSize、allocate、deallocate、fastMalloc、fastFree。格式輸出的函數(shù)啦format(是不是太熟悉了)。還有一些和系統(tǒng)相關(guān)的東西checkHardwareSupport、getNumThreads、getThreadNum、getTickCount、getTickFrequency、getCPUTickCount、setNumThreads。還有一些比較有意思的東西,比如功能類似#ifdef #endf這樣的開(kāi)關(guān),也有函數(shù)setUseOptimized實(shí)現(xiàn) ,相關(guān)的還有useOptimized函數(shù)。還有一個(gè)不懂的函數(shù)saturate_cast(求指點(diǎn))等待各位補(bǔ)充。

    實(shí)用函數(shù)很接近<math.h>里的一些函數(shù),很有意思,可以方便大家開(kāi)發(fā),有計(jì)算向量角度的函數(shù)fastAtan2、計(jì)算立方根的函數(shù)cubeRoot、向上取整函數(shù)cvCeil、向下取整函數(shù)cvFloor、四舍五入函數(shù)cvRound。注意cvCeil、cvFloor、cvRound和大家常用的ceil、floor、round函數(shù)略有不同,標(biāo)準(zhǔn)庫(kù)函數(shù)返回值并不是int型的變量,必要時(shí)需強(qiáng)制轉(zhuǎn)換,而OpenCV里面的取整函數(shù)返回值為int型。還有一些類似matlab里面的函數(shù),比如cvIsInf判斷自變量是否無(wú)窮大,cvIsNaN判斷自變量是否Not a Number。

    宏也很多,這些宏在標(biāo)準(zhǔn)c++、c里也有出現(xiàn),CV_Assert是個(gè)斷言,不知道和assert()有什么區(qū)別。error也是一種異常,還有Exception類這個(gè)異常類。

    有了這些東西,開(kāi)發(fā)起來(lái)有沒(méi)有更順手一些呢~~隨著使用的深入,我會(huì)再補(bǔ)充一些上訴東西的使用心得



    OpenCV學(xué)習(xí)筆記(三十八)——顯示當(dāng)前FPS?

    最近做一個(gè)東西,需要實(shí)時(shí)顯示,于是想在屏幕顯示FPS。FPS是Frame Per Second的縮寫(xiě),中文意思是每秒幀數(shù),即幀速。FPS是測(cè)量用于保存、顯示動(dòng)態(tài)視頻的信息數(shù)量。通俗來(lái)講就是指動(dòng)畫(huà)或視頻的畫(huà)面數(shù)。

    這就需要我在系統(tǒng)函數(shù)一講里提到的getTickCount、getTickFrequency這兩個(gè)函數(shù)了。前一個(gè)函數(shù)返回tick次數(shù),后一個(gè)函數(shù)返回每秒tick次數(shù),它們的比就是時(shí)間咯。

    如果想得到一段程序的運(yùn)行時(shí)間,可以套用下面的例子:

    [cpp] view plain copy
  • double?t?=?(double)getTickCount();??
  • //?do?something?...??
  • t?=?((double)getTickCount()?-?t)/getTickFrequency();??

  • 以上這段程序在測(cè)試算法的時(shí)間消耗在哪里是很好的測(cè)試程序。我這里只需要稍微改寫(xiě)一下這個(gè)例子,得到每幀之間的時(shí)間,再用我之前在繪圖函數(shù)那節(jié)講過(guò)的putText把FPS顯示到屏幕上咯。

    不過(guò)有個(gè)問(wèn)題還是讓我感覺(jué)不舒服,就是用它做的定時(shí)不是很準(zhǔn),感覺(jué)時(shí)間比實(shí)際的快一些。測(cè)試較少,也不敢亂講,歡迎大家測(cè)試并發(fā)表意見(jiàn)

    簡(jiǎn)單的很,源程序下載地址:http://download.csdn.net/detail/yang_xian521/3957523



    OpenCV學(xué)習(xí)筆記(三十九)——再談OpenCV的數(shù)據(jù)結(jié)構(gòu),Mat是如此強(qiáng)大?

    還是一個(gè)實(shí)時(shí)性要求的程序最近把我弄得有些上火。為了提高代碼運(yùn)行的速度,我也是又新啃東西學(xué)了。由于我代碼里使用了vector,網(wǎng)上搜來(lái)搜去有人說(shuō)vector慢,又有人說(shuō)STL里的sort排序速度是我等常人不能企及的,有人說(shuō)要少resize,這個(gè)重新分配內(nèi)存非常耗時(shí),又有人說(shuō)要用swap來(lái)徹底刪除不要的內(nèi)存空間。帶著這么多疑問(wèn),我實(shí)在不知道我程序慢的原因。于是乎閱讀了《Effective STL》,這書(shū)挺深的,粗淺讀讀,先把自己急著弄清楚的以上各問(wèn)題弄懂。再看程序,做了些優(yōu)化,速度還是提高不多,頭開(kāi)始大了

    我的解決辦法是用我上一講提到的getTickCount、getTickFrequency函數(shù)分析我代碼的運(yùn)行時(shí)間,遇到的問(wèn)題是下面這句非常耗時(shí)

    [cpp] view plain copy
  • vector<vector<int>>test?=?vector<vector<int>>(10000,?vector<int>(10,?0));??

  • 10000*10只是我要開(kāi)辟的空間,不知道怎么用reserve函數(shù)開(kāi)辟, 這句運(yùn)行了大概100ms。今天再看這段代碼,發(fā)現(xiàn)我太傻了,何必要用vector<vector<int>>呢,完全可以用OpenCV自帶的Mat來(lái)解決啊,于是把上面這句改寫(xiě)如下 [cpp] view plain copy
  • Mat?test1?=?Mat_<int>::zeros(10000,?10);??

  • 結(jié)果只需要0.2ms!!!同志們,STL在Mat面前都顯得如此無(wú)力啊,有木有啊!我決定花費(fèi)幾天的時(shí)間再好好讀讀reference的core的部分,來(lái)吃透OpenCV的數(shù)據(jù)結(jié)構(gòu)。而且感覺(jué)Mat跟STL的兼容性很好,也有push_back,pop_back這樣的操作,所以啊,同志們,千萬(wàn)別把Mat只當(dāng)做是顯示圖片用的,它是很強(qiáng)大的數(shù)據(jù)結(jié)構(gòu),用了它,可以事半功倍,誰(shuí)用誰(shuí)知道!~~


    OpenCV學(xué)習(xí)筆記(四十)——再談OpenCV數(shù)據(jù)結(jié)構(gòu)Mat詳解

    我記得開(kāi)始接觸OpenCV就是因?yàn)橐粋€(gè)算法里面需要2維動(dòng)態(tài)數(shù)組,那時(shí)候看core這部分也算是走馬觀花吧,隨著使用的增多,對(duì)Mat這個(gè)結(jié)構(gòu)越來(lái)越喜愛(ài),也覺(jué)得有必要溫故而知新,于是這次再看看Mat。

    Mat最大的優(yōu)勢(shì)跟STL很相似,都是對(duì)內(nèi)存進(jìn)行動(dòng)態(tài)的管理,不需要之前用戶手動(dòng)的管理內(nèi)存,對(duì)于一些大型的開(kāi)發(fā),有時(shí)候投入的lpImage內(nèi)存管理的時(shí)間甚至比關(guān)注算法實(shí)現(xiàn)的時(shí)間還要多,這顯然是不合適的。除了有些嵌入式場(chǎng)合必須使用c語(yǔ)言,我任何時(shí)候都強(qiáng)烈像大家推薦Mat。

    Mat這個(gè)類有兩部分?jǐn)?shù)據(jù)。一個(gè)是matrix header,這部分的大小是固定的,包含矩陣的大小,存儲(chǔ)的方式,矩陣存儲(chǔ)的地址等等。另一個(gè)部分是一個(gè)指向矩陣包含像素值的指針

    [cpp] view plain copy
  • Mat?A,?C;?//?creates?just?the?header?parts??
  • A?=?imread(argv[1],?CV_LOAD_IMAGE_COLOR);?//?here?we’ll?know?the?method?used?(allocate?matrix)??
  • Mat?B(A);?//?Use?the?copy?constructor??
  • C?=?A;?//?Assignment?operator??

  • 需要注意的是,copy這樣的操作只是copy了矩陣的matrix header和那個(gè)指針,而不是矩陣的本身,也就意味著兩個(gè)矩陣的數(shù)據(jù)指針指向的是同一個(gè)地址,需要開(kāi)發(fā)者格外注意。比如上面這段程序,A、B、C指向的是同一塊數(shù)據(jù),他們的header不同,但對(duì)于A的操作同樣也影響著B(niǎo)、C的結(jié)果。剛剛提高了內(nèi)存自動(dòng)釋放的問(wèn)題,那么當(dāng)我不再使用A的時(shí)候就把內(nèi)存釋放了,那時(shí)候再操作B和C豈不是很危險(xiǎn)。不用擔(dān)心,OpenCV的大神為我們已經(jīng)考慮了這個(gè)問(wèn)題,是在最后一個(gè)Mat不再使用的時(shí)候才會(huì)釋放內(nèi)存,咱們就放心用就行了。

    如果想建立互不影響的Mat,是真正的復(fù)制操作,需要使用函數(shù)clone()或者copyTo()

    說(shuō)到數(shù)據(jù)的存儲(chǔ),這一直就是一個(gè)值得關(guān)注的問(wèn)題,Mat_<uchar>對(duì)應(yīng)的是CV_8U,Mat_<uchar>對(duì)應(yīng)的是CV_8U,Mat_<char>對(duì)應(yīng)的是CV_8S,Mat_<int>對(duì)應(yīng)的是CV_32S,Mat_<float>對(duì)應(yīng)的是CV_32F,Mat_<double>對(duì)應(yīng)的是CV_64F,對(duì)應(yīng)的數(shù)據(jù)深度如下:

    ? CV_8U - 8-bit unsigned integers ( 0..255 )

    ? CV_8S - 8-bit signed integers ( -128..127 )

    ? CV_16U - 16-bit unsigned integers ( 0..65535 )

    ? CV_16S - 16-bit signed integers ( -32768..32767 )

    ? CV_32S - 32-bit signed integers ( -2147483648..2147483647 )

    ? CV_32F - 32-bit ?oating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN )

    ? CV_64F - 64-bit ?oating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN )

    這里還需要注意一個(gè)問(wèn)題,很多OpenCV的函數(shù)支持的數(shù)據(jù)深度只有8位和32位的,所以要少使用CV_64F,但是vs的編譯器又會(huì)把float數(shù)據(jù)自動(dòng)變成double型,有些不太爽。

    還有個(gè)需要注意的問(wèn)題,就是流操作符<<對(duì)于Mat的操作,僅限于Mat是2維的情況。

    還有必要說(shuō)一下Mat的存儲(chǔ)是逐行的存儲(chǔ)的。

    再說(shuō)說(shuō)Mat的創(chuàng)建,方式有兩種,羅列一下:1.調(diào)用create(行,列,類型)2.Mat(行,列,類型(值))。例如:

    [cpp] view plain copy
  • //?make?a?7x7?complex?matrix?filled?with?1+3j.??
  • Mat?M(7,7,CV_32FC2,Scalar(1,3));??
  • //?and?now?turn?M?to?a?100x60?15-channel?8-bit?matrix.??
  • //?The?old?content?will?be?deallocated??
  • M.create(100,60,CV_8UC(15));??

  • 要是想創(chuàng)建更高維的矩陣,要寫(xiě)成下面的方式
    [cpp] view plain copy
  • //?create?a?100x100x100?8-bit?array??
  • int?sz[]?=?{100,?100,?100};??
  • Mat?bigCube(3,?sz,?CV_8U,?Scalar::all(0));??

  • 對(duì)于矩陣的行操作或者列操作,方式如下:(注意對(duì)列操作時(shí)要新建一個(gè)Mat,我想應(yīng)該跟列地址不連續(xù)有關(guān)
    [cpp] view plain copy
  • //?add?the?5-th?row,?multiplied?by?3?to?the?3rd?row??
  • M.row(3)?=?M.row(3)?+?M.row(5)*3;??
  • //?now?copy?the?7-th?column?to?the?1-st?column??
  • //?M.col(1)?=?M.col(7);?//?this?will?not?work??
  • Mat?M1?=?M.col(1);??
  • M.col(7).copyTo(M1);??

  • 下面的東西就比較狂暴了,對(duì)于外來(lái)的數(shù)據(jù),比如你從別的地方接受了一幅圖片,但可以不是Mat結(jié)構(gòu)的,而只有一個(gè)數(shù)據(jù)的指針,看看接下來(lái)的代碼是如何應(yīng)付的,重點(diǎn)哦,親
    [cpp] view plain copy
  • void?process_video_frame(const?unsigned?char*?pixels,??
  • int?width,?int?height,?int?step)??
  • {??
  • Mat?img(height,?width,?CV_8UC3,?pixels,?step);??
  • GaussianBlur(img,?img,?Size(7,7),?1.5,?1.5);??
  • }??

  • 親,有木有很簡(jiǎn)單!!!

    還有一種快速初始化數(shù)據(jù)的辦法,如下:

    [cpp] view plain copy
  • double?m[3][3]?=?{{a,?b,?c},?{d,?e,?f},?{g,?h,?i}};??
  • Mat?M?=?Mat(3,?3,?CV_64F,?m).inv();??

  • 也可以把原來(lái)的IplImage格式的圖片直接用Mat(IplImage)的方式轉(zhuǎn)成Mat結(jié)構(gòu),也可以像Matlab一樣調(diào)用zeros()、ones()、eye()這樣的函數(shù)進(jìn)行初始化。

    如果你需要提前釋放數(shù)據(jù)的指針和內(nèi)存,可以調(diào)用release()。

    對(duì)于數(shù)據(jù)的獲取,當(dāng)然還是調(diào)用at<float>(3, 3)這樣的格式為最佳。其他的方法我甚少嘗試,就不敢介紹了。

    最后要提的一點(diǎn)是關(guān)于Mat的表達(dá)式,這個(gè)也非常多,加減乘除,轉(zhuǎn)置求逆,我怎么記得我以前介紹過(guò)呢。那就不多說(shuō)啦~


    from: http://blog.csdn.net/yang_xian521/article/category/910716

    總結(jié)

    以上是生活随笔為你收集整理的OpenCV学习笔记(三十六)——Kalman滤波做运动目标跟踪 OpenCV学习笔记(三十七)——实用函数、系统函数、宏core OpenCV学习笔记(三十八)——显示当前FPS OpenC的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。