移动对象跟踪三要素:图像表示(跟踪的对象要在图像中出现)外光模型,移动模型。

稀疏光流跟踪,KTL

void calcOpticalFlowPyrLK( // 稀疏光流跟踪,KLTInputArray prevImg, // 要跟踪的图像,8bitInputArray nextImg, // 在目标图像跟跟踪 prevImg 上的 prevPts 特征点InputArray prevPts, // prevImg 上的特征点(光流)的坐标位置;点坐标必须是单精度浮点数InputOutputArray nextPts, // 如果在 nextImg 上跟踪到了 prevImg 上的 prevPts[i],则在 nextPts[i] 上保存该特征点现在的坐标,nextPts与prevPts尺寸相同
OutputArray status, // 输出状态向量(无符号char);如果相应位置的流特征被发现,向量的每个元素被设置为1,否则,被置为0.OutputArray err, // 跟踪时候区域误差和
Size winSize = Size(21,21), // 在每个金字塔水平搜寻窗口的尺寸。int maxLevel = 3, // 金字塔的高度,初始为3层
TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 0.01), // 在每个金字塔层,为某点寻找光流的迭代过程的终止条件
// flags    CV_LKFLOW_PYR_A_READY , 在调用之前,第一帧的金字塔已经准备好
CV_LKFLOW_PYR_B_READY , 在调用之前,第二帧的金字塔已经准备好
CV_LKFLOW_INITIAL_GUESSES , 在调用之前,数组 B 包含特征的初始坐标 (Hunnish: 在本节中没有出现数组 B,不知是指的哪一个)
int flags = 0,double minEigThreshold = 1e-4 // 大量实验得出的默认值,别乱改);

代码:

