背景建模
帧差法
由于场景中的目标在运动,目标的影像在不同图像帧中的位置不同。该类算法对时间上连续的两帧图像进行查分运算,不同帧对应的像素点相减,判断灰度值的绝对值,当绝对值超过一定阈值时,即可判断为运动目标,从而实现目标的检测功能。
帧差法非常简单,但会引入噪音点和空洞问题(如上图中人物的身上是黑色,因为两帧之间的差别明显造成的)。
鲁棒性也称为健壮性、稳健性、强健性,是系统的特性,它是系统在遇到异常和危险情况下是否能生存的关键。是指系统在一定(结构,大小)的参数的扰动下,维持某些性能的特性。
混合高斯模型
在进行前景检测前,先对背景进行训练,对图像中每个背景采用一个混合高斯模型进行模拟,每个背景的混合高斯模型的个数可以自适应,然后再测试阶段,对新来的像素进行GMM匹配,如果该像素能够匹配其中一个高斯,则认为是背景,否则认为是前景。由于整个过程GMM模型都在不断学习中,所以对动态背景有一定的鲁棒性。
在视频中,像素的变化情况应当是符合高斯分布。
背景的实际分布应该是多个高斯模型混合在一起的,每个高斯模型也都应带有权重
高斯混合模型学习方法个数不宜过多(3-5个即可)
1、首先初始化每个高斯模型矩阵参数
2、取视频中T(大于等于200)帧数据图像用来训练高斯模型,来了第一个像素之后用它来当第一个高斯分布
3、当后面来的像素时,与已有的高斯的均值进行比较,如果该像素点的值与高斯的均值差在3倍的方差内,则属于该分布,加入该数据,并对其参数进行更新
4、如果下一个来的像素不满足当前的高斯分布,则用它来创建一个新的高斯分布
高斯混合模型测试方法
在测试阶段,在新来的每一个像素点的值与每一个模型的均值进行比较,如果差值在2倍的方差之间的话,则默认为背景,否则为前景。将前景赋值为255,背景赋值为0,这样就形成了一幅二值图像(视频流)。
完整代码:
import cv2 as cv
import matplotlib as plt
import numpy as np
cap=cv.VideoCapture("E:\OpenCVTests/test.avi")
#形态学操作需要使用
kernel=cv.getStructuringElement(cv.MORPH_ELLIPSE,(3,3))
#创建混合高斯模型用于背景建模
fgbg=cv.createBackgroundSubtractorMOG2()
while(True):
ret,frame=cap.read()
fgmask=fgbg.apply(frame)#每一帧
#开操作
fgmask=cv.morphologyEx(fgmask,cv.MORPH_OPEN,kernel)
#寻找视频中的轮廓
controus,hierarchy=cv.findContours(fgmask,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_NONE)
for c in controus:
perimeter=cv.arcLength(c,True)
if perimeter>188:
x,y,w,h=cv.boundingRect(c)
cv.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
cv.imshow("frame",frame)
cv.imshow("fgmask",fgmask)
k=cv.waitKey(100)&0xff#尽可能大一点,播放速度会慢一些,则更容易观察
if k==27:
break
cv.release()
cv.destroyAllWindows()