OpenCV(26-2):视频分析之二:背景建模

6.2 背景建模

所谓背景建模,就是将背景识别出来,与前景进行区分的过程。

6.2.1方法介绍

背景建模需要满足一定条件,保证摄像机拍摄位置不变,保证背景是基本不发生变化的。如路口的监控摄像机,只有车流人流等前景部分能发生移动,而马路树木等背景不能发生移动。

判断视频中前景和背景的方法主要有两种:帧差法、混合高斯模型

帧差法

如下图,摄像机拍摄获取一帧一帧的连续图像,需要摄像机识别出,哪些部分是运动的,哪些部分是静止的。在摄像机拍摄位置不变的前提下,一个物体位置发生了变化,那么像素点数值也会发生变化;不发生运动的物体,它的像素点数值不基本会发生的变化。

由于场景中的目标在运动,位置产生了差异,摄像头捕捉到的图像不同。该算法通过对时间上连续的两帧图像进行差分算法,不同帧对应的像素点相减,判断灰度差异的绝对值的变化情况,当绝对值超过一定阈值时,即可判断为运动目标,从而实现目标的检测功能。

帧差法公式如下

(x, y)  代表像素点坐标,  代表第n 帧图像, 代表第 帧图像,差分结果为  。如果差分结果大于阈值 T,将该像素点指定成255白点,代表前景;否则指定为0,代表背景。


       

帧差法缺点

第一,如果图像中存在噪音点,帧差法会引入噪音。第二,如上图右侧,人的轮廓是白色,但轮廓内是黑色的,因为人在前后两帧图像中的位置变化很小,会存在空洞问题。帧差法不常用。

混合高斯模型

在进行前景检测前,先对背景进行训练,对图像中每个背景采用一个混合高斯模型进行模拟,每个背景的混合高斯模型的个数可以自适应。然后在测试阶段对新来的像素进行GMM匹配,如果该像素值能够匹配其中一个高斯,则认为是背景,否则认为是前景。由于整个过程GMM模型在不断更新学习中,所以对动态背景具有一定的鲁棒性,整体的检测效果会得到提升。

可以简单理解一下。在图像中判断前景和背景,比如在运动过程中,人服从一种分布,背景也服从一种分布。判断视频中的像素点符合哪一种分布,符合运动的就判断是前景,符合静止的就判断为背景。

然而,背景的实际分布应当是多个高斯分布混合在一起的,每个高斯模型也有其对应的权重。下图左侧是图像背景满足的两种分布,得到右侧的结果也是不同的,两种分布需要对应不同的权重。虽然整体的背景是由多个高斯分布融合在一起的,但每个分布所占的权重不一定都相同。权重是由图像中像素点的个数决定的。

对于视频中某一块区域的一个像素点来说,虽然在视频中的位置不发生改变,但它的值会发生变化。像素点值的变化情况应当符合高斯分布

混合高斯模型的学习方法
  1. 首先初始化每个高斯模型矩阵参数。均值μ ,标准差σ
  2. 取视频中T 帧数据图像,用来训练高斯混合模型。来了第一个像素点之后用它来当作第一个高斯分布。如:μ1=100, σ1=5  。
  3. 当后面来的像素值,与前面已有的高斯的均值比较,如果该像素点的值与其模型均值差在3倍的方差内,则属于该分布,并对其进行参数更新。

如:第二帧的像素点的值为105 ,比较  ,因此第二帧的像素点属于第一帧像素的分布,因此这两个数据归纳在一起,更新第一个分布的均值μ ,标准差σ

如果下次来的像素点不满足当前的高斯分布,用它来创建一个新的高斯分布。

如:第三帧的像素点的值为200 ,不满足更新后σ ,那么创建一个新的高斯分布。如:

一般情况下,高斯分布的个数设置3-5个,过多的话结果不好

混合高斯模型测试方法

在测试阶段,对新来的像素点的值,与学习好了的混合高斯模型中的每一个均值比较,如果差值在2倍的方差之间,就认为是背景,否则认为是前景。将前景赋值为255,背景赋值为0

6.2.2 相关函数

混合高斯模型背景建模方法

函数原型:cv2.createBackgroundSubtractorMOG2().apply(image) 

参数

返回值

自定义卷积核

函数原型:rectkernel = cv2.getStructuringElement(shape, ksize, anchor=None)

参数

  1. shape卷积核形状。矩形:MORPH_RECT,十字型:MORPH_CROSS,椭圆形MORPH_ELLIPSE 
  2. ksize卷积核大小
  3. anchor坐标(x,y),元素内的锚定位置。默认值为(-1,-1),即结构化元素的中心。

返回值:卷积核矩阵

6.2.3 示例

import numpy as np
import cv2

# 指定文件夹
filepath = 'C:\\Users\\opencv\\img\\class'

# 获取文件夹中某个视频
video = cv2.VideoCapture(filepath + '\\test.avi')
#video = cv2.VideoCapture(0) #若没有测试文件,可用当前摄像头

# 自定义卷积核--矩形,用于形态学处理
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))

# 创建混合高斯模型用于背景建模
back = cv2.createBackgroundSubtractorMOG2()

# 读取每一帧并处理
while True:
    ret, frame = video.read() #每次读取一帧,返回是否打开和每帧图像
    img = back.apply(frame) #背景建模
   
    # 开运算(先腐蚀后膨胀),去除噪声
    img_close = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

    # 轮廓检测,获取最外层轮廓,只保留终点坐标
    contours,hierarchy = cv2.findContours(img_close,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    # 计算轮廓外接矩形
    for cnt in contours:
        # 计算轮廓周长
        length = cv2.arcLength(cnt,True)
        if length>188:
            # 得到外接矩形的要素
            x,y,w,h = cv2.boundingRect(cnt)
            # 画出这个矩形,在原视频帧图像上画,左上角坐标(x,y),右下角坐标(x+w,y+h)
            cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),2)
    # 图像展示
    cv2.imshow('frame',frame) # 原图
    cv2.imshow('img',img)  # 高斯模型图
    # 设置关闭条件,一帧200毫秒
    k = cv2.waitKey(100) & 0xff
    if k == 27:  #27代表退出键ESC
        break
    if k == 32:  #32代表空格键,暂停
        cv2.waitKey(0)
        continue
# 释放资源
video.release()
cv2.destroyAllWindows()

 

某一帧的效果图如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值