本代码将实现视频中的背景和前景分离,并定位行人。
1.实现效果
以下为处理后的视频截图
2.定义卷积核
import cv2
cap = cv2.VideoCapture('test.avi')
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3))# kernel: [[0 1 0],[1 1 1], [0 1 0]]
# 定义一个3*3的十字形卷积核,以便后续去噪
3.创建混合高斯模型,用于背景建模
fgbg = cv2.createBackgroundSubtractorMOG2(varThreshold = 30, detectShadows=True)
varThreshold=30:方差阈值,用于判断当前像素是前景还是背景。 默认值为16,用于控制阈值化过程,指定了像素在被分类为前景或背景之前必须超过的方差阈值。像素值的变化如果小于这个阈值,则认为该像素属于背景;如果大于这个阈值,则认为该像素可能属于前景。值越大,灵敏度越低,即较小的变化不会被视为前景。
detectShadows:是否检测影子。默认值为 False (不检测影子)。作用为确定是否将阴影视为前景目标的一部分。设置为True会增加程序的时间复杂度,因为需要额外处理阴影的检测和标记。
此外还有此处没有用到的参数history,用于训练背景的帧数。默认值为500帧。用于指定背景模型中需要考虑的过去帧的数量。较大的历史值将产生较长的动态背景模型,从而更好地适应背景中的变化,但也可能增加计算成本。
4.提取前景
while(True):
ret,frame = cap.read()
# ret:True 表示正常读取到图像,frame: 从视颊中获取当前一帧图片
cv2.imshow('frame', frame)
fgmask = fgbg.apply(frame) # 视频处理
cv2.imshow('fgmask', fgmask)
# fgbg.apply(frame)函数会返回一个掩膜,其中前景部分被设置为255(白色),背景部分为0(黑色)。
# 使用这个掩膜来提取和分析前景物体
fgmask_new = cv2.morphologyEx(fgmask,cv2.MORPH_OPEN,kernel) # 开运算去噪点
cv2.imshow('fgmask_new', fgmask_new)
5.提取轮廓
#寻找视频中的轮廓
_, contours, h = cv2.findContours(fgmask_new, 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)
# 画出外接矩形
fgmask_new_rect = cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
6.显示结果
cv2.imshow('fgmask_new_ rect', fgmask_new_rect)
k = cv2.waitKey(100) & 0xff
if k == 27:
break