详解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
猜你喜欢
- TensorFlow是一个基于数据流编程(dataflow programming)的符号数学系统,被广泛应用于各类机器学习(machine
- 1.调整内存 sp_configure 'show advanced options',1 GO RECONFIGURE G
- 前言工作中经常会使用到将宽表变成窄表,例如这样的形式编号编码单位1单位2单位3单位4.................. &nbs
- 如下所示:# 访问百度,模拟自动输入搜索# 代码中引入selenium版本为:3.4.3# 通过Chrom浏览器访问发起请求# Chrom版
- 实验环境1.安装Python 3.72.安装requests, bs4,pymysql 模块实验步骤1.安装环境及模块可参考https://
- 组合集总计: group by with rollup/cube grouping sets 子查询按执行方式分:标准子查询、关联子查询 标
- 之前希望在手机端使用深度模型做OCR,于是尝试在手机端部署tensorflow模型,用于图像分类。思路主要是想使用tflite部署到安卓端,
- 目录楔子faker使用方法基本使用地理信息类基础信息类计算机基础、Internet信息类网络基础信息类浏览器信息类数字类文本、加密类时间信息
- 密码保护是注册过程中的关键环节,尤其是对帐户安全级别比较高的网站,尤其在账号被盗或者涉及安全登录等问题的情况下,密码保护问题作为用户身份识别
- 图像的二值化或阈值化(Binarization)旨在提取图像中的目标物体,将背景以及噪声区分开来。通常会设定一个阈值T,通过T将图像的像素划
- MySQL手册中find_in_set函数的语法解释:FIND_IN_SET(str,strlist)str 要查询的字符串 strlist
- Python错误SyntaxError: unexpected EOF while parsing含义是解释器到底了都没找到它要找到的东西出
- 这个程序将记数器的数字放在ACCESS数据库中,当然你也能用你希望其它的ODBC数据源.这个程序从URL中读取记数信息.如下:< IM
- 其实golang用一个函数可以构建一个并发队列,现在编写一个灵活可控的队列程序先定义一个工作type Worker struct { &nb
- 1、保存列表为.txt文件#1/list写入txtipTable = ['158.59.194.213', '18.
- Python实现按某一列关键字分组,并计算各列的平均值,并用该值填充该分类该列的nan值。DataFrame数据格式fillna方式实现gr
- 所谓产品其实最终展现在用户面前的只是界面而已,所谓界面绝大多数时候只包括两个部分:图片、文字。重视界面上的每一个像素和每一个文字是UED的基
- print函数python输出主要使用print函数,print函数介绍:print(*objects, sep=' ',
- #mysqldump --help1.mysqldump的几种常用方法:(1)导出整个数据库(包括数据库中的数据)mysqldump -u
- 使用python的turtle库画一个方格和圆打开python编译器,导入turtle库from turtle import *首先画一个距