#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#include<opencv2/face.hpp>
#include<iostream>
#include<math.h>
#include <string>
#include<fstream> using namespace cv::face;
using namespace cv;
using namespace std;
using namespace cv::xfeatures2d;Mat frame, gray;//当前帧
Mat prev_gray;//前一帧
vector<Point2f> features;//shi-tomasi角点检测-特征数据
vector<Point2f>fpts[2];//保证当前帧和前一帧的特征点位置
vector<Point2f> iniPoints;
vector<uchar>status;//特征点跟踪成功标志位
vector<float>errors;//跟踪时候区域误差和void detectFeatures(Mat &inFrame, Mat &ingray)  // Shi-Tomas 角点检测
{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); // 算法很快,满足实时性要求cout << "detect features : " << features.size() << endl;
}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);}
}
void drawTrackLines() // 在跟踪到的且移动了的特征点(光流)的开始跟踪的位置 到 当前跟踪到的位置之间绘制线段
{for (size_t t = 0; t<fpts[1].size(); t++){line(frame, iniPoints[t], fpts[1][t], Scalar(0, 255, 0), 1, 8, 0); // 绘制线段circle(frame, fpts[1][t], 2, Scalar(0, 0, 255), 2, 8, 0);}
}
void KLTrackFeature() {//稀疏光流跟踪,KTLcalcOpticalFlowPyrLK(prev_gray, gray, fpts[0], fpts[1], status, errors);int k = 0;//保存跟踪到的特征点数,最后将特征点的尺寸重新设置为kfor (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])//跟踪到的特征点,且距离移动了2以上的{iniPoints[k] = iniPoints[i];//将跟踪到的移动了的特征点在vector中连续起来,剔掉损失的和禁止不动的特征点(这些跟踪点在前面帧中)fpts[1][k++] = fpts[1][i];//同上(只是这些跟踪点在当前帧中)}}//保存特征点并绘制跟踪轨迹iniPoints.resize(k);fpts[1].resize(k);drawTrackLines();std::swap(fpts[1], fpts[0]);//交换,将此帧跟踪到特征点作为下一帧的待跟踪点
}int main() {VideoCapture capture;capture.open("C:/Users/Administrator/Desktop/pic/3.avi");while (capture.read(frame)) {cvtColor(frame, gray, COLOR_BGR2GRAY);if (fpts[0].size() < 40) {//跟踪40个特征点,如果跟踪的时候损失了一些特征点,重新检测,追加detectFeatures(frame, gray);fpts[0].insert(fpts[0].end(), features.begin(), features.end());//追加带跟踪的特征点iniPoints.insert(iniPoints.end(), features.begin(), features.end());}else{cout << "tracjing........" << endl;}if (prev_gray.empty())gray.copyTo(prev_gray);//保存当前已帧,第一帧过完就不保存了KLTrackFeature();//稀疏光流跟踪,KLTdrawFeature(frame);//绘制特征点//更新前一帧数据gray.copyTo(prev_gray);//只需要灰度图imshow("src", frame);}waitKey(0);
}

结果:

稠密光流跟踪

void calcOpticalFlowFarneback( // 稠密光流跟踪
InputArray prev, // 输入前一帧图像
InputArray next, // 输入后一帧图像
InputOutputArray flow, // 输出的光流
double pyr_scale, // 金字塔上下两层之间的尺度关系
int levels, // 金字塔层数
int winsize, // 均值窗口大小,越大越能denoise并且能够检测快速移动目标,但会引起模糊运动区域
int iterations, // 迭代次数
int poly_n, // 像素领域大小,一般为5,7等
double poly_sigma, // 高斯标注差,一般为1-1.5
int flags // 计算方法。主要包括OPTFLOW_USE_INITIAL_FLOW和OPTFLOW_FARNEBACK_GAUSSIAN
);

代码:

#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#include<opencv2/face.hpp>
#include<iostream>
#include<math.h>
#include <string>
#include<fstream> using namespace cv::face;
using namespace cv;
using namespace std;
using namespace cv::xfeatures2d;void drawOpticalFlowHF(const 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 > 1 || fxy.y > 1) // x 或 y 方向移动了1个像素以上就表示该像素移动了{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()
{VideoCapture capture;capture.open("C:/Users/Administrator/Desktop/pic/3.avi");if (!capture.isOpened()) cout << "video not open.." << endl;Mat frame, gray;Mat prev_frame, prev_gray;Mat flowResult, flowdata;capture.read(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, 10); // 绘制跟踪imshow("flow", flowResult);imshow("src6-11", frame);}}waitKey(0);
}

结果:

OpenCV视频分析与对象跟踪C++(二)光流对象跟踪-稀疏光流、稠密光流相关推荐

  1. OpenCV视频分析与对象跟踪实战教程-贾志刚-专题视频课程

    OpenCV视频分析与对象跟踪实战教程-1957人已学习 课程介绍         OpenCV视频分析与对象跟踪实战视频培训课程概况:基于OpenCV新版本3.2 从基本的OpenCV视频读写与摄像 ...

  2. 15 OpenCV4图像处理与视频分析实战(49.基于颜色的对象跟踪-.)

    15 OpenCV4图像处理与视频分析实战(49.基于颜色的对象跟踪-) 一.49.基于颜色的对象跟踪-. 二,代码 来自网易云课堂(贾志刚) 一.49.基于颜色的对象跟踪-. 二,代码 #inclu ...

  3. OpenCV视频分析背景提取与前景提取

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 基本思想 OpenCV中支持的两种背景提取算法都是基于模型密度评估 ...

  4. opencv视频分析与对象追踪之CAMSHIFT对象跟踪

    原理 CamShift算法,全称是 Continuously AdaptiveMeanShift,顾名思义,它是对Mean Shift 算法的改进,能够自动调节搜索窗口大小来适应目标的大小,可以跟踪视 ...

  5. unity 引用prefab_Unity基础教程-对象管理(二)——对象多样化(Fabricating Shapes)...

    200+篇教程总入口,欢迎收藏: 放牛的星星:[教程汇总+持续更新]Unity从入门到入坟--收藏这一篇就够了​zhuanlan.zhihu.com 本文重点: 1.为形状创建一个工厂 2.保存和加载 ...

  6. Java OpenCV 图像处理30 视频分析和对象跟踪 视频读取

    Java OpenCV 图像处理30 视频分析和对象跟踪 视频读取 Java OpenCV-4.0.0 图像处理 视频分析和对象跟踪 视频读取 package com.xu.opencv.video; ...

  7. Java OpenCV 图像处理32.4 视频分析和对象跟踪 切换背景

    Java OpenCV 图像处理32.4 视频分析和对象跟踪 切换背景 方法 含义 解释 bitwise_and "与"操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制 ...

  8. OpenCV视频目标跟踪及背景分割器

    目标跟踪 本文主要介绍cv2中的视频分析Camshift和Meanshift. 目标: 学习Meanshift算法和Camshift算法来寻找和追踪视频中的目标物体 Meanshift算法: mean ...

  9. opencv 图像与视频分析教程③

    opencv 图像与视频分析教程 代码: https://github.com/bai1231/opencv-learn_and_pratice 二值图像分析 图像二值化 二值图像轮廓分析 霍夫检测 ...

最新文章

  1. 【仿去哪儿】骆驼动画加载
  2. 基于SSM的汽车销售管理系统
  3. python语言命令大全-python常用命令
  4. Python版猜数游戏
  5. docker搭建本地 Registry
  6. html5引擎 laya,传说中的HTML5超级引擎layabox今日开放
  7. 自学python到什么程度就可以工作-Python学到什么程度可以面试工作?
  8. socket.io html5 聊天,socket.io实现在线聊天页面
  9. Windows XP sp3上可以安装SQL Server 2008企业版?
  10. java导出数据库_如何在Java中从整个数据库导出数据?
  11. Django strftime 时区问题
  12. 同是IT小小鸟——《我是一只IT小小鸟》读书笔记
  13. Web前端学完后薪资怎么样?取决你技术好坏
  14. Wannafly挑战赛24 D 无限手套
  15. 11月15日火箭VS湖人视频直播在线观看
  16. 数字 IC 设计、FPGA 设计秋招笔试题目、答案、解析(5)2021 华为海思(下)
  17. 使用yanderify搞个图片转视频(让大头照动起来)
  18. 裁片没有html格式,富怡CAD写裁片属性的时候写不出来布料种类 – 手机爱问
  19. Unity3d调用Android版so库
  20. android ‘低’仿支付宝我的应用功能!(含完整Demo)

热门文章

  1. 保姆级教程!最全苹果相机使用技巧(系列二)
  2. [hadoop笔记]基于CentOS7虚拟机搭建Hadoop完全分布模式(3个节点)
  3. 端游吃鸡服务器维护到几点,《绝地求生》3月13日维护到几点 3月13日维护时间一览...
  4. 打怪小游戏(暂时只支持主线任务、刷怪和作者商店)
  5. JavaScript 数组去重方法合集(简洁易懂)
  6. 【NOIP2018模拟10.25】 总结
  7. php_imagick.dll for php 5.2.8 win ext
  8. HTML中style/css/color设置颜色值(RGB值)的几种方法(常见颜色和色值)
  9. Qt Widget使用QCustomPlot库实现二维螺旋曲线(螺旋曲线一)
  10. 灼热丝测试原理和检测内容