详解opencv去除背景算法的方法比较
作者:Stark_Jarvis 发布时间:2022-10-08 08:48:08
最近做opencv项目时,使用肤色分割的方法检测目标物体时,背景带来的干扰非常让人头痛。于是先将背景分割出去,将影响降低甚至消除。由于初次接触opencv,叙述不当的地方还请指正。
背景减除法
(以下文字原文来源于https://docs.opencv.org/3.4.7/d8/d38/tutorial_bgsegm_bg_subtraction.html)
背景减除法是很多基于视觉的应用的一个主要预处理步骤。例如使用一个静止的摄像头拍摄进出房间的人数,或是交通摄像头捕获车辆信息等。在以上的例子中,首先你需要单独把人和交通工具提取出来。从技术上来说,你需要从静止的背景中提取移动前景目标。
通常情况下,我们的背景往往是未知的,因此需要通过一定的方法得到视频背景,然后用新的图像减去背景图片即可。
在opencv中提供了几种背景减除的方法:
(1)BackgroundSubtractorMOG
这是基于高斯混合模型的算法,混合模型表示了观测数据在总体中的概率分布,高斯分布即正态分布,正态分布如下图:
(图片来源于网络)
而高斯混合模型就是使用高斯分布的混合模型,由于高斯分布具有良好的数学性质和计算性能,它的概率分布遵循高斯分布。
cv2.bgsegm.createBackgroundSubtractorMOG()使用时可以不用传入参数
import cv2
cap = cv2.VideoCapture(0)
fgbg = cv2.bgsegm.createBackgroundSubtractorMOG()
se = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
while cap.isOpened():
ret, frame = cap.read()
# 用于计算前景掩模
fgmask = fgbg.apply(frame)
_, binary = cv2.threshold(fgmask, 215, 255, cv2.THRESH_BINARY)
binary = cv2.morphologyEx(binary, cv2.MORPH_OPEN, se)
res = cv2.bitwise_and(frame, frame, mask=binary)
cv2.imshow("res", res)
if cv2.waitKey(1000 // 12) & 0xff == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
运行结果:
(2)BackgroundSubtractorMOG2
它是改进的高斯混合模型,为各个参数设置了一些合适的值。
import cv2
cap = cv2.VideoCapture(0)
fgbg = cv2.createBackgroundSubtractorMOG2()
se = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
while cap.isOpened():
ret, frame = cap.read()
fgmask = fgbg.apply(frame)
_, binary = cv2.threshold(fgmask, 215, 255, cv2.THRESH_BINARY)
binary = cv2.morphologyEx(binary, cv2.MORPH_OPEN, se)
backImage = fgbg.getBackgroundImage()
res = cv2.bitwise_and(frame, frame, mask=binary)
cv2.imshow("backImage", backImage)
cv2.imshow("res", res)
if cv2.waitKey(1000 // 12) & 0xff == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
运行结果:
(3)BackgroundSubtractorGMG
GMG:Geometric Multigid,几何多重网格。它默认使用前120帧图像进行建模,使用贝叶斯推断方法判断可能的前景物体。
import cv2
cap = cv2.VideoCapture(0)
fgbg = cv2.bgsegm.createBackgroundSubtractorGMG()
se = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
while cap.isOpened():
ret, frame = cap.read()
fgmask = fgbg.apply(frame)
_, binary = cv2.threshold(fgmask, 215, 255, cv2.THRESH_BINARY)
binary = cv2.morphologyEx(binary, cv2.MORPH_OPEN, se)
res = cv2.bitwise_and(frame, frame, mask=binary)
cv2.imshow("res", res)
if cv2.waitKey(1000 // 12) & 0xff == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
运行结果:
以上这三种方法对于检测运动物体行之有效,但如果检测静态物体就不适合了。
帧差法
在可以确定背景时采用帧差法,此方法不仅可以用于动态目标检测,也能检测静态目标。
帧差法需要一个变量来检测当前是第几帧。即通过后面的帧减去第一帧得到所需前景。
import cv2
cap = cv2.VideoCapture(0)
frameNum = 0
while cap.isOpened():
ret, frame = cap.read()
frameNum += 1
tmp = frame.copy()
if frameNum == 1:
bgFrame = cv2.cvtColor(tmp, cv2.COLOR_BGR2GRAY)
elif frameNum > 1:
foreFrame = cv2.cvtColor(tmp, cv2.COLOR_BGR2GRAY)
foreFrame = cv2.absdiff(foreFrame, bgFrame)
_, thresh = cv2.threshold(foreFrame, 30, 255, cv2.THRESH_BINARY)
gaussian = cv2.GaussianBlur(thresh, (3, 3), 0)
cv2.imshow('gaussian', foreFrame)
if cv2.waitKey(1000 // 12) & 0xff == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
运行结果:
上述除了使用滤波的方法,也可以直接用cv2.subtract()进行图像减法运算。
来源:https://blog.csdn.net/weixin_41076275/article/details/105466958
猜你喜欢
- 单线程+多任务异步协程协程在函数(特殊函数)定义的时候,使用async修饰,函数调用后,内部语句不会立即执行,而是会返回一个协程对象任务对象
- 保存为.py文件后 运行脚本在后面添加进程名称即可 比如:python proinfo.py qq 即可获取QQ的进程信息,注意不区分大小写
- 昨天在得写“RSS收藏”栏目展现的时候我让RSS的列表用弹出的形式展现了,开始是直接的控制 style.display 来做的,但是感觉有点
- 本文实例讲述了Python yield的用法。分享给大家供大家参考,具体如下:yield的英文单词意思是生产,刚接触Python的时候感到非
- 一、牛顿多项式拉格朗日多项式的公式不具备递推性,每个多项式需要单独构造。但很多时候我们需要从若干个逼近多项式选择一个。这个时候我们就需要一个
- cv2库在opencv库内,因此需要下载opencv-python1、打开windows命令行:win+Rcmd2、更新pip版本(不一定要
- 在计算机和信息技术领域里 I/O 这个术语表示输入 / 输出 ( 英语:Input / Output ) ,通常指数据在存储器(内部和外部)
- 一下文件执行将产生乱码,切.log文件显示问好,打不开import loggingdef shop_logging(name):  
- 1、为图片加入水印功能 Dim Jpeg Set Jpeg = Server.Create
- 前言最近用Django写项目的时候用到了数据的传递,一窍不通,查了点资料。记录一下。水平不高,瓜不保熟。 从两方面来说:从后端传递
- 通过XSL转换XML文件 最近,我喜欢上了XML编程,但又苦于它的美观程度又不够,找了许多书才搞定。用XML好是蛮好,但它还是不太适合做显示
- python图片生成视频MP4import osimport cv2# 要被合成的多张图片所在文件夹# 路径分隔符最好使用“/”,而不是“\
- 导语哈喽!我是木木子,今天又想我了嘛?之前不是出过一期Python美颜相机嘛?不知道你们还记得不?这一期的话话题还是围绕上期关于颜值方面来走
- 如果你从未为MySQL设置根用户密码,服务器在以根用户身份进行连接时不需要密码。但是,建议你为每个账户设置密码。如果你以前设置了根用户密码,
- $str=preg_replace("/\s+/", " ", $str); //过滤多余回车 $s
- 本文实例为大家分享了python实现手机销售管理系统的具体代码,供大家参考,具体内容如下要求如下:手机销售系统 &nb
- 本文实例讲述了python类和继承定义与用法。分享给大家供大家参考。具体如下:class Employee: passlee =
- 最近在用python连接sqlserver读取数据库,读取数据时候在本机电脑正常,但是把程序部署到服务器运行时一直报错“未发现数据源名称并且
- 在我们常用的系统windows和Linux系统中有很多支持的压缩包格式,包括但不限于以下种类:rar、zip、tar,以下的标准库的作用就是
- Python中生成器和迭代器的区别(代码在Python3.5下测试):Num01–>迭代器定义:对于list、string、tuple