EmguCV学习——简单算法 差分与高斯
公司项目需要检测运动物体,我对opencv也没啥研究,google了好久看了好多方法,最简单的就是差分与高斯背景建模了。
旁边搞c++的同事正在搞更nb的算法,等出来了 我再转成C#版的分享。
先看差分
//移动窗口
[System.Runtime.InteropServices.DllImportAttribute("opencv_highgui2410.dll", EntryPoint = "cvMoveWindow")]
public static extern void cvMoveWindow([System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string name, int x, int y);
//代表x帧差分,可以自由更改
static int USE_N_FRAMES_DIFF = ; public void PicDiff(string videoPath)
{
int iFrameIndex = ; IntPtr pIplGrayImg = IntPtr.Zero; IntPtr[] pIplFrameDiff = new IntPtr[USE_N_FRAMES_DIFF - ]; IntPtr[] pIplFrame = new IntPtr[USE_N_FRAMES_DIFF]; IntPtr CatchFrame = CvInvoke.cvCreateFileCapture(videoPath);
// 得到总帧数
var count = CvInvoke.cvGetCaptureProperty(CatchFrame, Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_COUNT);
// 视频宽度
int wd = (int)CvInvoke.cvGetCaptureProperty(CatchFrame, Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_WIDTH);
// 视频高度
int hg = (int)CvInvoke.cvGetCaptureProperty(CatchFrame, Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_HEIGHT);
//// 当前帧位置
//CvInvoke.cvGetCaptureProperty(CatchFrame, Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_POS_FRAMES);
//// 帧频
CvInvoke.cvGetCaptureProperty(CatchFrame, Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FPS); CvInvoke.cvNamedWindow("source");
CvInvoke.cvNamedWindow("Out");
cvMoveWindow("source", , );
cvMoveWindow("Out", , );
IntPtr FrameImg; IntPtr rawImage = IntPtr.Zero;
rawImage = CvInvoke.cvCreateImage(new Size(wd, hg), Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, );
IntPtr pIplFrameDiffOr = IntPtr.Zero;
IntPtr pIplFrameDiffOrCC = IntPtr.Zero;
IntPtr pIplFrameSmooth = IntPtr.Zero;
pIplFrameDiffOr = CvInvoke.cvCreateImage(new Size(wd, hg), Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, );
pIplFrameDiffOrCC = CvInvoke.cvCreateImage(new Size(wd, hg), Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, );
pIplFrameSmooth = CvInvoke.cvCreateImage(new Size(wd, hg), Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, ); while ((FrameImg = CvInvoke.cvQueryFrame(CatchFrame)) != IntPtr.Zero)
{ Rectangle cr = CvInvoke.cvGetImageROI(FrameImg); pIplGrayImg = CvInvoke.cvCreateImage(cr.Size, Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, ); CvInvoke.cvCvtColor(FrameImg, pIplGrayImg, Emgu.CV.CvEnum.COLOR_CONVERSION.BGR2GRAY); CvInvoke.cvSaveImage(savename, pIplGrayImg, IntPtr.Zero);
pIplFrame[iFrameIndex % USE_N_FRAMES_DIFF] = pIplGrayImg; if (iFrameIndex >= USE_N_FRAMES_DIFF - )
{
for (int i = ; i < USE_N_FRAMES_DIFF - ; i++)
{ CvInvoke.cvAbsDiff(pIplFrame[i], pIplFrame[i + ], rawImage);
pIplFrameDiff[i] = rawImage;
CvInvoke.cvThreshold(pIplFrameDiff[i], pIplFrameDiff[i], , , Emgu.CV.CvEnum.THRESH.CV_THRESH_BINARY);
//上面第三个参数为设置的阀值以此来根据物体运动时前后帧的差异产生白点
} for (int i = ; i < USE_N_FRAMES_DIFF - ; i++)
{
CvInvoke.cvOr(pIplFrameDiff[i], pIplFrameDiff[i + ], pIplFrameDiffOr, IntPtr.Zero); if (i + < USE_N_FRAMES_DIFF - )
{
CvInvoke.cvCopy(pIplFrameDiffOr, pIplFrameDiff[i + ], IntPtr.Zero);
} }
} CvInvoke.cvShowImage("source", FrameImg);
CvInvoke.cvShowImage("Out", pIplFrameDiffOr); CvInvoke.cvWaitKey();
iFrameIndex++; }
}
程序运行结果如图所示

高斯背景建模
public void guassModel(string videoPath)
{
int iFrameIndex = ;
IntPtr CatchFrame = CvInvoke.cvCreateFileCapture(videoPath);
// 得到总帧数
var count = CvInvoke.cvGetCaptureProperty(CatchFrame, Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_COUNT);
// 视频宽度
int wd = (int)CvInvoke.cvGetCaptureProperty(CatchFrame, Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_WIDTH);
// 视频高度
int hg = (int)CvInvoke.cvGetCaptureProperty(CatchFrame, Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_HEIGHT);
//// 帧频
CvInvoke.cvGetCaptureProperty(CatchFrame, Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FPS);
IntPtr background = CvInvoke.cvCreateImage(new Size(wd, hg), Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, );
IntPtr foreground = CvInvoke.cvCreateImage(new Size(wd, hg), Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, ); IntPtr FrameImg;
Emgu.CV.VideoSurveillance.BGStatModel<Bgr> bg = null;
CvInvoke.cvNamedWindow("bg");
CvInvoke.cvNamedWindow("fg");
CvInvoke.cvNamedWindow("source");
cvMoveWindow("bg", , );
cvMoveWindow("gf", , );
cvMoveWindow("source", , );
while ((FrameImg = CvInvoke.cvQueryFrame(CatchFrame)) != IntPtr.Zero)
{
Image<Bgr, byte> FramePic = new Image<Bgr, byte>(wd, hg);
CvInvoke.cvCopy(FrameImg, FramePic, IntPtr.Zero);
iFrameIndex++;
if (iFrameIndex == )
{
//高斯背景建模参数
Emgu.CV.Structure.MCvGaussBGStatModelParams pstruct = new MCvGaussBGStatModelParams();
pstruct.win_size = ;
pstruct.n_gauss = ;
pstruct.bg_threshold = 0.7;
pstruct.std_threshold = 3.5;
pstruct.minArea = ;
pstruct.weight_init = 0.333;
pstruct.variance_init = ;
bg = new Emgu.CV.VideoSurveillance.BGStatModel<Bgr>(FramePic, ref pstruct);
}
else
{
CvInvoke.cvShowImage("source", FrameImg);
CvInvoke.cvWaitKey();
//更新
bg.Update(FramePic);
background = bg.BackgroundMask;
CvInvoke.cvShowImage("bg", background);
CvInvoke.cvWaitKey();
foreground = bg.ForegroundMask;
CvInvoke.cvShowImage("fg", foreground);
CvInvoke.cvWaitKey();
}
}
CvInvoke.cvDestroyWindow("source");
CvInvoke.cvDestroyWindow("bg");
CvInvoke.cvDestroyWindow("fg");
}
运行结果如图

高斯的缺点就是受光照影响太大,近距离效果不好。
种一棵树最好的时间是十年前,其次是现在。
EmguCV学习——简单算法 差分与高斯的更多相关文章
- EmguCV学习——简单使用
关于EmguCV我就不多说了,是对应于OpenCV的一套net库. 公司是视觉方面的业务,我又不会c++(好想会啊,正在学习中).由于各种需求,自己觉得对c++不是特别感冒,所以选用了net下的ope ...
- [置顶] 小白学习KM算法详细总结--附上模板题hdu2255
KM算法是基于匈牙利算法求最大或最小权值的完备匹配 关于KM不知道看了多久,每次都不能完全理解,今天花了很久的时间做个总结,归纳以及结合别人的总结给出自己的理解,希望自己以后来看能一目了然,也希望对刚 ...
- 记录:EM 算法估计混合高斯模型参数
当概率模型依赖于无法观测的隐性变量时,使用普通的极大似然估计法无法估计出概率模型中参数.此时需要利用优化的极大似然估计:EM算法. 在这里我只是想要使用这个EM算法估计混合高斯模型中的参数.由于直观原 ...
- 从 SGD 到 Adam —— 深度学习优化算法概览(一) 重点
https://zhuanlan.zhihu.com/p/32626442 骆梁宸 paper插画师:poster设计师:oral slides制作人 445 人赞同了该文章 楔子 前些日在写计算数学 ...
- 学习cordic算法所得(流水线结构、Verilog标准)
最近学习cordic算法,并利用FPGA实现,在整个学习过程中,对cordic算法原理.FPGA中流水线设计.Verilog标准有了更加深刻的理解. 首先,cordic算法的基本思想是通过一系列固定的 ...
- Javascript学习-简单测试环境
Javascript学习-简单测试环境 在<JavaScript忍者秘籍>2.4测试条件基础知识中,作者给出了一个精简版的assert和assert组的实现,对于初学者而言,这无疑是一个很 ...
- 学习排序算法(一):单文档方法 Pointwise
学习排序算法(一):单文档方法 Pointwise 1. 基本思想 这样的方法主要是将搜索结果的文档变为特征向量,然后将排序问题转化成了机器学习中的常规的分类问题,并且是个多类分类问题. 2. 方法流 ...
- CPD轮播广告库的简单算法
在广告的领域中,有一种广告形式,采用的是CPD的售卖模式,为了对流量进行拆分,媒体方会对广告位进行轮播拆分.比如一个广告位,被拆成了10轮播,那么在广告主来预订广告位的时候,这个时候就可以告诉广告主, ...
- php实现简单算法2
php实现简单算法2 去弄php手册,里面有数据结构,有数据结构就好办了,我的算法基础那么好. 而且的话有数据结构的话再配合我脑中的那些算法了,我就都ok啦. 在手册里面搜索php数据结构就好 路径如 ...
随机推荐
- ceph--磁盘和rbd、rados性能测试工具和方法
我在物理机上创建了5台虚拟机,搭建了一个ceph集群,结构如图: 具体的安装步骤参考文档:http://docs.ceph.org.cn/start/ http://www.centoscn.com/ ...
- Gem5全系统模式下运行SPLASH-2 Benchmarks使用alpha ISA
Steps to run the SPLASH-2 Benchmarks on M5 in full system mode using the alpha ISA. This Guide is ai ...
- Windows应用替代方案接龙
使开源软件的优势: 开源安全产品的开发.测试和发布过程完全是透明的,同时提供产品的源代码及部分的文档.通过阅读源代码,大家可以清楚地了解开源安全技术的工作原理和实现方法,在选择开源安全技术时更有把握, ...
- [SSH 3]以网上商城项目浅谈spring配置
导读:在做ITOO项目的时候,就用到了容器+反射,从而运用了依赖注入和依赖查找.如果看过WCF端的配置文件,那么对于这个spring的配置就很容易理解.本篇博客,是对于自己做的一个小项目中所运用到的s ...
- ionic cordova social media sharing plugin
https://github.com/EddyVerbruggen/SocialSharing-PhoneGap-Plugin.git 从上面的连接下载 插件 1.肯定是要加入 下面的那个文件的吖 从 ...
- openstack openrpc
- EFDC_EE如何设置自适应时间步长
下图是EFDC_EE的运行时间参数的设置界面,在时间步长的设置中,如果“Safety Factor”参数,设置为非0,即可实现自适应时间步长的设置,但要注意如下几点: 1.“Safety Factor ...
- .net orm比较之dapper和Entity Framework6的简单测试比较
.net orm比较之dapper和Entity Framework6的简单测试比较
- centos7 docker1.12 私有仓库
docker1.12私有仓库 参考:http://www.cnblogs.com/xcloudbiz/articles/5497037.html 参考:http://www.07net01.com/2 ...
- Python搭建简易HTTP服务(3.x版本和2.x版本的)
废话不多说,我们工作时经常会用到需要HTTP服务,如果不想搞那些复杂的Apache.IIS服务器等,这时我们就可以用python帮我们搭建一个简单的服务器.操作如下: 1.下载并安装一个python: ...