Opencv光流運(yùn)動物體追蹤詳解
光流的概念是由一個(gè)叫Gibson的哥們在1950年提出來的。它描述是空間運(yùn)動物體在觀察成像平面上的像素運(yùn)動的瞬時(shí)速度,利用圖像序列中像素在時(shí)間域上的變化以及相鄰幀之間的相關(guān)性來找到上一幀跟當(dāng)前幀之間存在的對應(yīng)關(guān)系,從而計(jì)算出相鄰幀之間物體的運(yùn)動信息的一種方法。那么所說的光流到底是什么?

簡單來說,上圖表現(xiàn)的就是光流,光流描述的是圖像上每個(gè)像素點(diǎn)的灰度的位置(速度)變化情況,光流的研究是利用圖像序列中的像素強(qiáng)度數(shù)據(jù)的時(shí)域變化和相關(guān)性來確定各自像素位置的“運(yùn)動”。研究光流場的目的就是為了從圖片序列中近似得到不能直接得到的運(yùn)動場。
光流法的前提假設(shè):
(1)相鄰幀之間的亮度恒定;
(2)相鄰視頻幀的取幀時(shí)間連續(xù),或者,相鄰幀之間物體的運(yùn)動比較“微小”;
(3)保持空間一致性;即,同一子圖像的像素點(diǎn)具有相同的運(yùn)動;
Opencv中金字塔LK光流實(shí)現(xiàn):
#include "highgui/highgui.hpp"
#include "opencv2/nonfree/nonfree.hpp"
#include "opencv2/video/tracking.hpp"
#include <iostream>
using namespace cv;
using namespace std;
Mat image1,image2;
vector<Point2f> point1,point2,pointCopy;
vector<uchar> status;
vector<float> err;
int main(int argc,char *argv[])
{
VideoCapture video(argv[1]);
double fps=video.get(CV_CAP_PROP_FPS); //獲取視頻幀率
double pauseTime=1000/fps; //兩幅畫面中間間隔
video>>image1;
Mat image1Gray,image2Gray;
cvtColor(image1,image1Gray,CV_RGB2GRAY);
goodFeaturesToTrack(image1Gray,point1,100,0.01,10,Mat());
pointCopy=point1;
for(int i=0;i<point1.size();i++) //繪制特征點(diǎn)位
{
circle(image1,point1[i],1,Scalar(0,0,255),2);
}
namedWindow("角點(diǎn)特征光流",0);
imshow("角點(diǎn)特征光流",image1);
while(true)
{
video>>image2;
if(!image2.data||waitKey(pauseTime)==27) //圖像為空或Esc鍵按下退出播放
{
break;
}
cvtColor(image2,image2Gray,CV_RGB2GRAY);
calcOpticalFlowPyrLK(image1Gray,image2Gray,point1,point2,status,err,Size(20,20),3); //LK金字塔
for(int i=0;i<point2.size();i++)
{
circle(image2,point2[i],1,Scalar(0,0,255),2);
line(image2,pointCopy[i],point2[i],Scalar(255,0,0),2);
}
imshow("角點(diǎn)特征光流",image2);
swap(point1,point2);
image1Gray=image2Gray.clone();
}
return 0;
}
圖像跟蹤結(jié)果1:

圖像跟蹤結(jié)果2:

視頻流跟蹤:

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++實(shí)現(xiàn)批量提取PDF內(nèi)容
這篇文章主要為大家詳細(xì)介紹了如何使用C++批量提取PDF里文字內(nèi)容并導(dǎo)出到表格以及批量給?PDF?文件改名,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-02-02

