updateMotionHistory

void updateMotionHistory( InputArray silhouette, InputOutputArray mhi,double timestamp, double duration );

参数:
silhouette - 具有运动发生的非零像素的轮廓蒙版,非零像素的位置代表有运动发生。
mhi  - 由函数更新的运动历史图像(单通道,32位浮点)。
timestamp  - 以毫秒或其他单位表示的当前时间。
duration - 运动轨迹的最大持续时间,设置运动历史像素保留在mhi中的时间长度。换句话说,mhi中比(timestamp -duration )更早之前的像素被设为0.

calcMotionGradient:

void calcMotionGradient( InputArray mhi, OutputArray mask,OutputArray orientation,double delta1, double delta2,int apertureSize=3 );

mhi:是updateMotionHistory函数的输出结果;

OutputArray mask:单通道8位图像,非零项表示发现有效梯度的位置;
OutputArray orientation:浮点图像,给出每个点的梯度方向角度,以度为单位,范围0到360.
double delta1, double delta2,表示允许的最小,最大梯度幅度
int apertureSize=3,梯度运算符的宽度和高度。

segmentMotion

void segmentMotion(InputArray mhi, OutputArray segmask,CV_OUT vector<Rect>& boundingRects,double timestamp, double segThresh);

mhi:updateMotionHistory函数的输出

OutputArray segmask:单通道32位浮点图像,,各“片段”被标记在图上,其中每个片段被赋予不同的非零标记符(1,2,3.。。。0表示“无运动”)

opencv2中的segmentMotion内部调用的还是cvSegmentMotion这个函数

CvSeq* cvSegmentMotion( const CvArr* mhi, CvArr* seg_mask, CvMemStorage* storage,double timestamp, double seg_thresh );
mhi             运动历史图像
seg_mask        发现应当存储的 mask 的图像, 单通道, 32bits, 浮点数.
storage         包含运动连通域序列的内存存储仓
timestamp       当前时间,毫秒单位
seg_thresh      分割阈值,推荐等于或大于运动历史“每步”之间的间隔。
函数 cvSegmentMotion 寻找所有的运动分割,并且在seg_mask 用不同的单独数字(1,2,...)标识它们。

返回一个具有 CvConnectedComp 结构的序列,其中每个结构对应一个运动部件。在这之后,每个运动部件的运动方向就可以被函数 cvCalcGlobalOrientation 利用提取的特定部件的掩模(mask)计算出来

calcGlobalOrientation:找到整体运动方向作为有效梯度方向的向量和

double calcGlobalOrientation( InputArray orientation, InputArray mask,InputArray mhi, double timestamp,double duration );

InputArray orientation:calcMotionGradient的输出

InputArray mask:calcMotionGradient的输出
InputArray mhi,:updateMotionHistory函数的输出结果

double timestamp:当前时间;
double duration :持续时间。

函数返回目标运动的方向。

实例:

