详解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

这是基于高斯混合模型的算法,混合模型表示了观测数据在总体中的概率分布,高斯分布即正态分布,正态分布如下图:
(图片来源于网络)

详解opencv去除背景算法的方法比较

而高斯混合模型就是使用高斯分布的混合模型,由于高斯分布具有良好的数学性质和计算性能,它的概率分布遵循高斯分布。

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()

运行结果:

详解opencv去除背景算法的方法比较

(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()

运行结果:

详解opencv去除背景算法的方法比较

(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()

运行结果:

详解opencv去除背景算法的方法比较

以上这三种方法对于检测运动物体行之有效,但如果检测静态物体就不适合了。

帧差法

在可以确定背景时采用帧差法,此方法不仅可以用于动态目标检测,也能检测静态目标。
帧差法需要一个变量来检测当前是第几帧。即通过后面的帧减去第一帧得到所需前景。

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()

运行结果:

详解opencv去除背景算法的方法比较

上述除了使用滤波的方法,也可以直接用cv2.subtract()进行图像减法运算。

来源:https://blog.csdn.net/weixin_41076275/article/details/105466958

标签:opencv,去除背景
0
投稿

猜你喜欢

  • Python 合并多个TXT文件并统计词频的实现

    2023-01-09 12:16:08
  • FP-growth算法发现频繁项集——构建FP树

    2022-04-26 16:22:52
  • Numpy实现矩阵运算及线性代数应用

    2022-10-18 17:55:50
  • Python Queue模块详解

    2023-01-13 00:42:02
  • GoFrame框架gset使用对比PHP Java Redis优势

    2023-11-24 04:08:58
  • xmlHTTP技术资料

    2008-01-05 13:39:00
  • Python轻松管理与操作文件的技巧分享

    2021-11-19 14:42:12
  • Python3.10动态修改Windows系统本地IP地址

    2021-07-21 01:10:59
  • Python利用redis-py实现哈希数据类型的常用指令操作

    2021-09-24 18:16:45
  • MySQL存储过程中的sql_mode问题

    2011-01-04 19:50:00
  • Python探索之Metaclass初步了解

    2023-12-22 10:25:37
  • 大家都对vertical-align的各说各话

    2008-06-19 12:11:00
  • python opencv实现图片缺陷检测(讲解直方图以及相关系数对比法)

    2021-02-03 19:41:24
  • MySQL如何统计一个数据库所有表的数据量

    2024-01-23 20:07:14
  • MySQL数据库远程连接开启方法

    2024-01-13 03:39:30
  • 透明数据加密(TDE)库的备份和还原

    2012-07-21 14:44:08
  • Python英文文本分词(无空格)模块wordninja的使用实例

    2022-05-12 07:10:16
  • 命令行运行Python脚本时传入参数的三种方式详解

    2021-11-30 00:16:08
  • 详解vue-router 2.0 常用基础知识点之router.push()

    2024-04-09 10:49:35
  • 精心整理总结的Python自动化测试面试题

    2022-07-27 08:13:00
  • asp之家 网络编程 m.aspxhome.com