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数据结构就好 路径如 ...
随机推荐
- PL/0与Pascal-S编译器程序详细注释
学校编译课的作业之一,要求阅读两个较为简单的编译器的代码并做注释, 个人感觉是一次挺有意义的锻炼, 将自己的心得分享出来与一同在进步的同学们分享. 今后有时间再做进一步的更新和总结,其中可能有不少错误 ...
- 使用git管理github上的项目
使用git可以把我们的项目代码上传到github上面去,方便自己管理,如何使用git?觉得是每位程序猿所必需要有的谋生技能,所以在此记录一下自己学会使用的这个过程: 一.需要注册github账号,这样 ...
- Android开发-API指南-<meta-data>
<meta-data> 英文原文:http://developer.android.com/guide/topics/manifest/meta-data-element.html 采集( ...
- eclipse打开出错 Error: opening registry key 'Software\JavaSoft\Java Runtime Environment'
eclipse出现注册错误:①在“打开”输入框中输入“regedit”命令,删除注册表的HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\ 的INSTALLDIR删除. 或者 ...
- 线程中CreateEvent和SetEvent及WaitForSingleObject的用法
首先介绍CreateEvent是创建windows事件的意思,作用主要用在判断线程退出,线程锁定方面. CreateEvent 函功能描述:创建或打开一个命名的或无名的事件对象. EVENT有两种状态 ...
- js对象的相关操作方法
//在js的对象中可以直接将一个方法赋值给一个属性,这种方法非常好用. //在js中虽然没有像其他语言中的class关键字,但是我们也可以用函数,字面量的方式来模拟. var myHome={ nam ...
- Delphi Form的释放和隐藏:free,hide,close
form.Free - 释放Form占用的所有资源.Free后,Form指针不能再使用,除非对Form重新赋值. form.Hide - 隐藏Form.可以调用form.Show再 ...
- 关于hbase的read操作的深入研究 region到storefile过程
这里面说的read既包括get,也包括scan,实际底层来看这两个操作也是一样的.我们将要讨论的是,当我们从一张表读取数据的时候hbase到底是怎么处理的.分二种情况来看,第一种就是表刚创建,所有pu ...
- kbengine mmo源码(完整服务端源码+资源+完整客户端源码)
本项目作为kbengine服务端引擎的客户端演示而写 更新kbengine插件库(https://github.com/kbengine/kbengine_unity3d_plugins): ...
- u-boot board_uart_init流程
/** ****************************************************************************** * @author Maox ...