OpenCV学习之运动模板检测
来源:互联网 发布:centos 7.3安装nginx 编辑:程序博客网 时间:2024/06/07 22:41
运动模板检测
#include "cv.h"#include "highgui.h"#include <time.h> #include <math.h> #include <ctype.h> #include <stdio.h> // 不同的跟踪参数 const double MHI_DURATION = 0.5;const double MAX_TIME_DELTA = 0.5;const double MIN_TIME_DELTA = 0.05;// 用于运动检测的循环帧数,与机器速度及FPS设置有关 const int N = 2;IplImage **buf = 0;int last = 0;// 临时图像 IplImage *mhi = 0; // MHI: 运动历史图像 IplImage *orient = 0; // 方向 IplImage *mask = 0; // 有效的运动掩码 IplImage *segmask = 0; // 运动分割映射 CvMemStorage* storage = 0; // 临时存储区 // 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.; // 获取当前时间,以秒为单位 CvSize size = cvSize(img->width, img->height); // 获取当前帧尺寸 int i, idx1 = last, idx2; IplImage* silh; CvSeq* seq; CvRect comp_rect; double count; double angle; CvPoint center; double magnitude; CvScalar color; // 开始时为图像分配内存 or 帧尺寸改变时重新分配内存 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); //RGB帧图像格式转换为gray idx2 = (last + 1) % N; // index of (last - (N-1))th frame last = idx2; silh = buf[idx2]; // 相邻两帧的差 cvAbsDiff(buf[idx1], buf[idx2], silh); cvThreshold(silh, silh, diff_threshold, 1, CV_THRESH_BINARY); // 对差图像做二值化 cvUpdateMotionHistory(silh, mhi, timestamp, MHI_DURATION); // 更新运动历史 // convert MHI to blue 8u image // cvCvtScale的第四个参数 shift = (MHI_DURATION - timestamp)*255./MHI_DURATION // 控制帧差的消失速率 cvCvtScale(mhi, mask, 255. / MHI_DURATION, (MHI_DURATION - timestamp)*255. / MHI_DURATION); cvZero(dst); cvCvtPlaneToPix(mask, 0, 0, 0, dst); // B,G,R,0 convert to BLUE image // 计算运动的梯度方向以及正确的方向掩码 // Filter size = 3 cvCalcMotionGradient(mhi, mask, orient, MAX_TIME_DELTA, MIN_TIME_DELTA, 3); if (!storage) storage = cvCreateMemStorage(0); else cvClearMemStorage(storage); // 运动分割: 获得运动部件的连续序列 seq = cvSegmentMotion(mhi, segmask, storage, timestamp, MAX_TIME_DELTA); for (i = 0; i < seq->total; i++) { if (i < 0) { // 对整幅图像操作 comp_rect = cvRect(0, 0, size.width, size.height); color = CV_RGB(255, 255, 255); magnitude = 100; // 画线长度以及圆半径的大小控制 } else { // 第i个运动组件 comp_rect = ((CvConnectedComp*)cvGetSeqElem(seq, i))->rect; // 去掉小的部分 if (comp_rect.width + comp_rect.height < 100) continue; color = CV_RGB(255, 0, 0); magnitude = 30; //if(seq->total > 0) MessageBox(NULL,"Motion Detected",NULL,0); } // 选择组件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) = 所有像素值的和 count = cvNorm(silh, 0, CV_L1, 0); cvResetImageROI(mhi); cvResetImageROI(orient); cvResetImageROI(mask); cvResetImageROI(silh); // 检查小运动的情形 if (count < comp_rect.width*comp_rect.height * 0.05) // 像素的5% continue; // 画一个带箭头的记录以表示方向 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 = 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;}
阅读全文
0 0
- OpenCV学习之运动模板检测
- OpenCV:运动模板检测
- OpenCV学习之利用背景建模检测运动物体
- opencv之运动模板跟踪
- OpenCV学习——运动检测实例
- opencv学习---运动目标(前景)检测
- OpenCV之帧差法检测运动目标
- opencv 之运动物体检测(二)
- 【opencv】基于opencv实现运动目标检测之帧差法
- opencv运动检测实例
- OpenCV运动目标检测
- opencv三帧差分法运动检测
- opencv 运动目标检测
- opencv三帧差分法运动检测
- opencv三帧差分法运动检测
- python opencv运动检测
- opencv运动物体检测
- 1.0.x-学习Opencv与MFC混合编程之---视频运动检测
- win10蓝牙共享网络链接方法
- 获取session的几种方法
- VS下提示"不支持尝试执行的操作"
- 最大子数组的代码实现(非暴力方法)
- jquery系列教程1-选择器全解
- OpenCV学习之运动模板检测
- hdu 6073 Matching In Multiplication(2017 Multi-University Training Contest
- 【最短路入门专题1】 hdu 1874 B
- 易贝云网站管理系统 1.7.0 企业版
- Python---初识Scrapy框架
- VS 解决This function or variable may be unsafe
- spring+springmvc+mybatis的配置文件
- 武汉公布304个可售楼盘名单,保证供应稳定市场预期(蚌埠华瑞房地产评估)
- hdoj 6071 Lazy Running