cvUpdateMotionHishtory多幅图像叠加,第三个参数输入为每帧图片的绝对时间,第四个输入则是消逝的时间

cvCalcMotionGradient第三个参数为输出,输出值为各个像素点预测的运动方向值,第一个参数邻域中的最大最小值得差值在第四个和第五个两个值中间时,输出有效。而邻域大小由最后一个参数限定,使用算子为sobel算子。

//下面为转载的一部分代码,加上了部分显示功能,方便效果的展示
//#include "stdafx.h"
#include "opencv/cv.h"
#include "opencv/highgui.h"
#include <time.h>
#include <math.h>
#include <ctype.h>
#include <stdio.h>
// various tracking parameters (in seconds)
const double MHI_DURATION = 3;
const double MAX_TIME_DELTA = 0.5;
const double MIN_TIME_DELTA = 0.05;
// 用于运动检测的循环帧数,与机器速度以及FPS设置有关
const int N = 2;
// ring image buffer
IplImage **buf = 0;
int last = 0;
// temporary images
IplImage *mhi = 0; // MHI: motion history image
IplImage *orient = 0; // orientation
IplImage *mask = 0; // valid orientation mask
IplImage *segmask = 0; // motion segmentation map
CvMemStorage* storage = 0; // temporary storage
// parameters:
// img - input video frame
// dst - resultant motion picture
// args - optional parameters
void update_mhi(IplImage* img, IplImage* dst, int diff_threshold)
{
double timestamp = clock() / 1000.; // get current time in seconds
CvSize size = cvSize(img->width, img->height); // get current frame size
int i, idx1 = last, idx2;
IplImage* silh;
CvSeq* seq;
CvRect comp_rect;
double count;
double angle;
CvPoint center;
double magnitude;
CvScalar color;
// allocate images at the beginning or
// reallocate them if the frame size is changed
if (!mhi || mhi->width != size.width || mhi->height != size.height)
{
if (buf == 0)
{
buf = (IplImage**)malloc(N*sizeof(buf[0]));
memset(buf, 0, N*sizeof(buf[0]));
}
for (i = 0; i < N; i++)
{
cvReleaseImage(&buf[i]);
buf[i] = cvCreateImage(size, IPL_DEPTH_8U, 1);
cvZero(buf[i]);
}
cvReleaseImage(&mhi);
cvReleaseImage(&orient);
cvReleaseImage(&segmask);
cvReleaseImage(&mask);
mhi = cvCreateImage(size, IPL_DEPTH_32F, 1);
cvZero(mhi); // clear MHI at the beginning
orient = cvCreateImage(size, IPL_DEPTH_32F, 1);
segmask = cvCreateImage(size, IPL_DEPTH_32F, 1);
mask = cvCreateImage(size, IPL_DEPTH_8U, 1);
}
cvCvtColor(img, buf[last], CV_BGR2GRAY); // convert frame to grayscale
idx2 = (last + 1) % N; // index of (last - (N-1))th frame
last = idx2;
silh = buf[idx2];
// 相邻两帧的差
cvAbsDiff(buf[idx1], buf[idx2], silh); // get difference between frames
// 对差图像做二值化
cvThreshold(silh, silh, diff_threshold, 1, CV_THRESH_BINARY); // and threshold it
cvUpdateMotionHistory(silh, mhi, timestamp, MHI_DURATION); // update MHI

cvShowImage("silh", silh);
cvWaitKey(1);

// convert MHI to blue 8u image
// cvCvtScale的第四个参数 shift = (MHI_DURATION - timestamp)*255./MHI_DURATION
// 控制帧差的消失速率
cvShowImage("mhi", mhi);
cvWaitKey(1);

cvCvtScale(mhi, mask, 255. / MHI_DURATION,
(MHI_DURATION - timestamp)*255. / MHI_DURATION);
cvZero(dst);
cvCvtPlaneToPix(mask, 0, 0, 0, dst); // B,G,R,0 -> dist : convert to BLUE image

cvShowImage("mask", mask);
cvWaitKey(1);

// 计算运动的梯度方向以及正确的方向掩模mask
// Filter size = 3
cvCalcMotionGradient(mhi, mask, orient,
MAX_TIME_DELTA, MIN_TIME_DELTA, 3);

cvCvtScale(orient, orient, 1,0);

cvShowImage("orient", orient);
cvWaitKey(1);

if (!storage)
storage = cvCreateMemStorage(0);
else
cvClearMemStorage(storage);
// 运动分割: 获得运动部件的连续序列
// segmask is marked motion components map. It is not used further
seq = cvSegmentMotion(mhi, segmask, storage, timestamp, MAX_TIME_DELTA);
// iterate through the motion components,
// One more iteration (i == -1) corresponds to the whole image (global motion)
for (i = 0; i < seq->total; i++)
{
if (i < 0) { // case of the whole image,对整幅图像做操作
comp_rect = cvRect(0, 0, size.width, size.height);
color = CV_RGB(255, 255, 255); // white color
magnitude = 100; // 画线长度以及圆半径的大小控制
}
else { // i-th motion component
comp_rect = ((CvConnectedComp*)cvGetSeqElem(seq, i))->rect;
// 去掉小的部分
if (comp_rect.width + comp_rect.height < 100)
continue;
color = CV_RGB(255, 0, 0); // red color
magnitude = 30;
//if(seq->total > 0) MessageBox(NULL,"Motion Detected",NULL,0);
}
// select component ROI
cvSetImageROI(silh, comp_rect);
cvSetImageROI(mhi, comp_rect);
cvSetImageROI(orient, comp_rect);
cvSetImageROI(mask, comp_rect);
// 在选择的区域内, 计算运动方向
angle = cvCalcGlobalOrientation(orient, mask, mhi, timestamp,
MHI_DURATION);
angle = 360.0 - angle; // adjust for images with top-left origin
// 在轮廓内计算点数
// Norm(L1) = sum of total pixel values
count = cvNorm(silh, 0, CV_L1, 0);
// The function cvResetImageROI releases image ROI
cvResetImageROI(mhi);
cvResetImageROI(orient);
cvResetImageROI(mask);
cvResetImageROI(silh);
// check for the case of little motion
if (count < comp_rect.width*comp_rect.height * 0.05) // five percent of pixel
continue;
// draw a clock with arrow indicating the direction
center = cvPoint((comp_rect.x + comp_rect.width / 2),
(comp_rect.y + comp_rect.height / 2));
cvCircle(dst, center, cvRound(magnitude*1.2), color, 3, CV_AA, 0);
cvLine(dst, center, cvPoint(cvRound(center.x +
magnitude*cos(angle*CV_PI / 180)),
cvRound(center.y - magnitude*sin(angle*CV_PI / 180))),
color, 3, CV_AA, 0);
cvRectangle(dst, cvPoint(comp_rect.x, comp_rect.y), cvPoint(comp_rect.x + comp_rect.width, comp_rect.y + comp_rect.height),cvScalar(255,0,0));

}
}
int main(int argc, char** argv)
{
IplImage* motion = 0;
CvCapture* capture = 0;
if (argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])))
capture = cvCaptureFromCAM(argc == 2 ? argv[1][0] - '0' : 0);
else if (argc == 2)
capture = cvCaptureFromAVI(argv[1]);
if (capture)
{
cvNamedWindow("Motion", 1);
for (;;)
{
IplImage* image;
if (!cvGrabFrame(capture))
break;
image = cvRetrieveFrame(capture);
if (image)
{
if (!motion)
{
motion = cvCreateImage(cvSize(image->width, image->height),
8, 3);
cvZero(motion);
motion->origin = image->origin;

}
}
update_mhi(image, motion, 60);
cvShowImage("Motion", motion);
if (cvWaitKey(10) >= 0)
break;
}
cvReleaseCapture(&capture);
cvDestroyWindow("Motion");
}
return 0;
}

