opencv--光流跟踪

对象跟踪三要素:图像表示,外观模型,移动模型

    KLT(Lucas Kanade Tracker)条件:亮度恒定,近距离移动,空间一致性

稀疏光流:Sparse Optical Flow

    找到特征点: 角点检测法

代码:

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

Mat frame,gray;
Mat prev_frame,prev_gray;
vector<Point2f> features;
vector<Point2f> iniPoints;
vector<Point2f> fpts[2];
vector<uchar> status;
vector<float> errors;

//void drawFeature(Mat &inFrame)
//{
//	for(size_t t = 0;t < features.size();t++)
//	{
//		circle(inFrame,features[t],2, Scalar(0,0,255),2,8,0);	
//	}
//}
void drawFeature(Mat &inFrame)
{
	for(size_t t = 0;t < fpts[0].size();t++)
	{
		//画圆点
		circle(inFrame,fpts[0][t],2, Scalar(0,0,255),2,8,0);	
	}
}
void detectFeatures(Mat &inFrame,Mat &ingray)
{
	double MaxCorners = 5000;
	double qualitylevel = 0.01;
	double minDistance = 10;
	double blockSize = 3;
	double k= 0.04;
	//特征跟踪
	goodFeaturesToTrack(ingray,features,MaxCorners,qualitylevel,minDistance,Mat(),blockSize,false,k);
	printf("[%s][%d]detect features:%d\n",__FUNCTION__,__LINE__,features.size());

}
void drawTrackLines()
{
	for(size_t t = 0;t < fpts[1].size();t++)
	{
		line(frame,iniPoints[t],fpts[1][t],Scalar(0,255,0),2,8,0);
		circle(frame,fpts[1][t],2, Scalar(0,0,255),2,8,0);	
	}
}

void klTrackFeature()
{
	calcOpticalFlowPyrLK(prev_gray,gray,fpts[0],fpts[1],status,errors);
	int k = 0;
	for(int i=0; i<fpts[1].size();i++)
	{
		double dist =abs(fpts[0][i].x - fpts[1][i].x) + abs(fpts[0][i].y -fpts[1][i].y);
		if(dist > 2 && status[i])
		{
			iniPoints[k] = iniPoints[i];
			fpts[1][k++] =  fpts[1][i];
		}
	}
	iniPoints.resize(k);
	fpts[1].resize(k);
	drawTrackLines();
	std::swap(fpts[1],fpts[0]);
}
int main(int argc, char** argv)
{
	VideoCapture capture(0);
	//capture.open("./video/bike.avi");
	//capture.open("./video/video_006.mp4");
	//VideoCapture capture(0);
	if(!capture.isOpened())
	{
		printf("[%s][%d]could not load video data...\n",__FUNCTION__,__LINE__);
		return -1;
	}
	while(capture.read(frame))
	{
		//转化为灰度图像
		cvtColor(frame,gray,COLOR_BGR2GRAY);
		if(fpts[0].size()<40)
		{
			detectFeatures(frame,gray);
			fpts[0].insert(fpts[0].end(),features.begin(),features.end());
			iniPoints.insert(iniPoints.end(),features.begin(),features.end());
		}
		else
		{
			printf("TTTTTTTTTTTTT\n");
		}
		if(prev_gray.empty())
		{
			gray.copyTo(prev_gray);
		}
		klTrackFeature();
		drawFeature(frame);

		//保存上一针的图像
		gray.copyTo(prev_gray);
		frame.copyTo(prev_frame);
		imshow("input",frame);

		if(waitKey(33) == 27)
		{
			break;
		}
	}
	capture.release();
	waitKey(0);
	return 0;
}

稠密光流:Dense Optical Flow

相关函数:

    calcOpticalFlowFarneback() 稠密光流

代码:

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;
void drawOpticalFlowHF(Mat &flowdata, Mat &image,int step)
{
	for(int row = 0;row <image.rows;row++)
	{
		for(int col = 0;col<image.cols;col++)
		{
			const Point2f fxy = flowdata.at<Point2f>(row, col);
			if(fxy.x >2||fxy.y >2)
			{
				line(image,Point(col,row),Point(cvRound(col+fxy.x),cvRound(row+fxy.y)),Scalar(0,255,0),2,8,0);
				circle(image,Point(col,row),2,Scalar(0,0,255),-1);
			}
		}
	}
}
int main(int argc, char** argv)
{
#if 1
	VideoCapture capture;
	//capture.open("./video/bike.avi");
	capture.open("./video/video_003.avi");
	//capture.open("./video/video_006.mp4");
#else
	VideoCapture capture(0);
#endif
	if(!capture.isOpened())
	{
		printf("[%s][%d]could not load video data...\n",__FUNCTION__,__LINE__);
		return -1;
	}
	Mat frame,gray;
	Mat prev_frame,prev_gray;
	Mat flowResult,flowdata;//光流的结果,以及数据
	capture.read(frame);
	imshow("input1",frame);
	cvtColor(frame,prev_gray,COLOR_BGR2GRAY);

	while(capture.read(frame))
	{
		cvtColor(frame,gray,COLOR_BGR2GRAY);
		if(!prev_gray.empty())
		{
			calcOpticalFlowFarneback(prev_gray,gray,flowdata,0.5,3,15,3,5,1.2,0);
			cvtColor(prev_gray,flowResult,COLOR_GRAY2BGR);
			drawOpticalFlowHF(flowdata,flowResult,1);
			imshow("flow",flowResult);
			imshow("input",frame);
		}

		if(waitKey(33) == 27)
		{
			break;
		}
	}
	capture.release();
	waitKey(0);
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值