进行运动物体检测就是将动态的前景从静态的背景中分离出来。将当前画面与假设是静态背景进行比较发现有明显的变化的区域,就可以认为该区域出现移动的物体。在实际情况中由于光照阴影等因素干扰比较大,通过像素直接进行比较往往很容易造成误检。因此有不少算法被开发出来在进行前后景分离的时候对运动和其他因素造成的变动进行区分。opencv中提供了多种背景减除的算法,其中基于高斯混合模型(GMM)的cv2.BackgroundSubtractorMOG()cv2.BackgroundSubtractorMOG2()已经基于贝叶斯模型的cv2.bgsegm.createBackgroundSubtractorGMG()最为常用。

1) GMM法

GMM进行前后景分离最早是在2001年的文章An improved adaptive background mixture model for real-time tracking with shadow detection中提出的。其设计思路为:

  1. 在不知道图像历史的时候,假设每个像素点的值都是可以分解为一组adaptive Gaussian。adaptive是由于需要跟随光照条件的变化而变化。
  2. 像素值的历史由一组高斯分布进行建模,包括每个分布的权重。
  3. 每次新图像输入的时候都会用这一组高斯分布进行评估,如果像素匹配上其中一个分布就会认为这个像素属于背景,而高斯分布的均值和方差等参数会用当前像素的值进行更新。
  4. 标记为前景的像素通过connected component analysis进行分组。

    opencv的cv2.BackgroundSubtractorMOG()的函数就是对次方法的实现。

基于2004年提出的Improved adaptive Gausian mixture model for background subtractio和2006年提出的Efficient Adaptive Density Estimation per Image Pixel for the Task of Background Subtraction算法对上述GMM算法进行改良的就是opencv的cv2.BackgroundSubtractorMOG2()的函数。主要的提升是对每个像素都选择合适数量的高斯分布而非原来的全部相同的个数。此外,这个函数还允许是否检测阴影。

使用方法(以MOG2为例)

import cv2

cam = cv2.VideoCapture(0)

fgbg = cv2.createBackgroundSubtractorMOG()
while cam.isOpened():
ret, frame = cam.read()
if ret:
fgmask = fgbg.apply(frame)
# 通过腐蚀和膨胀过滤一些噪声
erode = cv2.erode(fgmask, (21, 21), iterations=1)
dilate = cv2.dilate(fgmask, (21, 21), iterations=1)
(_, cnts, _) = cv2.findContours(dilate.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for c in cnts:
c_area = cv2.contourArea(c)
if c_area < 1600 or c_area > 16000: # 过滤太小或太大的运动物体,这类误检概率比较高
continue
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 2)
cv2.imshow("origin", frame)
if cv2.waitKey(1) == ord('q'):
break
cv2.destroyAllWindows()

2)GMG法

根据2012年的文章Visual Tracking of Human Visitors under Variable-Lighting Conditions for a Responsive Audio Art Installation, opencv开发了相应的函数cv2.bgsegm.createBackgroundSubtractorGMG() (好像在3.2中被放到了contrib中,在之前可以直接用cv2.createBackgroundSubtractorGMG()进行调用)。这个方法默认使用前120张图片进行背景的建模,并使用概率前景分割算法找到可能的前景(基于贝叶斯推测)。为了更好适应不同光照变化的影响,新的图片的权重比旧图片要高。

使用方法

cam = cv2.VideoCapture(0)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (8, 8))
fgbg = cv2.bgsegm.createBackgroundSubtractorGMG(initializationFrames=10)
while cam.isOpened():
ret, frame = cam.read()
if ret:
fgmask = fgbg.apply(frame)
fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel) # 过滤噪声
(_, cnts, _) = cv2.findContours(dilate.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for c in cnts:
c_area = cv2.contourArea(c)
if c_area < 1600 or c_area > 16000: # 过滤太小或太大的运动物体,这类误检概率比较高
continue
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 2)
cv2.imshow("origin", frame)
if cv2.waitKey(1) == ord('q'):
break
cv2.destroyAllWindows()

参考:

  1. https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_video/py_bg_subtraction/py_bg_subtraction.html
  2. http://android4arduino.com/computer-vision/motion-detection/
  3. https://www.pyimagesearch.com/2015/05/25/basic-motion-detection-and-tracking-with-python-and-opencv/
  4. https://docs.opencv.org/3.0-beta/modules/video/doc/motion_analysis_and_object_tracking.html?highlight=createbackgroundsubtractormog

