【python】实现基于混合高斯模型的运动目标检测 | 方案和代码

在视频监控场景中,应用基于背景减去法的运动目标检测是比较常见的。

目录

一 安装依赖

二 函数

① cv2.createBackgroundSubtractorMOG2()

② apply()

③ cv2.findContours()

三 实现基于背景减去法的运动目标检测的方法

四 实践

① 代码

② 效果图



一 安装依赖

通过以下命令安装相关依赖:

pip install opencv-python numpy

二 函数

① cv2.createBackgroundSubtractorMOG2()

cv2.createBackgroundSubtractorMOG2()函数是OpenCV库中用于创建混合高斯模型(Gaussian Mixture Model,简称GMM)背景减除器的方法。

初始化一个背景减除器对象,用于实时视频流中前景目标的检测。

函数的参数

▲ history:整型参数,指定最近多少帧用于学习背景模型。较大的history值可以使模型更加稳定,但也会增加响应时间,即模型适应新背景的时间会更长。history=450意味着模型将基于最近450帧的历史数据来学习背景。

▲ varThreshold:整型参数,设置混合高斯模型的方差阈值。这个参数决定了如何将前景像素与背景模型区分开来。较大的varThreshold值会减少误报,但可能会漏掉一些真正的前景对象;较小的varThreshold值则会增加敏感度,但可能会增加误报。varThreshold=16是一个相对适中的设置,适用于大多数场景。

▲ detectShadows:布尔型参数,决定是否检测阴影。如果设为True,背景减除器将尝试识别并标记阴影区域。这在光照变化较大的环境中很有用,但可能会稍微降低性能。

② apply()

apply()方法返回一个前景掩码。

③ cv2.findContours()

在OpenCV中,cv2.findContours()函数用于从二值图像中检测物体的轮廓。该函数接受三个主要参数:输入图像(通常是二值图像)、轮廓检索模式和轮廓近似方法。

contours, _ = cv2.findContours(fgmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

参数含义如下

▲ fgmask:这是背景减除后的前景掩膜图像,通常是一个二值图像,其中前景像素值为255,背景像素值为0。

▲ cv2.RETR_EXTERNAL:这是一个轮廓检索模式,只检索最外层的轮廓,忽略内嵌的轮廓。这通常用于只需要最外层物体边界的场景。

▲ cv2.CHAIN_APPROX_SIMPLE:这是一个轮廓近似方法,它压缩水平的、垂直的和对角线的元素,只留下端点。这样可以大大减少存储轮廓所需的点的数量,同时保留轮廓的基本形状。

函数返回两个值

contours 和 _(通常被忽略)。contours是一个Python列表,其中每一个元素都是图像中的一个轮廓,表示为Numpy数组,数组中的每一行存储轮廓上一个点的坐标(x, y)。_通常代表层次结构信息,但在大多数情况下,只关心轮廓本身,所以通常用_来忽略这个返回值。

使用cv2.findContours()获取轮廓后,可以进一步处理这些轮廓,比如计算轮廓的面积、周长、中心点、最小包围矩形等,或者在原图像上绘制这些轮廓。这些操作对于目标检测、物体识别、手势识别等计算机视觉应用是非常基础且重要的。

三 实现基于背景减去法的运动目标检测的方法

① 创建了一个BackgroundSubtractorMOG2对象,是OpenCV提供的基于混合高斯模型的背景减除类。

② 从视频流中读取每一帧,应用背景减除。

③ 使用形态学操作(如开运算)来去除小的噪声区域。

④ 检测前景中的轮廓,并为面积大于设定阈值的轮廓绘制边界框。

⑤ 显示目标检测结果。

四 实践

① 代码

import cv2
import numpy as np
# 创建BackgroundSubtractorMOG2对象
fgbg = cv2.createBackgroundSubtractorMOG2(history=450, varThreshold=20, detectShadows=True)
# 打开视频文件
cap = cv2.VideoCapture('test.mp4')
while True:
    ret, frame = cap.read()
    if not ret:
        break
    # 应用背景减除
    fgmask = fgbg.apply(frame)
    # 使用形态学操作去除噪声
    kernel = np.ones((3,3),np.uint8)
    fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)
    # 查找轮廓
    contours, _ = cv2.findContours(fgmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    # 绘制边界框
    for contour in contours:
        if cv2.contourArea(contour) > 300:
            x, y, w, h = cv2.boundingRect(contour)
            cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
    # 显示结果
    cv2.imshow('Frame', frame)
    # cv2.imshow('FG Mask', fgmask)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break
cap.release()
cv2.destroyAllWindows()

② 效果图

至此,本文的内容就结束啦。

作者:Jackilina_Stone

物联沃分享整理
物联沃-IOTWORD物联网 » 【python】实现基于混合高斯模型的运动目标检测 | 方案和代码

发表回复