超详细注释的基于opencv3的Optical flow(光流点追踪)

#include<opencv2/opencv.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
using namespace cv;
using namespace std;
void track(Mat& frame, Mat& result);
bool addNewPoint();
bool acceptTrackPoint(int i);
Mat curgray;//当前图片
Mat pregray;//先前图片
vector<Point2f> point[2];//point[0]是特征点的原来位置,point[1]是特征点的新位置
vector<Point2f> initpoint;//初始化跟踪点的位置
vector<Point> features;//检测到的特征点
int maxCounts=500;//检测的最大特征点数
double qLevel = 0.01;//检测特征的等级
double minDist = 10.0;//检测特征的最小距离
vector<uchar> status;//跟踪特征的状态,发现特征的流为1,否则为0
vector<float> err;//误差矢量
int main()
{
 Mat srcimage, dstimage;
 VideoCapture capture(0);
 while (capture.isOpened())
 {
  capture >> srcimage;
  if (!srcimage.data)
  {
   cerr << "Get picture error!" << endl;
   return 0;
  }
  else
  {
   track(srcimage, dstimage);
  }
  if(waitKey(1) == 27)
   return 0;
 }
 waitKey(0);
 system("pause");
 return 0;
}
void track(Mat& frame, Mat& result)
{
 cvtColor(frame, curgray, COLOR_BGR2GRAY);
 frame.copyTo(result);
 if (addNewPoint())
 {
  //确定图像强角点,并把角点存放在vector<Point2f>的features中
  goodFeaturesToTrack(curgray, features, maxCounts, qLevel, minDist);
  //把feature里的角点重头到尾存到point[0]的末尾中
  point[0].insert(point[0].end(), features.begin(), features.end());
  //把feature里的角点重头到尾存到initpoint的末尾中
  initpoint.insert(initpoint.end(), features.begin(), features.end());
 }
 if (pregray.empty())
 {
  curgray.copyTo(pregray);
 }
 //计算稀疏征集的光流
 calcOpticalFlowPyrLK(pregray, curgray, point[0], point[1], status, err);
 int k = 0;
 for (int i = 0; i < point[1].size(); i++)
 {
  if (acceptTrackPoint(i))
  {
   initpoint[k] = initpoint[i];
   point[1][k++] = point[1][i];
  }
 }
 point[1].resize(k);//把point[1]中所含有的数量重新变成含有k个
 initpoint.resize(k);//把initpoint中所含有的数量重新变成含有k个
 //绘制角点和运动轨迹
 for (int i = 0; i < point[1].size(); i++)
 {
  line(result, initpoint[i], point[1][i], Scalar(0, 0, 255));
  circle(result, point[1][i], 3, Scalar(0, 255, 0), -1);
 }
 swap(point[1], point[0]);//把point[0]和point[1]的元素交换
 swap(pregray, curgray);//把两张图片交换

 imshow("Optical Flow Demo", result);
}
//function:addNewPoint
//brief:检测新点是否被添加
//return:是否被添加的标志
bool addNewPoint()
{
 return point[0].size() <= 10;
}
//function:acceptTrackPoint
//brief:决定哪些跟踪点被接受
//return:是否被接受的标志
bool acceptTrackPoint(int i)
{
 return status[i] && ((abs(point[0][i].x - point[1][i].x) + abs(point[0][i].y - point[1][i].y)) > 2);
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值