利用opencv进行移动物体检测的更多相关文章

  1. opencv,关于物体检测

    关于物体检测 环境:opencv 2.4.11+vs2013 参考: http://www.cnblogs.com/tornadomeet/archive/2012/06/02/2531705.htm ...

  2. OpenCV学习 物体检测 人脸识别 填充颜色

    介绍 OpenCV是开源计算机视觉和机器学习库.包含成千上万优化过的算法.项目地址:http://opencv.org/about.html.官方文档:http://docs.opencv.org/m ...

  3. OpenCV 使用光流法检测物体运动

    OpenCV 可以使用光流法检测物体运动,贴上代码以及效果. // opticalflow.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" ...

  4. [PyImageSearch] Ubuntu16.04 使用深度学习和OpenCV实现物体检测

    上一篇博文中讲到如何用OpenCV实现物体分类,但是接下来这篇博文将会告诉你图片中物体的位置具体在哪里. 我们将会知道如何使用OpenCV‘s的dnn模块去加载一个预训练的物体检测网络,它能使得我们将 ...

  5. OpenCV平面物体检测

    平面物体检测 这个教程的目标是学习如何使用 features2d 和 calib3d 模块来检测场景中的已知平面物体. 测试数据: 数据图像文件,比如 “box.png”或者“box_in_scene ...

  6. 利用modelarts和物体检测方式识别验证码

    近来有朋友让老山帮忙识别验证码.在github上查看了下,目前开源社区中主要流行以下几种验证码识别方式: tesseract-ocr模块: 这是HP实验室开发由Google 维护的开源 OCR引擎,内 ...

  7. OpenCV神技——人脸检测,猫脸检测

    简介   OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux.Windows.Android和Mac OS操作系统上.它轻量级而且高效--由一系列 C 函数和少量 ...

  8. 如何利用OpenCV自带的级联分类器训练程序训练分类器

    介绍 使用级联分类器工作包括两个阶段:训练和检测. 检测部分在OpenCVobjdetect 模块的文档中有介绍,在那个文档中给出了一些级联分类器的基本介绍.当前的指南描述了如何训练分类器:准备训练数 ...

  9. OPENCV图像特征点检测与FAST检测算法

    前面描述角点检测的时候说到,角点其实也是一种图像特征点,对于一张图像来说,特征点分为三种形式包括边缘,焦点和斑点,在OPENCV中,加上角点检测,总共提供了以下的图像特征点检测方法 FAST SURF ...

随机推荐

  1. mysql 设置、更改、找回密码

    1,新装mysql,添加密码 mysqladmin -u root password NEWPASSWORD 2,记得旧密码,改密码 mysqladmin -u root -p'OLDPASSWORD ...

  2. 4990: [Usaco2017 Feb]Why Did the Cow Cross the Road II 线段树维护dp

    题目 4990: [Usaco2017 Feb]Why Did the Cow Cross the Road II 链接 http://www.lydsy.com/JudgeOnline/proble ...

  3. Linux之临时配置网络(ip,网关,dns)+永久配置

    作业一:临时配置网络(ip,网关,dns)+永久配置 配置网络信息 [root@localhost ~]# ifconfig eno16777736: flags=4163<UP,BROADCA ...

  4. jquery .stop()的用法

    jquery的.stop()的用法: 目的:为了 了解stop()的用法,举个例子,直观的方式看看. 实物:一个id="animater"的div包含了一段文字.(以下用anima ...

  5. embOS ARM and Cortex Library Object and Symbol List

    OS_Alloc.o OS_free OS_Alloc.o OS_malloc OS_Alloc.o OS_realloc OS_ARM720_MMU.o OS_ARM720_CACHE_CleanR ...

  6. socket.io常用api

    1. 服务端 io.on('connection',function(socket)); 监听客户端连接,回调函数会传递本次连接的socket io.sockets.emit('String',dat ...

  7. java调用sap的webservice(需要登录验证)

    1.Base64.java /* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache ...

  8. hadoop ha 读取 activce状态的活动节点

    方式一 package com.xxx.hadoop; import com.sun.demo.jvmti.hprof.Tracker; import com.sun.xml.bind.util.Wh ...

  9. Glide终于解决了同时绑定多个webp格式图片的问题

    前端时间,要给项目换个图片加载的库,使用Glide 3.7版本进行测试, 发现在快速滑动列表(每个item都会加载一个app的图标,采用webp格式,即同时加载多个webp格式)的时候,一屏至少有2- ...

  10. shell编程学习笔记(十一):Shell中的while/until循环

    shell中也可以实现类似java的while循环 while循环是指满足条件时,进行循环 示例: #! /bin/sh index=10 while [ $index -gt 0 ] do inde ...