一、背景建模

指在计算机视觉中,从视频序列中提取出静态背景的一种技术。在视频中,背景通常被定义为相对稳定的部分,例如墙壁、地面或天空等。背景建模的目标是将动态的前景对象与静态的背景进行分离,以便进一步分析和处理。

1. 目的

通过背景建模,我们可以实现很多应用,例如运动检测、目标跟踪等等。

2. 方法

背景建模的方法:帧差法,其中又包括两种方法:

  1. 基于K近邻的背景/前景分割算法BackgroundSubtractorKNN
  2. 基于高斯混合的背景/前景分割算法BackgroundSubtractorMOG2

3. 帧差法

  • 原理

由于场景中的目标在运动,目标的影像在不同图像帧中的位置不同。该类算法对时间上连续的两帧图像进行差分运算,不同帧对应的像素点相减,判断灰度差的绝对值,当绝对值超过一定阈值时,即可判断为运动目标,从而实现目标的检测功能。

在这里插入图片描述

  • 优缺点

帧差法非常简单,但是会引入噪音和空洞(人物中间是黑色的)问题。

4. 光流估计

  • 原理

光流(Optical Flow)是指图像中一个像素在不同帧之间的运动向量。光流估计的目标是在连续的图像帧之间找到对应的像素,并计算它们之间的位移或速度。其基本原理基于亮度恒定假设,即认为在短时间内,一个像素的亮度值在运动过程中保持不变。根据这一假设,光流估计方法通过观察像素在图像序列中的位置变化来推测它们的运动。

  • 前提

(1)亮度恒定:同一点随着时间的变化,其亮度不会发生改变。

(2)小运动:随着时间的变化不会引起位置的剧烈变化,只有小运动情况下才能用前后帧之间单位位置变化引起的灰度变化去近似灰度对位置的偏导数。

(3)空间一致:一个场景上邻近的点投影到图像上也是邻近点,且邻近点速度一致。因为光流法基本方程约束只有一个,而要求x,y方向的速度,有两个未知变量。所以需要连立n多个方程求解。

二、代码步骤

1. 读取视频

"""-----帧差法-----"""
import cv2
# 经典的测试视频
cap = cv2.VideoCapture('test.avi')

2. 构建卷积核

主要用于后续的腐蚀、膨胀、开/闭运算等,对侦察后的图片进行处理。

  • 方法
构建卷积核:
getStructuringElement(shape,ksize,anchor=None)得到一个卷积核。主要用于后续的腐蚀、膨胀、开/闭运算等
参数:
-- shape:设定卷积核的形状,可选以下参数:
     1. MORPH_RECT(矩形卷积核)
     2. MORPH_CROSS(十字形卷积核)
     3. MORPH_ELLIPSE(椭圆形卷积核)
-- ksize:设定卷积核的大小
-- anchor:表示描点的位置,一般c = 1,表示描点位于中心
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))

3. 背景建模

创建混合高斯模型,用于背景建模:

  • 步骤:对视频的每一帧图片进行帧差处理,然后对帧差后的图片进行噪声处理,接着找到视频中移动人物的轮廓,最后画出轮廓,定位移动目标。

  • 结果展示:随着步骤展示每步后的结果。

  1. 源图像:

在这里插入图片描述

  1. 帧差图:

在这里插入图片描述

  1. 去噪声:

在这里插入图片描述

  1. 目标跟踪:

在这里插入图片描述

  • 代码展示
# 创建混合高斯模型,用于背景建模
fgbg = cv2.createBackgroundSubtractorMOG2()
while (True):
    ret,frame = cap.read()
    cv2.imshow('frame',frame)
    fgmask = fgbg.apply(frame) # 视频处理
    cv2.imshow('fgmask',fgmask)
    fgmask_new = cv2.morphologyEx(fgmask,cv2.MORPH_OPEN,kernel) # 开运算去除噪声点,先腐蚀后膨胀
    cv2.imshow('fgmask1',fgmask_new)

    # 寻找视频中的轮廓
    _,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)
    cv2.imshow('fgmask_new_rect',fgmask_new_rect)
    k = cv2.waitKey(60)
    if k == 27:
        break

总结

本篇介绍了:

  1. 对视频进行背景建模,使用帧差法。
  2. 对视频中移动对象进行目标跟踪检测。
Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