背景相减(BS)是一种常用且广泛使用的技术,用于通过使用静态相机来生成前景掩模(即,包含属于场景中运动对象的像素的二值图像)。
顾名思义,BS计算前景掩码,在当前帧和背景模型之间执行减法,该模型包含场景的静态部分,或者更一般地,考虑到观察到的场景的特性,可以认为是背景的所有内容。
背景建模包含两个主要步骤:
import cv2
videoname = "assets/vtest.avi"
algo_method = "MOG2"
# 背景模型初始化
if algo_method == "MOG2":
backSub = cv2.createBackgroundSubtractorMOG2()
else:
backSub = cv2.createBackgroundSubtractorKNN()
# 读入视频
capture = cv2.VideoCapture(videoname)
if not capture.isOpened():
print("Error opening video file")
exit(0)
while True:
ret, frame = capture.read()
if frame is None:
break
# 背景更新
fgMask = backSub.apply(frame)
# 绘制帧号,可以不用---
cv2.rectangle(frame, (10, 2), (100, 20), (255, 255, 255), -1)
cv2.putText(frame, str(capture.get(cv2.CAP_PROP_POS_FRAMES)), (15, 15),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0))
cv2.imshow('Frame', frame)
cv2.imshow('FG Mask', fgMask)
keyboard = cv2.waitKey(30)
if keyboard == 'q' or keyboard == 27:
break
capture.release()
cv2.destroyAllWindows()
cv2.createBackgroundSubtractorKNN( [, history[, dist2Threshold[, detectShadows]]] ) -> retval
cv::createBackgroundSubtractorKNN ( int history = 500,
double dist2Threshold = 400.0,
bool detectShadows = true
)
创建一个knn背景模型对象
- history: 历史长度,默认500
- dist2Threshold: 判断两帧之间像素的距离平方的阈值,默认400
- detectShadows: 如果为真,检测阴影
cv2.createBackgroundSubtractorMOG2( [, history[, varThreshold[, detectShadows]]] ) -> retval
cv::createBackgroundSubtractorMOG2 ( int history = 500,
double varThreshold = 16,
bool detectShadows = true
)
创建一个混合高斯背景模型
- history: 历史长度
- varThreshold: 像素和模型之间的平方马氏距离阈值,以确定像素是否被背景模型很好地描述
- detectShadows: 如果为真,就检测阴影
cv2.BackgroundSubtractor.apply( image[, fgmask[, learningRate]] ) -> fgmask
计算前景
- image: 下一帧图像
- fgmask: 前景图像
- learningRate: 学习率,0~1,0代表不更新,1代表直接替换;
在用例中,直接用 backSub.apply
cv2.BackgroundSubtractor.getBackgroundImage( [, backgroundImage] ) -> backgroundImage
获得背景
在用例中,直接用 backSub.getBackgroundImage
其他背景模型见:
OpenCV: cv::BackgroundSubtractor Class Reference