一.稠密光流法跟踪移动物体


例1

#include <opencv2/opencv.hpp>
#include <iostream>using namespace cv;
using namespace std;int main(int argc, char** argv)
{VideoCapture capture("mulballs.mp4");Mat prevFrame, prevGray;if (!capture.read(prevFrame)){cout << "请确认视频文件名称是否正确" << endl;return -1;}//将彩色图像转换成灰度图像cvtColor(prevFrame, prevGray, COLOR_BGR2GRAY);while (true){Mat nextFrame, nextGray;//所有图像处理完成后推出程序if (!capture.read(nextFrame)){break;}imshow("视频图像", nextFrame);//计算稠密光流cvtColor(nextFrame, nextGray, COLOR_BGR2GRAY);Mat_<Point2f> flow;  //两个方向的运动速度calcOpticalFlowFarneback(prevGray, nextGray, flow, 0.5, 3, 15, 3, 5, 1.2, 0);Mat xV = Mat::zeros(prevFrame.size(), CV_32FC1);  //x方向移动速度Mat yV = Mat::zeros(prevFrame.size(), CV_32FC1);  //y方向移动速度//提取两个方向的速度for (int row = 0; row < flow.rows; row++){for (int col = 0; col < flow.cols; col++){const Point2f& flow_xy = flow.at<Point2f>(row, col);xV.at<float>(row, col) = flow_xy.x;yV.at<float>(row, col) = flow_xy.y;}}//计算向量角度和幅值Mat magnitude, angle;cartToPolar(xV, yV, magnitude, angle);//cartToPolar是OpenCV中的一个函数//讲角度转换成角度制angle = angle * 180.0 / CV_PI / 2.0;//把幅值归一化到0-255区间便于显示结果normalize(magnitude, magnitude, 0, 255, NORM_MINMAX);//计算角度和幅值的绝对值convertScaleAbs(magnitude, magnitude);convertScaleAbs(angle, angle);//讲运动的幅值和角度生成HSV颜色空间的图像Mat HSV = Mat::zeros(prevFrame.size(), prevFrame.type());vector<Mat> result;split(HSV, result);result[0] = angle;  //决定颜色result[1] = Scalar(255);result[2] = magnitude;  //决定形态//将三个多通道图像合并成三通道图像merge(result, HSV);//讲HSV颜色空间图像转换到RGB颜色空间中Mat rgbImg;cvtColor(HSV, rgbImg, COLOR_HSV2BGR);//显示检测结果imshow("运动检测结果", rgbImg);int ch = waitKey(5);if (ch == 27){break;}}waitKey(0);return 0;
}

运行结果:

二.稀疏光流法跟踪移动物体


  通常情况下,我们使用的是托马斯角点
例2

*附例2代码:

nclude <opencv2/opencv.hpp>
#include <iostream>using namespace cv;
using namespace std;void draw_lines(Mat &image, vector<Point2f> pt1, vector<Point2f> pt2);
vector<Scalar> color_lut;  //颜色查找表int main()
{VideoCapture capture("mulballs.mp4");Mat prevframe, prevImg;if (!capture.read(prevframe)){cout << "请确认输入视频文件是否正确" << endl;return -1;}cvtColor(prevframe, prevImg, COLOR_BGR2GRAY);//角点检测相关参数设置vector<Point2f> Points;double qualityLevel = 0.01;int minDistance = 10;int blockSize = 3;bool useHarrisDetector = false;double k = 0.04;int Corners = 5000;//角点检测goodFeaturesToTrack(prevImg, Points, Corners, qualityLevel, minDistance, Mat(),blockSize, useHarrisDetector, k);//稀疏光流检测相关参数设置vector<Point2f> prevPts;  //前一帧图像角点坐标vector<Point2f> nextPts;  //当前帧图像角点坐标vector<uchar> status;  //检点检测到的状态vector<float> err;TermCriteria criteria = TermCriteria(TermCriteria::COUNT+ TermCriteria::EPS, 30, 0.01);double derivlambda = 0.5;int flags = 0;//初始状态的角点vector<Point2f> initPoints;initPoints.insert(initPoints.end(), Points.begin(), Points.end());//前一帧图像中的角点坐标prevPts.insert(prevPts.end(), Points.begin(), Points.end());while (true){Mat nextframe, nextImg;if (!capture.read(nextframe)){break;}imshow("nextframe", nextframe);//光流跟踪cvtColor(nextframe, nextImg, COLOR_BGR2GRAY);calcOpticalFlowPyrLK(prevImg, nextImg, prevPts, nextPts, status, err,Size(31, 31), 3, criteria, derivlambda, flags);//判断角点是否移动,如果不移动就删除size_t i, k;for (i = k = 0; i < nextPts.size(); i++){// 距离与状态测量double dist = abs(prevPts[i].x - nextPts[i].x) + abs(prevPts[i].y - nextPts[i].y);if (status[i] && dist > 2){prevPts[k] = prevPts[i];initPoints[k] = initPoints[i];nextPts[k++] = nextPts[i];circle(nextframe, nextPts[i], 3, Scalar(0, 255, 0), -1, 8);}}//更新移动角点数目nextPts.resize(k);prevPts.resize(k);initPoints.resize(k);// 绘制跟踪轨迹draw_lines(nextframe, initPoints, nextPts);imshow("result", nextframe);char c = waitKey(50);if (c == 27){break;}//更新角点坐标和前一帧图像std::swap(nextPts, prevPts);nextImg.copyTo(prevImg);//如果角点数目少于30,就重新检测角点if (initPoints.size() < 30){goodFeaturesToTrack(prevImg, Points, Corners, qualityLevel,minDistance, Mat(), blockSize, useHarrisDetector, k);initPoints.insert(initPoints.end(), Points.begin(), Points.end());prevPts.insert(prevPts.end(), Points.begin(), Points.end());printf("total feature points : %d\n", prevPts.size());}}return 0;
}void draw_lines(Mat &image, vector<Point2f> pt1, vector<Point2f> pt2)
{RNG rng(5000);if (color_lut.size() < pt1.size()){for (size_t t = 0; t < pt1.size(); t++){color_lut.push_back(Scalar(rng.uniform(0, 255), rng.uniform(0, 255),rng.uniform(0, 255)));}}for (size_t t = 0; t < pt1.size(); t++) {line(image, pt1[t], pt2[t], color_lut[t], 2, 8, 0);}
}