#include<opencv2\video\tracking.hpp>
#include<opencv2\video\video.hpp>
#include<opencv2\highgui.hpp>
#include <opencv2\imgproc.hpp>#include <time.h>
#include <stdio.h>
#include <ctype.h>using namespace cv;
using namespace std;static void help(void)
{printf("\nThis program demonstrated the use of motion templates -- basically using the gradients\n""of thresholded layers of decaying frame differencing. New movements are stamped on top with floating system\n""time code and motions too old are thresholded away. This is the 'motion history file'. The program reads from the camera of your choice or from\n""a file. Gradients of motion history are used to detect direction of motion etc\n""Usage :\n""./motempl [camera number 0-n or file name, default is camera 0]\n");
}
// various tracking parameters (in seconds)
const double MHI_DURATION = 5;
const double MAX_TIME_DELTA = 0.5;
const double MIN_TIME_DELTA = 0.05;
// number of cyclic frame buffer used for motion detection
// (should, probably, depend on FPS)// ring image buffer
vector<Mat> buf;
int last = 0;// temporary images
Mat mhi, orient, mask, segmask, zplane;
vector<Rect> regions;// parameters:
//  img - input video frame
//  dst - resultant motion picture
//  args - optional parameters
static void  update_mhi(const Mat& img, Mat& dst, int diff_threshold)
{double timestamp = (double)clock() / CLOCKS_PER_SEC; // get current time in secondsSize size = img.size();int i, idx1 = last;Rect comp_rect;double count;double angle;Point center;double magnitude;Scalar color;// allocate images at the beginning or// reallocate them if the frame size is changedif (mhi.size() != size){mhi = Mat::zeros(size, CV_32F);zplane = Mat::zeros(size, CV_8U);buf[0] = Mat::zeros(size, CV_8U);buf[1] = Mat::zeros(size, CV_8U);}cvtColor(img, buf[last], COLOR_BGR2GRAY); // convert frame to grayscaleint idx2 = (last + 1) % 2; // index of (last - (N-1))th framelast = idx2;Mat silh = buf[idx2];absdiff(buf[idx1], buf[idx2], silh); // get difference between framesthreshold(silh, silh, diff_threshold, 1, THRESH_BINARY); // and threshold itupdateMotionHistory(silh, mhi, timestamp, MHI_DURATION); // update MHI// convert MHI to blue 8u imagemhi.convertTo(mask, CV_8U, 255. / MHI_DURATION, (MHI_DURATION - timestamp)*255. / MHI_DURATION);Mat planes[] = { mask, zplane, zplane };merge(planes, 3, dst);// calculate motion gradient orientation and valid orientation maskcalcMotionGradient(mhi, mask, orient, MAX_TIME_DELTA, MIN_TIME_DELTA, 3);// segment motion: get sequence of motion components// segmask is marked motion components map. It is not used furtherregions.clear();segmentMotion(mhi, segmask, regions, timestamp, MAX_TIME_DELTA);// iterate through the motion components,// One more iteration (i == -1) corresponds to the whole image (global motion)for (i = -1; i < (int)regions.size(); i++) {if (i < 0) { // case of the whole imagecomp_rect = Rect(0, 0, size.width, size.height);color = Scalar(255, 255, 255);magnitude = 100;}else { // i-th motion componentcomp_rect = regions[i];if (comp_rect.width + comp_rect.height < 100) // reject very small componentscontinue;color = Scalar(0, 0, 255);magnitude = 30;}// select component ROIMat silh_roi = silh(comp_rect);Mat mhi_roi = mhi(comp_rect);Mat orient_roi = orient(comp_rect);Mat mask_roi = mask(comp_rect);// calculate orientationangle = calcGlobalOrientation(orient_roi, mask_roi, mhi_roi, timestamp, MHI_DURATION);angle = 360.0 - angle;  // adjust for images with top-left origincount = norm(silh_roi, NORM_L1);; // calculate number of points within silhouette ROI// check for the case of little motionif (count < comp_rect.width*comp_rect.height * 0.05)continue;// draw a clock with arrow indicating the directioncenter = Point((comp_rect.x + comp_rect.width / 2),(comp_rect.y + comp_rect.height / 2));cv::Mat img = img;circle(img, center, cvRound(magnitude*1.2), color, 3, 16, 0);line(img, center, Point(cvRound(center.x + magnitude*cos(angle*CV_PI / 180)),cvRound(center.y - magnitude*sin(angle*CV_PI / 180))), color, 3, 16, 0);}
}int main(int argc, char** argv)
{VideoCapture cap;help();if (argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])))cap.open(argc == 2 ? argv[1][0] - '0' : 0);else if (argc == 2)cap.open(argv[1]);if (!cap.isOpened()){printf("Could not initialize video capture\n");return 0;}buf.resize(2);Mat image, motion;for (;;){cap >> image;if (image.empty())break;update_mhi(image, motion, 30);imshow("Image", image);imshow("Motion", motion);if (waitKey(10) >= 0)break;}return 0;
}

