Opencv实现运动检测
运动检测多种多样,这里的需求只是检测到有运动物体就行了,而且
要尽量减少误报的情况。另外尽量降低CPU的消耗,因为最终需要在树莓派上面运行。
看了一些中文的文章,发现无法很好地理解别人说的内容,反而是外国人写的文章比较实在:
这里的思路和代码来自一篇外文博客,原文来自:http://blog.cedric.ws/opencv-simple-motion-detection
这里博主使用了差值的办法来检测运动。也就是准备三幅图像,分布叫做prev, current 和next
这三幅图像是一个视频的前后三帧。
可以这样表示检测的过程:
diff1 = prev - next
diff2 = current - next
result = diff1 & diff2
用opencv的语言来说,就是:
absdiff(prev_frame, next_frame, d1);
absdiff(current_frame, next_frame, d2);
bitwise_and(d1, d2, result);
另外,最后还要加一个阈值,因为很细小的运动,比如窗帘被气流吹动的行为会造成一个误报的
现象,这里主要是需要检测大动作,比如一只小狗走来走去的现象。
threshold(result, result, , , CV_THRESH_BINARY);
检测的结果如下:

可以说有初步成效了。
下面,可以在上图的白色区域放置一个矩形框(用opencv可以很轻松地做到)
这里博主贴出了代码:
// loop over image and detect changes
for(int j = y_start; j < y_stop; j+=){ // height
for(int i = x_start; i < x_stop; i+=){ // width
// check if at pixel (j,i) intensity is equal to 255
// this means that the pixel is different in the sequence
// of images (prev_frame, current_frame, next_frame)
if(static_cast(motion.at<uchar>(j,i)) == )
{
number_of_changes++;
if(min_x>i) min_x = i;
if(max_x<i) max_x = i;
if(min_y>j) min_y = j;
if(max_y<j) max_y = j;
}
}
}
从代码里面看,这里遍历了整一幅差值图像(也就是上面的result图),并且将所有为255亮度的
点统计起来,并且生成两个结果:
1.number of changes,也就是变化为100%的点的数量
2.max值和min值,用于在变化周围画矩形
这是画矩形的代码:
if(number_of_changes){
//check if not out of bounds
if(min_x- > ) min_x -= ;
if(min_y- > ) min_y -= ;
if(max_x+ < result.cols-) max_x += ;
if(max_y+ < result.rows-) max_y += ;
// draw rectangle round the changed pixel
Point x(min_x,min_y);
Point y(max_x,max_y);
Rect rect(x,y);
Mat cropped = result(rect);
cropped.copyTo(result_cropped);
rectangle(result,rect,color,);
}
这里的处理number of changes应该是判断大于某个值的时候再画,因为
可能出现误报。
优化
到这里为止,可以得到两个结论:
1.这个算法是比较简单的,也就是CPU消耗比较少。
2.这个算法存在着不足,也就是误报的问题。
因为这个算法要应用到树莓派中,所以特别复杂但是精准的办法就不可取。
上面的办法可以做两点优化,第一个是判断number of changes大于某个值的时候再画,
第二个是判断图像中出现移动物体时延迟一段时间后再判断,这样会减少误报。
// If a lot of changes happened, we assume something changed.
if(number_of_changes>=there_is_motion)
{
if(number_of_sequence>){
saveImg(result,DIR,EXT,DIR_FORMAT.c_str(),FILE_FORMAT.c_str());
saveImg(result_cropped,DIR,EXT,DIR_FORMAT.c_str(),CROPPED_FILE_FORMAT.c_str());
}
number_of_sequence++;
}
else
{
number_of_sequence = ;
// Delay, wait a 1/2 second.
cvWaitKey (DELAY);
}
注意到,这里是检测到了物体再delay,而不是每次都delay。这样会保证整个检测系统的运行
质量。
另一个办法是通过标准差来检测先后的变化,当然这个办法会消耗额外的CPU,不过可以试试看
// calculate the standard deviation
Scalar mean, stddev;
meanStdDev(motion, mean, stddev);
// if not to much changes then the motion is real (neglect agressive snow, temporary sunlight)
if(stddev[] < max_deviation)
最后博主给出了代码(github上也有):
https://github.com/cedricve/motion-detection/blob/master/motion_src/src/motion_detection.cpp
因为目前没有可用的摄像头,买到之后试试博主的代码并且更新博客。
Opencv实现运动检测的更多相关文章
- 1.0.x-学习Opencv与MFC混合编程之---视频运动检测
源代码地址: http://download.csdn.net/detail/nuptboyzhb/3961668 版本1.0.x新增内容 视频运动检测 Ø 新建菜单项,Learning OpenCV ...
- OpenCV进阶之路:一个简化的视频摘要程序
一.前言 视频摘要又称视频浓缩,是对视频内容的一个简单概括,先通过运动目标分析,提取运动目标,然后对各个目标的运动轨迹进行分析,将不同的目标拼接到一个共同的背景场景中,并将它们以某种方式进行组合.视频 ...
- opencv笔记6:角点检测
time:2015年10月09日 星期五 23时11分58秒 # opencv笔记6:角点检测 update:从角点检测,学习图像的特征,这是后续图像跟踪.图像匹配的基础. 角点检测是什么鬼?前面一篇 ...
- 运动检测(前景检测)之(一)ViBe
运动检测(前景检测)之(一)ViBe zouxy09@qq.com http://blog.csdn.net/zouxy09 因为监控发展的需求,目前前景检测的研究还是很多的,也出现了很多新的方法和思 ...
- 运动检测(前景检测)之(二)混合高斯模型GMM
运动检测(前景检测)之(二)混合高斯模型GMM zouxy09@qq.com http://blog.csdn.net/zouxy09 因为监控发展的需求,目前前景检测的研究还是很多的,也出现了很多新 ...
- 学习OpenCV,看这些!
OpenCV简介: OpenCV 是一款功能强大的跨平台计算机视觉开源库,可以用于解决人机交互.物体检测.人脸识别等领域的问题.库本身是采用 C++ 编写的,但是同时也对 Python, Java, ...
- OpenCV ——背景建模之CodeBook(2)
1,CodeBook的来源 先考虑平均背景的建模方法.该方法是针对每一个像素,累积若干帧的像素值,然后计算平均值和方差,以此来建立背景模型,相当于模型的每一个像素含有两个特征值,这两个特征值只是单纯的 ...
- opencv 相关一个很好的博客
http://blog.csdn.net/zouxy09/article/category/1218765 图像卷积与滤波的一些知识点 图像卷积与滤波的一些知识点zouxy09@qq.comhttp: ...
- OpenCV学习笔记二:OpenCV模块一览
注:本系列博客基于OpenCV 2.9.0.0 一,一览图: 二,模块: /* 基础库 */ 1,opencv_core(链接) ,opencv最基础的库.包含exception,point,rect ...
随机推荐
- [QTP/UFT12]无限延长试用期的方法
1. 删除C:\ProgramData隐藏目录下的SafeNet Sentinel文件夹 2.运行QTP安装目录下的bin\instdemo.exe 3. 重新运行QTP/UFT 12后即可恢复30天 ...
- SAM4E单片机之旅——22、GMAC和PHY的介绍与初始化
网络通信的作用不用多说,而这次进行的工作即是对以太网通信过程中,需要用到的硬件部分进行初始化,也介绍了发送和接收数据的方法. 由于较为复杂,所以使用了ASF框架.但是也会对用到的库函数的实现做一个介绍 ...
- Linux之格式化与挂载
格式化与挂载 一块硬盘要想被使用,要经过分区,格式化,挂载这三个步骤.前面我们讲过MBR分区和GPT分区. 下面我们就来讲一下如果格式化一个分区.其实很简单,一句话就能搞定了. 首先来查看一下sdb盘 ...
- Effective Java 21 Use function objects to represent strategies
Theory In the Java the function pointers is implemented by the declaring an interface to represent s ...
- MyCat 学习笔记 第十一篇.数据分片 之 分片数据查询 ( select * from table_name limit 100000,100 )
1 环境说明 VM 模拟3台MYSQL 5.6 服务器 VM1 192.168.31.187:3307 VM2 192.168.31.212:3307 VM3 192.168.31.150: 330 ...
- mysql中出现Incorrect DECIMAL value: '0' for column '' at row -1错误解决方案
本人开发项目时,在从一个服务器导出数据库到另一服务器时,存储过程中,报Incorrect DECIMAL value: '0' for column '' at row -1错误. 原因: 存储过程中 ...
- 从零开始学习Mysql的学习记录
2015/06/18 16:23更新,由于QQ邮件的图片链接失效了,请在云笔记链接查看 http://note.youdao.com/share/?id=f0b2ed30a3fc8e57c381e3d ...
- JS高级程序设计2nd部分知识要点2
ECMAScript中所有函数的参数都是按值传递的. 5种基本数据类型: Undfined,Null,Boolean,Number,String. 当代码在一个环境中执行时,会创建变量对象的一个作用域 ...
- 湖南师范大学第五届大学生计算机程序设计竞赛--G--修路
题目链接:http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=11464&courseid=132 题目: ...
- nyoj 42 一笔画问题 欧拉路径
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=42 欧拉回路,欧拉路径水题~ 代码: #include "stdio.h&quo ...