运行结果:

OpenCV4每日一练day14:光流法跟踪移动物体相关推荐

  1. 视觉SLAM笔记(42) 光流法跟踪特征点

    视觉SLAM笔记(42) 光流法跟踪特征点 1. 使用 TUM 公开数据集 2. 使用 LK 光流 1. 使用 TUM 公开数据集 准备了若干张数据集图像,存放在程序目录中的 VSLAM_note/0 ...

  2. KLT稀疏光流法跟踪特征点详解

    由于要做SLAM的project,而KLT是这个项目中第一个算法,做个记录顺便让自己记住. 定义一个矩阵frame,用于盛放caputure对象发过来的每一帧图像,gray是frame对应的灰度图,f ...

  3. 跟踪算法(一)光流法跟踪

    COPY FROM:http://blog.csdn.net/crzy_sparrow/article/details/7407604 BTW:原文作者是我学习的榜样! 本文目录: 一.基于特征点的目 ...

  4. OpenCV4每日一练day3:运行OpenCV示例程序(物体跟踪)

    step1:准备好摄像头,或用电脑自带摄像头也可以.这里使用的是英特尔D435i. step2:找到OpenCV自带的物体跟踪demo--camshiftdemo.cpp,添加到VS2015源文件中 ...

  5. QT每日一练day14:QFontDialog字体对话框

    一.第一阶段 运行结果: day14.pro QT += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += c++11# ...

  6. OpenCV4每日一练day13:双目相机校正

    一.双目相机校正说明--<OpenCV4快速入门> 二.双目相机校正 文件准备: 运行结果: 附代码: #include <opencv2\opencv.hpp> #inclu ...

  7. OpenCV4每日一练day12:双目相机标定

    一.标定说明--<OpenCV4快速入门> 二.标定 文件准备: 运行结果: <OpenCV4快速入门>中的运行结果: 附上例代码: #include <opencv2\ ...

  8. OpenCV4每日一练day11:单目位姿估计

    一.单目位姿估计   根据相机成像模型,如果已知相机的内参矩阵.世界坐标系中若干空间点的三维坐标和空间点在图像中投影的二维坐标,那么可以计算出世界坐标系到相机坐标系的旋转向量和平移向量.如图所示,当知 ...

  9. OpenCV4每日一练day8:模型投影函数projectPoints()

      OpenCV4中提供了projectPoints()函数用于计算世界坐标系中的三维点投影到像素坐标系中的二维坐标. 例:程序参数来自下述图片 运行结果: 附上例代码: #include <o ...

最新文章

  1. Oracle HA 之 oracle 11.2 rac库配置active dataguard
  2. python基础 函数 (四)
  3. 牛客练习赛84F-牛客推荐系统开发之下班【莫比乌斯反演,杜教筛】
  4. JZOJ5776. 【NOIP2008模拟】小x游世界树
  5. 闪存必须解决的三大问题
  6. 微信小程序uni.getImageInfo踩坑大计划
  7. 米筐量化不支持c语言_从零开始学量化(三):数据获取途径
  8. Selenium FirePath的安装和使用
  9. 嵌入式 Linux 按键驱动
  10. 微信小程序 input ,阻止冒泡事件,catchtap的使用
  11. 小米手机与计算机如何连接网络连接,小米手机连接不上电脑怎么办 图文教你小米手机怎么连接电脑...
  12. kubernetes: CNI解读
  13. Linux:解决centos7每次更换IP方法
  14. 格林尼治时间与本地时间的转换
  15. 非华为电脑多屏协同安装最新的电脑管家
  16. Day 1 廉颇老矣,尚能饭否?
  17. Java-龙与地下城怪物设计
  18. margin-left:-100%理解
  19. 计算机科学 泰勒级数,一阶常微分方程泰勒级数解法的计算机实现.pdf
  20. 表示转折时yet与but的区别是什么

热门文章

  1. 基于JAVA+SpringMVC+Mybatis+MYSQL的图书管理系统
  2. 基于JAVA+SpringMVC+Mybatis+MYSQL的在线书城购物网站
  3. 基于JAVA+SpringMVC+Mybatis+MYSQL的旅游景点酒店预订网站设计
  4. 基于JAVA+SpringMVC+Mybatis+MYSQL的停车预约管理系统
  5. jQuery插件定义
  6. 1.1.29 加入项目符号后换行文字未对齐
  7. 帮助新手理解equals和hashCode
  8. apidoc @apiGroup兼容中文
  9. Syntax Error: Unexpected token 报错原因
  10. vs已停止工作的解决方案