#include "cv.h"
#include "highgui.h"
#include "stdlib.h"
#include "malloc.h"
#include "cxcore.h"
#include "assert.h"
#include <time.h>
#include <math.h>
#include <ctype.h>
#include <stdio.h>
#include <iostream> using namespace std; // various tracking parameters (in seconds)
const double MHI_DURATION = ;
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)
//用于运动检测的循环帧数
const int N = ; // ring image buffer
IplImage **buf = ;
int last = ; // temporary images
IplImage *mhi = ; // MHI
IplImage *orient = ; // orientation
IplImage *mask = ; // valid orientation mask
IplImage *segmask = ; // motion segmentation map
CvMemStorage* storage = ; // 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 = (double)clock() / CLOCKS_PER_SEC; // 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 == )
{
buf = (IplImage**)malloc(N*sizeof(buf[]));
memset(buf, , N*sizeof(buf[]));//把申请到的内存空间用0初始化
} for (i = ; i < N; i++) {
cvReleaseImage(&buf[i]);
buf[i] = cvCreateImage(size, IPL_DEPTH_8U, );
cvZero(buf[i]);
}
cvReleaseImage(&mhi);
cvReleaseImage(&orient);
cvReleaseImage(&segmask);
cvReleaseImage(&mask); mhi = cvCreateImage(size, IPL_DEPTH_32F, );
cvZero(mhi); // clear MHI at the beginning
orient = cvCreateImage(size, IPL_DEPTH_32F, );
segmask = cvCreateImage(size, IPL_DEPTH_32F, );
mask = cvCreateImage(size, IPL_DEPTH_8U, );
} cvCvtColor(img, buf[last], CV_BGR2GRAY); // convert frame to grayscale 转换为灰度图 idx2 = (last + ) % 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, , CV_THRESH_BINARY); // and threshold it
cvUpdateMotionHistory(silh, mhi, timestamp, MHI_DURATION); // update MHI // convert MHI to blue 8u image
cvCvtScale(mhi, mask, . / MHI_DURATION,
(MHI_DURATION - timestamp)*. / MHI_DURATION);
cvZero(dst);
cvCvtPlaneToPix(mask, , , , dst); // calculate motion gradient orientation and valid orientation mask计算运动的梯度方向以及正确的方向掩码
cvCalcMotionGradient(mhi, mask, orient, MAX_TIME_DELTA, MIN_TIME_DELTA, ); if (!storage)
storage = cvCreateMemStorage();
else
cvClearMemStorage(storage); // segment motion: get sequence of motion components运动分割:获取运动组成成分的序列
// 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 = -; i < seq->total; i++)
{ if (i < )
{ // case of the whole image
comp_rect = cvRect(, , size.width, size.height);
color = CV_RGB(, , );
magnitude = ;
}
else
{ // i-th motion component
comp_rect = ((CvConnectedComp*)cvGetSeqElem(seq, i))->rect;
if (comp_rect.width + comp_rect.height < ) // reject very small components
continue;
color = CV_RGB(, , );
magnitude = ;
} // select component ROI
cvSetImageROI(silh, comp_rect);
cvSetImageROI(mhi, comp_rect);
cvSetImageROI(orient, comp_rect);
cvSetImageROI(mask, comp_rect); // calculate orientation在选择区域内计算运动方向
angle = cvCalcGlobalOrientation(orient, mask, mhi, timestamp, MHI_DURATION);
angle = 360.0 - angle; // adjust for images with top-left origin count = cvNorm(silh, , CV_L1, ); // calculate number of points within silhouette 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)
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);
}
} int main(int argc, char** argv)
{
IplImage* motion = ;
CvCapture* capture = ; capture = cvCaptureFromFile("E:\Videos\\daria_walk.avi"); if (capture)
{
cvNamedWindow("Motion", ); for (;;)
{
IplImage* image;
if (!cvGrabFrame(capture))
break;
//Decodes and returns the grabbed video frame.
//C++: bool VideoCapture::retrieve(Mat& image, int channel=0)
// IplImage* cvRetrieveFrame(CvCapture* capture, int streamIdx=0 )
image = cvRetrieveFrame(capture); if (image)
{
if (!motion)
{
//Creates an image header and allocates the image data.
//C: IplImage* cvCreateImage(CvSize size, int depth, int channels)
motion = cvCreateImage(cvSize(image->width, image->height), , );
//Clears the array.
//C: void cvSetZero(CvArr* arr)
cvZero(motion);
motion->origin = image->origin;
}
} update_mhi(image, motion, );
cvShowImage("Motion", motion); if (cvWaitKey() >= )
break;
}
cvReleaseCapture(&capture);
cvDestroyWindow("Motion");
} return ; }