有关cvUpdateMotionHishtory,cvCalcMotionGradient等函数的使用相关推荐

  1. 图像处理和图像识别中常用的OpenCV函数

    1.   cvLoadImage:将图像文件加载至内存: 2.   cvNamedWindow:在屏幕上创建一个窗口: 3.   cvDestroyWindow:销毁显示图像文件的窗口: 4.   c ...

  2. 学习OpenCV 函数方法结构总结

    原文出自:http://blog.chinaunix.net/uid-8402201-id-2899695.html OpenCv中文论坛精华地址 http://www.opencv.org.cn/i ...

  3. Openv学习笔记--常用函数(转自互联网)

    cvLoadImage:将图像文件加载至内存: cvNamedWindow:在屏幕上创建一个窗口: cvDestroyWindow:销毁显示图像文件的窗口: cvDestroyAllWindows:销 ...

  4. opencv学习篇(1) 图像处理和图像识别中常用的OpenCV函数

    今天开始打算整理一下上一阶段所学的内容,感觉学习的阅读的太多,知识点像一团乱麻一样,需要整理一下了. 为了能快速查阅opencv的一些基本函数,先汇总一下,以供日后查阅. 1.   cvLoadIma ...

  5. 数据库中自定义排序规则,Mysql中自定义字段排序规则,Oracle中自定义字段排序规则,decode函数的用法,field函数的用法

    数据库中自定义排序 场景:有一张banner表,表中有一个status字段,有0, 1, 2三个状态位,我想要 1,0,2的自定义排序(这里是重点),然后再进行之上对sequence字段进行二次排序( ...

  6. Mysql函数group_concat、find_in_set 多值分隔字符字段进行数据库字段值翻译

    Mysql函数group_concat.find_in_set进行数据库字段值翻译 场景 配方表:记录包含的原料 sources表示原料,字段值之间用逗号分隔 原料表:对应原料id和原料名称 现需要查 ...

  7. C++ 笔记(34)— C++ exit 函数

    当遇到 main 函数中的 return 语句时,C++ 程序将停止执行.但其他函数结束时,程序并不会停止.程序的控制将返回到函数调用之后的位置.然而,有时候会出现一些非常少见的情况,使得程序有必要在 ...

  8. C++ 笔记(30)— 友元函数与友元类

    我们知道类的私有成员只能在类的成员函数内部访问,如果想在别处访问对象的私有成员,只能通过类提供的接口(成员函数)间接地进行.这固然能够带来数据隐藏的好处,利于将来程序的扩充,但也会增加程序书写的麻烦. ...

  9. 浅显易懂 Makefile 入门 (07)— 其它函数(foreach 、if、call、origin )

    1. foreach 函数 foreach 函数定义如下: $(foreach <var>,<list>,<text>) 函数的功能是:把参数 <list&g ...

最新文章

  1. python BeautifulSoup的简单使用
  2. Keras之父:我担心的是AI被社交媒体操控
  3. automation服务器不能创建对象是什么意思_从运营商角度来考虑为什么NAT不能搭建服务器?...
  4. spring的发展||springboot和微服务的介绍
  5. 使用BeetleX在Linux下部署.NET多站点服务
  6. 何时以及如何使用ThreadLocal
  7. 【LeetCode笔记】438. 找到字符串中所有字母异位词(Java、字符串、滑动窗口)
  8. 微软将数据保存在玻璃中 可以安全地存储数千年
  9. 使用poi读写Excel
  10. 操作系统 第四章 文件管理
  11. 【论文写作】本科、硕士研究生毕业论文格式问题
  12. 华为双前置摄像头_vivo双摄像头为何前置?华为为何是后置?
  13. C++验证哥德巴赫猜想
  14. bootdo框架使用步骤总结
  15. 路由器k2固件改系统时间
  16. c 语言 todo 用法,Tip:iOS开发中关于TODO的用法
  17. 蓝牙4.0 OSAL层工作原理
  18. 右上角的引用文献格式_论文要引用的小符号右上角怎么打?
  19. select中选中option的方法
  20. --i和i--的区别

热门文章

  1. lua 调用文件中的函数调用_四、C++获得Lua的变量和Table的值
  2. 300 行代码带你秒懂 Java 多线程!
  3. 近两年火热的微服务springboot不同配置文件详细讲解
  4. 算法--360面试:使用递归实现:a0=1,a1=1;a2=a0+a1;a3=a1+a2...以此类推,求a30
  5. 一天搞定HTML----常用标签01
  6. (仿头条APP项目)3.二级页面首页的ViewPager页面切换
  7. JSunpack-n的安装与简单使用
  8. JavaScript中Console的9个常用调试命令
  9. 山科大计算机专业排名,山东科技大学专业排名情况
  10. 霍夫曼树(最优二叉树)的实现