公司项目需要检测运动物体,我对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");
}

运行结果如图

高斯的缺点就是受光照影响太大,近距离效果不好。

种一棵树最好的时间是十年前,其次是现在。

最新文章

  1. iOS开发系列--C语言之数组和字符串
  2. 设备像素比devicePixelRatio简单介绍
  3. 使用 CSS 的 :before 和 :after 选择器做一个箭头样式
  4. div的contenteditable和placeholder蹦出的火花
  5. qt 5 数据库操作(mysql)
  6. zabbix图中出现中文乱码问题
  7. maven(一) maven到底是个啥玩意~
  8. 一道有趣的Twitter技术面试题
  9. 想在京津冀地区找个UI&amp;UE的工作靠啥?看看这篇博客
  10. LeetCode算法题-Maximum Product of Three Numbers(Java实现)
  11. 安装vs2017后造成无法打开xproj项目无法打开
  12. Web从入门到放弃&lt;4&gt;
  13. 13 Connectors: show contrast/oppistion
  14. 解决64bit不能连接access的问题
  15. Job for ssh.service failed because the control process exited with error code.......
  16. what&#39;s the python之模块
  17. iOS开发-UIButton浅谈
  18. ballerina 学习 三十 扩展开发(一)
  19. kubernetes实战(四):k8s持久化安装rabbitmq集群
  20. 代码版本控制:git使用

热门文章

  1. Android杂谈--网络状态判断
  2. dedecms首页怎么调用公司简介的内容
  3. maven搭建项目的时候,src/main/java无法建立的问题,提示信息The folder is already a source folder.(文件夹已经是源文件夹。)
  4. MatlabR2014a 安装破解详细图文教程(附下载链接(内附CVX工具箱))
  5. 目标检测--Rich feature hierarchies for accurate object detection and semantic segmentation(CVPR 2014)
  6. c# 清空txt文本文件的值
  7. 关于Rational Functional Tester (RFT)的简单介绍
  8. 学习记录 java随机数的产生机制
  9. asp.net(c#)修改时的赋值操作
  10. ASPxTreeList控件去根节点的新增修改操作(写在onCommandColumnButtonInitialize()事件中)