MHI ,运动历史图像的的获取[下载自CSDN]的更多相关文章

  1. OpenCV3.1.0中调用MHI(Motion History Images, 运动历史图像)

    写在前边: OpenCV3.0+要想使用MHI,就要现安装扩展模块opencv_contrib.安装方法见:ubuntu 14.04 64位 安装Opencv3.1.0 (包含opencv_contr ...

  2. c#图像处理入门(-bitmap类和图像像素值获取方法)

    c#图像处理入门 -bitmap类和图像像素值获取方法 一.Bitmap类 Bitmap对象封装了GDI+中的一个位图,此位图由图形图像及其属性的像素数据组成.因此Bitmap是用于处理由像素数据定义 ...

  3. 最新版ChemDraw 15.1 免费获取下载

    ChemDraw 15.1 Pro是最新版的ChemOffice套件的个人生产力工具,它可以帮助科学家有效地捕捉和分享工作内容,通过可视化功能对结果获得更深入的了解.现在为大家带来好消息,ChemOf ...

  4. php 微信开发之新增上传/获取下载临时素材

    php 微信开发之新增上传/获取下载临时素材 代码 <?php define("AppID","");//你的id define("AppSec ...

  5. 如何获取下载 FreeBSD

    『如何获取下载 FreeBSD 』 『如何获取下载 FreeBSD 』 FreeBSD 是免费获取的. [下载地址] O网页链接 版本选择,尽量选择较新版本,桌面用户可选择 current 版本.st ...

  6. Ueditor文本编辑器(新浪SAE平台版本) - 下载频道 - CSDN.NET

    Ueditor文本编辑器(新浪SAE平台版本) - 下载频道 - CSDN.NET Ueditor文本编辑器(新浪SAE平台版本)

  7. C#中的bitmap类和图像像素值获取方法

    一.Bitmap类 Bitmap对象封装了GDI+中的一个位图,此位图由图形图像及其属性的像素数据组成.因此Bitmap是用于处理由像素数据定义的图像的对象.该类的主要方法和属性如下: 1. GetP ...

  8. c#图像处理入门(-bitmap类和图像像素值获取方法) 转

    一.Bitmap类 Bitmap对象封装了GDI+中的一个位图,此位图由图形图像及其属性的像素数据组成.因此Bitmap是用于处理由像素数据定义的图像的对象.该类的主要方法和属性如下: 1. GetP ...

  9. 【UE4】如何获取/下载虚幻4(Unreal Engine4)源码

    在官网中点击[获取虚幻引擎]可以看到,虚幻4完整源代码已经放在Github上,所以与其用百度搜别人的资源,当然是直接上Github下啊. 主要步骤如下: 注册一个Github帐号,这个没啥值得说的. ...

随机推荐

  1. phpmyadmin的安装和使用

    首先在phpmyadmin的官方网站的下载页面根据自己的PHP以及MYSQL的版本下载对应的phpmyadmin版本. 图中红框部分标识此版本支持度额PHP版本以及MYADL版本. 比如此版本就是支持 ...

  2. Mako

    from:  http://www.yeolar.com/note/2012/08/26/mako-usage/ Python模板库Mako的用法(选译自官方文档) Yeolar 2012-08-26 ...

  3. EDIUS设置采集磁带的方法

    EDIUS作为一款应用广泛的非线性视频编辑软件,将磁带记录的视频信号采集为可以编辑的数字视频信号的使用还是十分广泛的,毕竟磁带不同于数字存储单元,它在批量化的视频录制中表现出很大的优势.下面,小编跟大 ...

  4. alpha预乘

    将(r,g,b,a)变为(r*a,g*a,b*a,a)的操作称为alpha预乘. 对于alpha预乘的图片,应使用(One,OneMinusSrcAlpha)进行混合. 使用alpha预乘方式混合出来 ...

  5. android电视安装爱奇艺等不能看视频问题

    下载地址: http://pan.baidu.com/s/1dDoxA29

  6. Oracle视图详解

    转载自:http://blog.itpub.net/29785807/viewspace-1270120/ 一. 视图的定义 视图(view),也称虚表, 不占用物理空间,这个也是相对概念,因为视图本 ...

  7. DW(三):polybase基本理论

    PolyBase is a technology that accesses and combines(整合) both non-relational and relational data, all ...

  8. Ext JS treegrid 发生的在tree上增加itemclick 与在其它列上增加actioncolumn 发生事件冲突(event conflict)的解决办法

    Ext JS treegrid 发生的在tree上增加itemclick 与在其它列上增加actioncolumn 发生事件冲突(event conflict)的解决办法 最近在适用Ext JS4开发 ...

  9. WEB用户访问控制方法

    分享到 一键分享 QQ空间 新浪微博 百度云收藏 人人网 腾讯微博 百度相册 开心网 腾讯朋友 百度贴吧 豆瓣网 搜狐微博 百度新首页 QQ好友 和讯微博 更多... 百度分享 一直以来,我对用户/权 ...

  10. 【python】sys.argv[]的用法

    在学python的过程中,一直弄不明白sys.argv[]的意思,虽知道是表示命令行参数,但还是有些稀里糊涂的感觉. 今天又好好学习了一把,总算是大彻大悟了. Sys.argv[]是用来获取命令行参数 ...