1.概念:
背景减法是许多基于计算机视觉应用的主要预处理操作。举个例子,想象一下一个固定在柜台的摄像机需要计算进来与出去房间的人的数量的情况抑或是提取有关车辆等信息的交通摄像头等等。在所有这些情况下,首先你需要做的便是单独提取出人亦或是交通工具。从技术上来讲,你需要从静态的背景中提取出移动的前景。
如果你只有背景图像,像是没有访客的房间图像,没有车辆的道路图像等等,进行背景减法将是一件容易的事。只需要从背景图像中减去新图像。你便能得到前景对象了。但是,在大多数情况下,你可能并没有这样的图片,所以你需要从我们拥有的图像中提取背景。当车辆有阴影时情况会变得更加复杂。由于阴影也会移动,因此简单的减法也会将其标记为前景。这使得背景减除变得复杂。
2.相关重要的函数方法
1.背景建模方法
目前我的opencv版本为4.8,已经移除了BackgroundSubtractorMOG()方法了
cv::createBackgroundSubtractorMOG2 ( int history = 500,
double varThreshold = 16,
bool detectShadows = true )
使用混合高斯模型(Mixture of Gaussians,MOG)。MOG 假设每个像素的颜色是由多个高斯分布的组合来建模的,这有助于更好地适应具有不同光照条件和背景变化的场景。
优点: 适用于相对复杂的场景,对于具有动态背景和光照变化的视频效果较好。
cv::createBackgroundSubtractorKNN ( int history = 500,
double varThreshold = 16,
bool detectShadows = true )
与上述参数一致,使用 K近邻算法(K-Nearest Neighbors,KNN)。KNN 通过维护像素的最近邻居的列表来建模背景,并使用该信息来判断像素是否属于前景。
优点: 适用于对实时性要求较高的场景,对于相对简单的场景和运动较缓慢的对象效果较好。
2.图像形态学参数设置
cv2.getStructuringElement(shape,ksize,anchor)
OpenCV 中用于创建结构元素的函数。结构元素通常用于图像处理中的形态学操作,例如腐蚀(erosion)、膨胀(dilation)、开运算(opening)和闭运算(closing)等
shape
: 结构元素的形状,可以是矩形 (cv2.MORPH_RECT
)、椭圆 (cv2.MORPH_ELLIPSE
) 或十字形 (cv2.MORPH_CROSS
)。ksize
: 结构元素的大小,指定了结构元素的宽度和高度。anchor
: 结构元素的锚点位置。锚点是结构元素的中心,默认为结构元素的中心。3.图像形态学操作
cv2.morphologyEx
(src, op, kernel , anchor, iterations, borderType, borderValue)
OpenCV 中用于执行形态学操作的函数
src
: 输入图像。op
: 形态学操作的类型,如腐蚀、膨胀、开运算或闭运算等。kernel
: 结构元素,定义了形态学操作的操作模式。anchor
: 结构元素的锚点,默认为结构元素的中心。通常用上述2.设置方法iterations
: 迭代次数,指定形态学操作应该应用的次数。borderType
: 边界模式,指定图像边界的处理方式。borderValue
: 边界值,在指定边界模式时使用的边界值。如:op:cv2.MORPH_OPEN
表示进行开运算。开运算是先对图像进行腐蚀,然后再进行膨胀的操作。它通常被用于去除图像中的噪声,平滑边界,以及分离物体之间的连接。开运算可以帮助消除小的物体或者细小的结构,而保留更大的结构。
3.代码演示:
import numpy as np
import cv2
cap=cv2.VideoCapture('opencv_test_3.avi')
# 形态学操作需要使用
kernel=cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
# 创建高斯混合模型用于背景建模
# 这个算法的一个特点是它为每 一个像素选择一个合适数目的高斯分布
fgbg=cv2.createBackgroundSubtractorMOG2()
while(True):
ret,frame=cap.read()
fgmask=fgbg.apply(frame)
# 形态学开运算去噪点
fgmask=cv2.morphologyEx(fgmask,cv2.MORPH_OPEN,kernel)
# 寻找视频中的轮廓
contours,hierarchy=cv2.findContours(fgmask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
# 计算各轮廓的周长
perimeter=cv2.arcLength(c,True)
if perimeter>188:
# 找到一个直矩形
x,y,w,h=cv2.boundingRect(c)
# 画出这个矩形
cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),2)
cv2.imshow('frame',frame)
cv2.imshow('fgmask',fgmask)
k=cv2.waitKey(100) & 0xff#可以提前使用Esc键来退出
if k == 27:
break
cap.release()
cv2.destroyWindow()
测试视频:
Opencv实验三——背景消除测试视频-CSDN直播
4.效果演示:
本次实验展示了视频分析中的背景减法功能,官方文档请看OpenCV: OpenCV Tutorials
如有错误或遗漏,希望小伙伴批评指正!!!!
希望这篇博客对你有帮助!!!!
实验二:计算机视觉Opencv实验合集——实验二:特征匹配-CSDN博客
实验四:Opencv实验合集——实验四:图片融合-CSDN博客