OpenCV3学习(12.2) 目标跟踪之运动模板法segmentMotion实现(Mat版本)相关推荐

  1. 目标跟踪之Lukas-Kanade光流法

    光流是图像亮度的运动信息描述.光流法计算最初是由Horn和Schunck于1981年提出的,创造性地将二维速度场与灰度相联系,引入光流约束方程,得到光流计算的基本算法.光流计算基于物体移动的光学特性提 ...

  2. 【目标跟踪】帧差法结合卡尔曼滤波行人姿态识别【含GUI Matlab源码 1127期】

    ⛄一.基于人体特征识别和卡尔曼滤波的行人跟踪算法简介 1 基于体型和行为姿态特征的人体识别算法 从红外图像中可以得到目标与背景之间的灰度级差别,从而区分出有生命特征的运动物体,但仅从亮度特征无法区别出 ...

  3. 基于Python和OpenCV的目标跟踪学习教程 Object Tracking using Python and OpenCV

    实现12种不同的算法来跟踪视频和网络摄像头中的对象! 你会学到: 使用Python和OpenCV跟踪视频和网络摄像头中的对象 理解跟踪算法的基本直觉 实现12种跟踪算法 了解对象检测和对象跟踪之间的区 ...

  4. 基于元学习的红外弱小点状目标跟踪算法

    基于元学习的红外弱小点状目标跟踪算法 人工智能技术与咨询 昨天 本文来自<激光技术>,作者热孜亚·艾沙等 引言 红外点状目标的跟踪是红外搜索和跟踪(infrared search and ...

  5. opencv动态目标跟踪学习总结

    用opencv实现对视频中动态目标的追踪 第一步,是要建立一个编程环境,然后加载opencv的库路径等等.具体步骤在 http://www.opencv.org.cn/ 的"安装" ...

  6. 深度学习在目标跟踪中的应用

    from: http://www.dataguru.cn/article-9863-1.html 摘要: 人眼可以比较轻松的在一段时间内跟住某个特定目标.但是对机器而言,这一任务并不简单,尤其是跟踪过 ...

  7. (转) 深度学习在目标跟踪中的应用

    深度学习在目标跟踪中的应用 原创 2016-09-05 徐霞清 深度学习大讲堂 点击上方"深度学习大讲堂"可订阅哦!深度学习大讲堂是高质量原创内容的平台,邀请学术界.工业界一线专家 ...

  8. [转]深度学习在目标跟踪中的应用

    原文链接:https://zhuanlan.zhihu.com/p/22334661 开始本文之前,我们首先看上方给出的3张图片,它们分别是同一个视频的第1,40,80帧.在第1帧给出一个跑步者的边框 ...

  9. Jarry的目标跟踪学习笔记一

    Jarry的目标跟踪学习笔记一 目标跟踪是计算机视觉中的一个重要方向,已经由来已久,并且有着广泛的应用,如:视频监控,人机交互, 无人驾驶等.在我的想象中,自己研究的内容就是,将来钢铁侠头盔里追踪敌人 ...

最新文章

  1. 超全汇总 | ORB-SLAM2 / ORB-SLAM3 相关改进代码!
  2. matebook14支持触摸屏吗_华为MateBook 14 2021发布,触摸屏成标配
  3. c#图片上绘制半透明矩形
  4. java wait源码_Java精通并发-透过openjdk源码分析wait与notify方法的本地实现
  5. 山西最值得一去的5座古镇,你都去过吗?
  6. linux下源码安装vsftpd-3.0.2
  7. 2000年考研英语阅读理解文章五
  8. 2 WM配置-企业结构-分配-给工厂和库存地点分配仓库号
  9. java catch自定义异常_Laravel - 自定义处理程序中的Catch异常
  10. 计算机常见知识大全,电脑基本知识
  11. PS使用:利用PS去除图片中的多余文字
  12. Redis【有与无】【Lettuce】L4.Redis Sentinel
  13. 图表示学习之时序的事件和节点动态
  14. windows10家庭版修改中文用户名完美解决
  15. 写了placement new也要写placement delete——条款52
  16. Python爬虫-安某某客新房和二手房
  17. 英语口语8000句-随意的谈话
  18. 投稿时Cover Letter的重要性(部分体会来自导师)
  19. Office 文件解析入门
  20. 改改host,轻松登录dropbox!(For Windows)

热门文章

  1. escilpe mysql,wordpress函数esc_sql()用法示例
  2. linux samba教程,Linux samba的配置和使用
  3. mysql导出选择两张表,Mysql导出(多张表)表结构及表数据 mysqldump用法
  4. zabbix4.2学习笔记系列
  5. 打开网页到我们看到页面显示的过程中发生了什么?
  6. 微信小程序之弹框modal
  7. [Ogre][地形]OgreTerrain的实现原理分析
  8. IIS搭建网站遇到的问题
  9. cocos2dx 3.x 解决输入框(TextField,TextFieldTTF) 输入中文变乱码的问题
  10. php二维数组排序方法(array_multisort usort)